interp2 with Octave 3.6.2 yields NA - octave

Strip = [-2.0650, -3.2540, -4.4145, -5.4490, -6.3575, -7.2380, -8.1185, -8.9995, -9.8805, -10.7615, -11.6420, -12.5225, -13.4035, -14.1520, -14.7675, -15.3830];
YA = [-1.103, -2.586, -3.724, -4.981, -5.997, -7.134, -8.271, -9.407, -10.545, -11.682, -12.818, -13.955, -15.69];
%
DFZ = [ 1184.31, 1526.26, 762.50, 562.81, 359.21, 250.49, 180.48, 110.95, 73.79, 48.42, 30.62, 23.56, 4.03;
746.64, 1310.41, 952.00, 649.05, 462.94, 307.50, 209.61, 127.17, 81.29, 52.38, 32.17, 24.46, 5.87;
471.84, 977.42, 946.58, 774.77, 494.69, 321.74, 214.50, 127.93, 80.13, 50.67, 30.56, 22.53, 5.27;
305.12, 610.90, 657.14, 730.46, 510.09, 302.22, 198.04, 115.46, 70.76, 43.97, 25.98, 18.45, 3.78;
241.27, 470.64, 469.33, 625.56, 598.09, 369.79, 225.75, 128.23, 76.21, 46.15, 26.48, 18.55, 3.66;
203.92, 393.14, 373.35, 484.21, 590.13, 487.48, 289.38, 156.48, 90.26, 52.59, 29.20, 20.16, 4.07;
172.49, 329.92, 304.57, 370.21, 476.58, 542.99, 403.83, 202.30, 112.69, 63.06, 33.62, 22.00, 4.71;
145.30, 277.10, 251.22, 295.10, 357.11, 468.45, 518.32, 287.29, 148.14, 79.56, 40.13, 24.65, 5.10;
122.14, 233.34, 208.52, 240.30, 275.85, 344.08, 503.98, 410.61, 210.72, 105.57, 50.03, 28.81, 5.52;
102.56, 196.41, 172.98, 196.53, 218.95, 252.62, 375.33, 470.42, 320.77, 148.75, 66.14, 35.36, 6.22;
84.73, 162.98, 141.44, 158.99, 173.43, 190.78, 257.28, 377.15, 436.28, 228.33, 91.72, 45.02, 7.26;
69.70, 134.30, 115.17, 128.64, 138.52, 147.27, 187.27, 247.97, 395.45, 359.38, 144.13, 63.30, 9.31;
56.51, 108.89, 92.50, 102.78, 109.86, 114.13, 139.44, 170.85, 255.10, 387.73, 255.91, 100.24, 12.92;
30.85, 59.730, 50.24, 55.57, 59.00, 60.25, 71.91, 84.427, 115.63, 201.32, 224.63, 109.67, 12.29;
23.27, 45.200, 37.68, 41.61, 44.03, 44.35, 52.19, 59.597, 77.19, 126.73, 200.29, 149.32, 15.32;
16.60, 32.364, 26.74, 29.44, 31.11, 30.98, 36.03, 40.255, 50.19, 74.54, 135.16, 173.17, 21.94];
Matrix DFZ maps a parameter onto a (Strip vs. YA) grid.
I would like to have it interpolated onto a (YStrip vs. Ystrip) grid. The code below returns an answer that seems to be OK:
[x, y] = meshgrid(YA,Strip);
[z, w] = meshgrid(Strip,Strip);
DFZ_Strip = interp2(x,y,DFZ,z,w,"spline")
When I try the same code using a linear interpolation though, I get a matrix of NA's.
Any tip about why the linear interpolation does not work?

