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)