I have a code that defines a function, then I try to use the variables I defined within that function in another expression. When I do this, I get an error that is:
Undefined function or variable 'phi'.
I'm not sure why phi is undefined, since I have it in the if/else statement.
It might be better to explain with my (shortened) code:
global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40...
C110 C120 C130 C210 C220 C230 C310 C320 C330 IC K0
IC = [w10 w20 w30...
eps10 eps20 eps30 eps40...
C110 C120 C130 C210 C220 C230 C310 C320 C330];
opts = odeset('RelTol', 1*10^(-10),'AbsTol', 1*10^(-10));
[t, y] = ode45(#(t,y) DynEqn2(t,y,I11,I22,I33,Mx,My,Mz), [ti tf], IC, opts);
N = sqrt(sum(y(:,4:7).^2,2));
kap = acosd(1-2*y(:,5).^2-2*y(:,7).^2);
phi1 = acosd((2.*(y(:,4).*y(:,5)+y(:,6).*y(:,7)))/sind(kap));
phi2 = asind((2.*(y(:,6).*y(:,4)-y(:,5).*y(:,7)))/sind(kap));
if phi1==phi2
phi = phi1;
elseif phi1==180-phi2
phi = phi1;
elseif -phi1==phi2
phi = -phi1;
elseif -phi1==180-phi2
phi = -phi1;
else
disp('Something is wrong with phi')
end
figure (1)
plot(t,phi)
figure (2)
plot(t,kap)
function soln = DynEqn2(t,y,I11,I22,I33,Mx,My,Mz)
w1 = y(1);
w2 = y(2);
w3 = y(3);
eps1 = y(4);
eps2 = y(5);
eps3 = y(6);
eps4 = y(7);
C11 = y(8);
C12 = y(9);
C13 = y(10);
C21 = y(11);
C22 = y(12);
C23 = y(13);
C31 = y(14);
C32 = y(15);
C33 = y(16);
w1_dot = (Mx - w2*w3*(I33-I22))/I11;
w2_dot = (My - w1*w3*(I11-I33))/I22;
w3_dot = (Mz - w1*w2*(I22-I11))/I33;
eps1_dot = .5*(w1*eps4-w2*eps3+w3*eps2);
eps2_dot = .5*(w1*eps3+w2*eps4-w3*eps1);
eps3_dot = .5*(-w1*eps2+w2*eps1+w3*eps4);
eps4_dot = -.5*(w1*eps1+w2*eps2+w3*eps3);
C11_dot = C12*w3-C13*w2;
C12_dot = C13*w1-C11*w3;
C13_dot = C11*w2-C12*w1;
C21_dot = C22*w3-C23*w2;
C22_dot = C23*w1-C21*w3;
C23_dot = C21*w2-C22*w1;
C31_dot = C32*w3-C33*w2;
C32_dot = C33*w1-C31*w3;
C33_dot = C31*w2-C32*w1;
soln = [w1_dot; w2_dot; w3_dot; ...
eps1_dot; eps2_dot; eps3_dot; eps4_dot; ...
C11_dot; C12_dot; C13_dot; C21_dot; C22_dot; C23_dot; C31_dot; C32_dot; C33_dot];
end
My lines where I calculate phi1, phi2, and then the if/else statement to find phi, are what I am struggling with.
I made sure that the variables defined in the function work, so for example, in the command window I typed in 'y(:,4)' and got the correct output. But whenever I try to use this within the functions i.e. 'phi1', it repeatedly outputs an incorrect value of '90.0000' until I stop it.
Where I define the 'N' variable, it is something similar, yet that one works without errors.
Does anyone have any ideas how to amend this issue?
Any help is appreciated, thanks.
Edit: The complete error message is as follows:
Undefined function or variable 'phi'.
Error in HW6_Q1 (line 85)
plot(t,phi)
I figured out my solution with the help from a colleague not on Stack Overflow.
I forgot the ./, which turned my phi into a matrix, rather than a vector which is what I wanted from it.
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
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
I'm trying to plot a function that contains a definite integral. My code uses all anonymous functions. When I run the file, it gives me an error. My code is below:
%%% List of Parameters %%%
gamma_sp = 1;
cap_gamma = 15;
gamma_ph = 0;
omega_0 = -750;
d_omega_0 = 400;
omega_inh = 100;
d_omega_inh = 1000;
%%% Formulae %%%
gamma_t = gamma_sp/2 + cap_gamma/2 + gamma_ph;
G = #(x) exp(-(x-omega_inh).^2./(2*d_omega_inh.^2))./(sqrt(2*pi)*d_omega_inh);
F = #(x) exp(-(x-omega_0).^2./(2*d_omega_0.^2))./(sqrt(2*pi)*d_omega_0);
A_integral = #(x,y) G(x)./(y - x + 1i*gamma_t);
Q_integral = #(x,y) F(x)./(y - x + 1i*gamma_t);
A = #(y) integral(#(x)A_integral(x,y),-1000,1000);
Q = #(y) integral(#(x)Q_integral(x,y),-3000,0);
P1 = #(y) -1./(1i.*(gamma_sp + cap_gamma)).*(1./(y + 2.*1i.*gamma_t)*(A(y)-conj(A(0)))-1./y.*(A(y)-A(0))+cap_gamma./gamma_sp.*Q(y).*(A(0)-conj(A(0))));
P2 = #(y) conj(P1(y));
P = #(y) P1(y) - P2(y);
sig = #(y) abs(P(y)).^2;
rng = -2000:0.05:1000;
plot(rng,sig(rng))
It seems to me that when the program runs the plot command, it should put each value of rng into sig(y), and that value will be used as the y value in A_integral and Q_integral. However, matlab throws an error when I try to run the program.
Error using -
Matrix dimensions must agree.
Error in #(x,y)G(x)./(y-x+1i*gamma_t)
Error in #(x)A_integral(x,y)
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 133)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 76)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 89)
Q = integralCalc(fun,a,b,opstruct);
Error in #(y)integral(#(x)A_integral(x,y),-1000,1000)
Error in
#(y)-1./(1i.*(gamma_sp+cap_gamma)).*(1./(y+2.*1i.*gamma_t)*(A(y)-conj(A(0)))-1. /y.*(A(y)-A(0))+cap_gamma./gamma_sp.*Q(y).*(A(0)-conj(A(0))))
Error in #(y)P1(y)-P2(y)
Error in #(y)abs(P(y)).^2
Error in fwm_spec_diff_paper_eqn (line 26)
plot(rng,sig(rng))
Any ideas about what I'm doing wrong?
You have
>> rng = -2000:0.05:1000;
>> numel(rng)
ans =
60001
all 60001 elements get passed down to
A = #(y) integral(#(x)A_integral(x,y),-1000,1000);
which calls
A_integral = #(x,y) G(x)./(y - x + 1i*gamma_t);
(similar for Q). The thing is, integral is an adaptive quadrature method, meaning (roughly) that the amount of x's it will insert into A_integral varies with how A_integral behaves at certain x.
Therefore, the amount of elements in y will generally be different from the elements in x in the call to A_integral. This is why y-x +1i*gamma_t fails.
Considering the complexity of what you're trying to do, I think it is best to re-define all anonymous functions as proper functions, and integrate a few of them into single functions. Look into the documentation of bsxfun to see if that can help (e.g., bsxfun(#minus, y.', x) instead of y-x could perhaps fix a few of these issues), otherwise, vectorize only in x and loop over y.
Thanks Rody, that made sense to me. I keep trying to use matlab like mathematica and I forget how matlab does things. I modified the code a bit, and it produces the right result. The integrals are evaluated very roughly, but it should be easy to fix that. I've posted my modified code below.
%%% List of Parameters %%%
gamma_sp = 1;
cap_gamma = 15;
gamma_ph = 0;
omega_0 = -750;
d_omega_0 = 400;
omega_inh = 100;
d_omega_inh = 1000;
%%% Formulae %%%
gamma_t = gamma_sp/2 + cap_gamma/2 + gamma_ph;
G = #(x) exp(-(x-omega_inh).^2./(2*d_omega_inh.^2))./(sqrt(2*pi)*d_omega_inh);
F = #(x) exp(-(x-omega_0).^2./(2*d_omega_0.^2))./(sqrt(2*pi)*d_omega_0);
A_integral = #(x,y) G(x)./(y - x + 1i*gamma_t);
Q_integral = #(x,y) F(x)./(y - x + 1i*gamma_t);
w = -2000:0.05:1000;
sigplot = zeros(size(w));
P1plot = zeros(size(w));
P2plot = zeros(size(w));
Pplot = zeros(size(w));
aInt_range = -1000:0.1:1200;
qInt_range = -2000:0.1:100;
A_0 = sum(A_integral(aInt_range,0).*0.1);
for k=1:size(w,2)
P1plot(k) = -1./(1i*(gamma_sp + cap_gamma)).*(1./(w(k)+2.*1i.*gamma_t).*(sum(A_integral(aInt_range,w(k)).*0.1)-conj(A_0))-1./w(k).*(sum(A_integral(aInt_range,w(k)).*0.1)-A_0)+cap_gamma./gamma_sp.*sum(Q_integral(qInt_range,w(k)).*0.1).*(A_0-conj(A_0)));
P2plot(k) = conj(P1plot(k));
Pplot(k) = P1plot(k) - P2plot(k);
sigplot(k) = abs(Pplot(k)).^2;
end
plot(w,sigplot)