The x and y given to interp2 should be strictly monotonic and increasing.
For instance with decreasing x and y
x_ = [-1.5 -2.5];
y_ = [-1 -2 -3];
[x__, y__] = meshgrid(x_, y_);
z__ = x__ + y__;
xi_ = x_;
yi_ = x_;
[xi__, yi__] = meshgrid(xi_, yi_);
# zi__ = interp2(x__, y__, z__, xi__, yi__, "spline")
zi__ = interp2(x__, y__, z__, xi__, yi__, "linear")
one gets
zi__ =
-3 NA
-4 NA
The workaround is to sort x, y and reorder z accordingly:
x_ = [-1.5 -2.5];
y_ = [-1 -2 -3];
[x__, y__] = meshgrid(x_, y_);
z__ = x__ + y__;
# sort x and y and reorder z accordingly
[x_sorted_, idx_x_] = sort(x_);
[y_sorted_, idx_y_] = sort(y_);
x__ = x__(idx_y_, idx_x_);
y__ = y__(idx_y_, idx_x_);
z__ = z__(idx_y_, idx_x_);
xi_ = x_;
yi_ = x_;
[xi__, yi__] = meshgrid(xi_, yi_);
# zi__ = interp2(x__, y__, z__, xi__, yi__, "spline")
zi__ = interp2(x__, y__, z__, xi__, yi__, "linear")
Then the right result is obtained:
zi__ =
-3 -4
-4 -5

Related

Interp1 function in ODE45

I am trying to solve a 3 Degree Of Freedom vessel-crane system in MATLAB using ode45. In my ode function, the vessel motion is determined by simple spring and damper constants, but the device below the main hoist system, a cranemaster, has a displacement-dependent stiffness and thus depends on one of the Degrees Of Freedom. To determine this value, I use the interp1 function to determine the stiffness from a dataset:
vq = interp1(x,v,xq,method,extrapolation)
This all works fine, but only when I add the extrapolation option in the interp1 function, even though the xq values all fall inside the dataset x-values. If I do not specify extrapolation, the function returns NAN.
I have checked if the stiffness values in the dataset make sense by taking the median value as a constant value and then the ode45 solver works just fine and the displacement never falls outside of the dataset. I have also noticed that if I switch to ode23 as a solver, it also works. This all makes me believe it has something to do with the solving method and the stepsize the ode solver takes as its initial value.
I have provided (a simplified version of) my code and a picture of the system to get a feel for the problem. I know that switching to ode23 solves the problem but I would like to understand why and, if possible, stay with ode45 as it is a more general solver.
Any help would be appreciated!
Regards,
Diederik
Overview of the system I am solving
close all
tspan = [0 100];
x0 = [0.0; 0; 0.0; 0; 0.0; 0]; % initial disp. and vel. is 0. for all 3 DOF.
% x = [z; zdot; theta; thetadot; u; udot]
[t,x] = ode45(#Three_DOF,tspan,x0);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plots
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure()
subplot(2,1,1)
plot(t,x(:,5),'color','b','LineWidth',1)
grid on
xlabel('Time (s)')
ylabel('Displacement (m)')
title('Displacement Vs Time')
subplot(2,1,2)
plot(t,x(:,6),'color','#D95319','LineWidth',1)
grid on
xlabel('Time (s)')
ylabel('Velocity (m/s)')
title('Velocity Vs Time')
function [dxdt] = Three_DOF(t,x)
% vessel parameters
m = 570.5e6;
m55 = 4.591e12;
mh = 200e3;
c33 = 3.83952e8;
c55 = 3.66116e12;
wnh = 0.360;
wnp = 0.596;
a33 = (c33-wnh^2*m)/wnh^2;
a55 = (c55-wnp^2*m55)/wnp^2;
zeta33 = 0.386;
zeta55 = 0.121;
b33 = zeta33*2*sqrt(c33*(m+a33));
b55 = zeta55*2*sqrt(c55*(m55+a55));
Fa = 153e6;
Ma = 3.013e9;
w1 = 0.21/0.36;
w2 = 0.18/0.28;
%%%% Cable parameters
k_c = 496e6;
b_c = 5.01e6;
%%% CRANEMASTER parameters
x_data = [-2.0; -1.87; -1.73; -1.60; -1.47; -1.33; -1.20; -1.07; -0.93; -0.8; -0.67; -0.53; -0.4; -0.27; -0.13; 0.0; 0.13; 0.27; 0.40; 0.53; 0.67; 0.80; 0.93; 1.07; 1.20; 1.33; 1.47; 1.60; 1.73; 1.87; 2.0];
k_data = [760; 792.1; 784.8; 813.9; 828.4; 850.2; 879.3; 901.1; 922.9; 959.2; 981.0; 1010.1; 1039.1; 1068.2; 1104.5; 1133.6; 1177.2; 1206.3; 1242.6; 1286.2; 1329.8; 1373.4; 1409.7; 1460.6; 1511.5; 1562.3; 1620.5; 1671.3; 1729.5; 1794.9; 1853];
k_cm = 30000*interp1(x_data,k_data,x(5));%,'linear','extrap');
%k_cm = 30000*1133.61; % middle value of dataset k_data
b_cm = 6e4;
l = 217.5;
% Matrices & solve
Mass = [m+a33 0 0; 0 m55+a55 0; 0 0 mh];
k = [c33+k_c -k_c*l -k_c; -k_c*l c55+k_c*l^2 k_c*l; -k_c k_c*l k_c+k_cm];
b = [b33+b_c -b_c*l -b_c; -b_c*l b55+b_c*l^2 b_c*l; -b_c b_c*l b_c+b_cm];
F = [Fa*sin(w1*t); Ma*sin(w2*t); 0];
EOM = Mass\(F-b*([x(2); x(4); x(6)])-k*([x(1); x(3); x(5)]));
dxdt = [x(2); EOM(1); x(4); EOM(2); x(6); EOM(3)];
% x = [z; zdot; theta; thetadot; u; udot]
end

How to graph the function in matlab?

I have the following 2n*π-periodic function F(x) = sin(x/n) and I need to graph the dx/dt = γ - F(x) on the segment from 0 to 2pi. So it should look like this. I tried to do it matlab this way:
gamma = 1.01;
n=3;
[t,phi] = ode45(#(t,x)gamma-sin(x/n), [0,400], pi);
[t1,phi1] = ode45(#(t,x)gamma-sin(x/n), [112,400], 0);
[t2,phi2] = ode45(#(t,x)gamma-sin(x/n), [231,250], 0);
figure();
plot(t, phi, 'k', t1, phi1, 'k', t2, phi2, 'k');
ylim([0 2*pi]);
yticks([0 pi 2*pi]);
yticklabels(["0" "\pi" "2\pi"]);
grid on; grid minor;
title('\itsin(x/n)')
but I only got something like this. So there the lines are not transferred, but "begin anew". does anyone here know how to do that?
I get a plot similar to your first sketch, and based on your code in the comments (in future, put such additions into the question itself, use formatting to mark it as addition, and cite it then in the comment) with the changes
use pi as initial point as seen in the drawing,
use the options of the ODE solver to restrict the step size, directly and by imposing error tolerances
your original time span covers about 3 periods, reduce this to [0, 200] to get the same features as the drawing.
gamma = 1.01; n=3;
opts = odeset('AbsTol',1e-6,'RelTol',1e-9,'MaxStep',0.1);
[t, phi] = ode45(#(t,x)gamma-sin(x/n), [0,200], pi, opts);
phi = mod(phi, 2*pi);
plot(t, phi, 'k');
ylim([0 2*pi]); yticks([0 pi 2*pi]); yticklabels(["0" "\pi" "2\pi"]);
grid on; grid minor;
title('\itsin(x/n)')
To get more elaborate, use events to get points on the numerical solution where it exactly crosses the 2*pi periods, then use that to segment the solution plot (styling left out)
function [ res, term, dir ] = event(t,y)
y = mod(y+pi,2*pi)-pi;
res = [ y ];
dir = [1]; % only crossing upwards
term = [0]; % do not terminate
end%function
opts = odeset(opts,'Events',#(t,y)event(t,y));
sol = ode45(#(t,x)gamma-sin(x/n), [0,200], pi, opts);
tfs = [ sol.xe; sol.x(end) ]
N = length(tfs)
clf;
t0 = 0;
for i=1:N
tf = tfs(i);
t = linspace(t0+1e-2,tf-1e-2,150);
y = deval(sol,t); % octave: deval=#(res,t) interp1(res.x, res.y,t)
y = mod(y,2*pi);
plot(t, y);
hold on;
t0=tf;
end;
hold off;

plotTuneMultiCritResult does not work with TuneMultiCritControlMBO

I am trying to plot the Pareto front of a TuneMultiCritResult object, tuned with a control object of class TuneMultiCritControlMBO:
# multi-criteria optimization of (tpr, fpr) with MBO
lrn = makeLearner("classif.ksvm")
rdesc = makeResampleDesc("Holdout")
ps = makeParamSet(
makeNumericParam("C", lower = -12, upper = 12, trafo = function(x) 2^x),
makeNumericParam("sigma", lower = -12, upper = 12, trafo = function(x) 2^x)
)
ctrl = makeTuneMultiCritControlMBO()
res = tuneParamsMultiCrit(lrn, sonar.task, rdesc, par.set = ps,
measures = list(tpr, fpr), control = ctrl)
Printing the object res gives the following:
> res
Tune multicrit result:
Points on front: 14
> res$ind
[1] 1 2 4 5 6 7 9 11 12 14 15 16 17 18
But the length of the optimization path saved in res$opt.path only has 10 points, the ones proposed by MBO I guess.
> res$opt.path
Optimization path
Dimensions: x = 2/2, y = 2
Length: 10
Add x values transformed: FALSE
Error messages: TRUE. Errors: 0 / 10.
Exec times: TRUE. Range: 0.031 - 0.041. 0 NAs.
Since the function plotTuneMultiCritResult relies on the objects res$ind and res$opt.path to print the front, it shows weird results.
I think that the correct way to go is to copy the optimization path of the object res$mbo.result$opt.path into res$opt.path, but my question is: What's the point of having different optimization paths in res$opt.path and res$mbo.result$opt.path?
Thanks!!
Víctor
Using mlr_2.13 and mlrMBO_1.1.3 and the following code everything works like expected. I suggeset that you use the MBO Control object to specify how much iterations your optimization should have. Otherwise a default (4*d evaluations for the initial design + 10 iterations) will be used.
set.seed(1)
library(mlr)
library(mlrMBO)
# multi-criteria optimization of (tpr, fpr) with MBO
lrn = makeLearner("classif.ksvm")
rdesc = makeResampleDesc("Holdout")
ps = makeParamSet(
makeNumericParam("C", lower = -12, upper = 12, trafo = function(x) 2^x),
makeNumericParam("sigma", lower = -12, upper = 12, trafo = function(x) 2^x)
)
mbo.ctrl = makeMBOControl(n.objectives = 2)
mbo.ctrl = setMBOControlTermination(mbo.ctrl, iters = 20)
ctrl = makeTuneMultiCritControlMBO(n.objectives = 2)
res = tuneParamsMultiCrit(lrn, sonar.task, rdesc, par.set = ps,
measures = list(tpr, fpr), control = ctrl)
plotTuneMultiCritResult(res = res, path = FALSE) # path = FALSE would only shows the Pareto Front

Octave fminunc doesn't update

I have the following octave script:
clear;
T0 = [...
1.0, 1.0, 5.0; ...
1.0, 2.0, 3.0; ...
-1.0,0.0, 6.0];
option = optimset('Display','Iter','GradObj','on','MaxIter','300','TolFun',10-5);
[t f] = fminunc(#flatTriangle,T0(:),option);
t = reshape(t,3,3);
And following octave functions
function [cost grad] = flatTriangle(T)
T = reshape(T,3,3);
Q = T(1,:)';
P = T(2,:)';
R = T(3,:)';
e3 = [0;0;1];
nf = cross(R - Q,P - Q);
cost = 0.5*(e3'*nf - norm(nf))^2;
grad = zeros(9,1);
commonStuff = (e3'*nf - norm(nf))*(e3 - nf/norm(nf))';
grad(1:3) = (commonStuff*skew(P - R)')';
grad(4:6) = (commonStuff*skew(R - Q)')';
grad(7:9) = (commonStuff*skew(Q - P)')';
endfunction
function Vhat = skew(V)
Vhat = [...
0.0 -V(3) V(2); ...
V(3) 0.0 -V(1); ...
-V(2) V(1) 0.0];
endfunction
Now despite the fact the grad vector isn't 0 the final output doesn't change at all from the initial input.
Am I using incorrectly something? maybe I'm not configuring something properly?
The code runs but it doesn't seem to do anything.

Object of type 'closure' is not subsettable - R

I am using R to extract tweets and analyse their sentiment, however when I get to the lines below I get an error saying "Object of type 'closure' is not subsettable"
scores$drink = factor(rep(c("east"), nd))
scores$very.pos = as.numeric(scores$score >= 2)
scores$very.neg = as.numeric(scores$score <= -2)
Full code pasted below
load("twitCred.Rdata")
east_tweets <- filterStream("tweetselnd.json", locations = c(-0.10444, 51.408699, 0.33403, 51.64661),timeout = 120, oauth = twitCred)
tweets.df <- parseTweets("tweetselnd.json", verbose = FALSE)
##function score.sentiment
score.sentiment = function(sentences, pos.words, neg.words, .progress='none')
{
# Parameters
# sentences: vector of text to score
# pos.words: vector of words of postive sentiment
# neg.words: vector of words of negative sentiment
# .progress: passed to laply() to control of progress bar
scores = laply(sentences,
function(sentence, pos.words, neg.words)
{
# remove punctuation
sentence = gsub("[[:punct:]]", "", sentence)
# remove control characters
sentence = gsub("[[:cntrl:]]", "", sentence)
# remove digits?
sentence = gsub('\\d+', '', sentence)
# define error handling function when trying tolower
tryTolower = function(x)
{
# create missing value
y = NA
# tryCatch error
try_error = tryCatch(tolower(x), error=function(e) e)
# if not an error
if (!inherits(try_error, "error"))
y = tolower(x)
# result
return(y)
}
# use tryTolower with sapply
sentence = sapply(sentence, tryTolower)
# split sentence into words with str_split (stringr package)
word.list = str_split(sentence, "\\s+")
words = unlist(word.list)
# compare words to the dictionaries of positive & negative terms
pos.matches = match(words, pos.words)
neg.matches = match(words, neg.words)
# get the position of the matched term or NA
# we just want a TRUE/FALSE
pos.matches = !is.na(pos.matches)
neg.matches = !is.na(neg.matches)
# final score
score = sum(pos.matches) - sum(neg.matches)
return(score)
}, pos.words, neg.words, .progress=.progress )
# data frame with scores for each sentence
scores.df = data.frame(text=sentences, score=scores)
return(scores.df)
}
pos = readLines(file.choose())
neg = readLines(file.choose())
east_text = sapply(east_tweets, function(x) x$getText())
scores = score.sentiment(tweetseldn.json, pos, neg, .progress='text')
scores()$drink = factor(rep(c("east"), nd))
scores()$very.pos = as.numeric(scores()$score >= 2)
scores$very.neg = as.numeric(scores$score <= -2)
# how many very positives and very negatives
numpos = sum(scores$very.pos)
numneg = sum(scores$very.neg)
# global score
global_score = round( 100 * numpos / (numpos + numneg) )
If anyone could help with as to why I'm getting this error it will be much appreciated. Also I've seen other answeres about adding '()' when referring to the variable 'scores' such as scores()$.... but it hasn't worked for me. Thank you.
The changes below got rid of the error:
x <- scores
x$drink = factor(rep(c("east"), nd))
x$very.pos = as.numeric(x$score >= 2)
x$very.neg = as.numeric(x$score <= -2)