About using quad in MATLAB - matlab

I encounter a strange problem with quad function.
I was using quad to calculate simple integral, and it worked for 10 to 20 times, then Matlab issues the following error:
Error using quad (line 75)
The integrand function must return an output vector of the same length as the input vector.
yteor(k) = quad(#(q)(exp(-(q).^2).*q.^2/(k.^2+1)), 0, 1);
Here q and k are scalars.
I can not get what is wrong and why it worked several hours ago.
Edit
Here is my code
for k=1:100,
xteor(k)=step*k;
yteor(k)=quad(#(q)(exp(-(q).^2).*q.^2/((step.*k+1).^2)),0,1);
end plot(xteor,yteor,'r');

The following snippet works for me on Octave (Matlab GNU clone)
step = 1;
xteor = zeros(100,1);
yteor = zeros(100,1);
for k=1:100,
xteor(k)=step*k;
yteor(k)=quad(#(q)(exp(-(q).^2).*q.^2/((step.*k+1).^2)),0,1);
end
plot(xteor,yteor,'r');
pause
My hypothesis is that your error is the consequence of something else happening earlier in your code (maybe related to step not being a scalar?). Instead of focusing on this line where the error arise. Try to search what you have changed just before the error appear.

Related

Unexpected length of array and plotting error as a result

I wanted to plot the load voltage across the resistor in series with a diode using matlab. This is a rather simple example involving piecewise functions, however I ran into an unexpected error.
t=[0:0.001:10]
vs=4*sin(pi * t)
for i =1:length(vs)
if(vs(i)<=0.7)
v(i)=0;
else
v(i)=vs(i)-0.7;
end
end
plot(t,v)
t is the time, vs is the source voltage, and v is the load voltage. Now, running this gave me an error saying "error, t and v are of different sizes..". Using length() I found out that while t and vs are of lengths 10001, v is somehow of length 1000001.
This is truly baffling to me. How can v and vs possibly differ in size? every element of vs was mapped to an element of v, and yet the size of v comes out to be about 100 times the size of vs.
Being new to matlab, I still am not very comfortable with not explicitly declaring the array v before using it in the for loop. However, I went through with it, because the example I worked on prior to this, used the same thing and it worked without any problems. We simply had a plot a piecewise function:
x=[-2 : 0.00001 : 20];
for i=1: length(x)
if(x(i)>=-2 && x(i)<0)
y(i)=sqrt(x(i)^2+1);
else if(x(i)>=0 && x(i)<10)
y(i)=3*x(i)+1;
else
y(i)=9*sin(5*x(i)-50);
end
end
end
plot(x,y)
This code worked flawlessly, and in my opinion the initial code is fundamentally doing the same thing, so again, I'm clueless as to why it failed.
The original code works if you initialise v to be of the same size as t (and therefore, vs), but still, I want to know why the code involving x,y worked (where y wasn't initialised) and the code involving (t,v) failed.
Also, my friend copy pasted the entire code into the command window of matlab 2016, and it worked. (and I'm using the 2021 version).
Its good practice to initialize variables before entering a loop. It will help avoid undefinied behaviour when you run the script multiple times. If you run the script with different lengths for t, it would fail the second run. One solution would be:
t=0:0.001:10;
vs=4*sin(pi * t);
v=nan(size(t));
for i =1:length(vs)
if(vs(i)<=0.7)
v(i)=0;
else
v(i)=vs(i)-0.7;
end
end
figure;
plot(t,v);
You could also avoid the for loop and use matrix operations instead:
t=0:0.001:10;
vs=4*sin(pi * t);
v=vs-0.7;
v(vs<=0.7)=0;
figure;
plot(t,v);

Descent direction error using fminunc in matlab

I am optimizing a kernel in matlab, but on one of the loops it outputs the following error:
Error using lineSearch Search direction is not a descent direction;
roundoff errors may be affecting convergence.
and exits the whole program. I'm actually fine with there being an error, I just would want it to continue to the next loop rather than exiting the program and making me start all over, only to run into the same error again. Is there a way to just make it just return an NAN or whatever number it managed to hit upon and move on to the next iteration?
Edit:
I have reproduced the error with the following lines of code
options = optimset('Display','off','TolFun',4e-16,'LargeScale','off');
par12=[4.45873897125075124848,2.45448132035209054536,398.23544583453281120455];
psfY12=[332.20478974188495158160,105.81515908458436570072,0,217.29169454128577854135,47.84122489713877257600,398.23544583453281120455,186.32064258820469149214,69.24275387165039319370,33.13754887984555352887];
y12=1:9;
fp1D = fminunc(#errfun,par12,options,psfY12,y12);
function [z] = errfun(p,v,x);
%cx = p(1);
%wx = p(2);
%amp = p(3);
zx = p(3)*exp(-0.5*(x-p(1)).^2./(p(2)^2)) - v;
z = sum(zx.^2);
end
Also I traced the error to the following line:
if strcmpi(output.algorithm, medium)
[x,FVAL,GRAD,HESSIAN,EXITFLAG,OUTPUT] = fminusub(funfcn,x, ...
options,defaultopt,f,GRAD,sizes,flags,finDiffFlags,varargin{:});
But I doing
open fminusub
returns the error:
Error using open (line 86)
File 'fminusub' not found.
fminusub is a private function to fminunc.
One idea is to add 'Display','Iter' to your optimoptions call, so that you can see more details of what the optimizer is doing. It is possible that the optimizer has gotten into a poorly conditioned region, or is close to a local minimum or a saddle point, causing the finite difference approximation of the gradient of your cost function to behave poorly.
One suggestion is to try setting FiniteDifferenceStepSize to some small value in the optimoptions call.
Here's an example:
optimoptions(#fminunc, 'MaxIterations', 10000, 'MaxFunctionEvaluations', 50000, 'Display', 'Iter', 'FiniteDifferenceStepSize', 1e-3);

Error during rm ANOVA (Matlab) with random factor

I am trying to run a repeated measures ANOVA in Matlab with 4 factors including one factor representing my subjects which I want as a random factor.
The code I have is as follows:
[p,table,stats] = anovan(COORDS_SUBJ_II,{group_hand,group_stim,group_time,group_subs},'random',4,'varnames',{'HAND','STIM','TIME','SUBS'});
Here, all variables have the same dimension, which is 1350x1(all types are 'double'). I checked my code with some proposed code on the net and it matches, yet I keep getting the following error...
Error using chi2inv (line 3)
P and V must be of common size or scalars
Error in anovan>varcompest (line 838)
L = msTerm .* dfTerm ./ chi2inv(1-alpha/2,dfTerm);
Error in anovan>getRandomInfo (line 811)
[varest,varci] = varcompest(ems,randomterms,msTerm,dfTerm,alpha);
Error in anovan (line 296)
getRandomInfo(msterm,dfterm,mse,dfe,emsMat,randomterm,...
My dependent variable (COORDS_SUBJ_II) has a couple of NaN's in it, although I ran the code once where I replaced those NaN's with random numbers and it still gives me the same error. I am kind of lost right now and would appreciate any help.
Best
ty
Found it out. A toolbox I downloaded a while ago also had the chi2inv command and this prompted the error =)

MATLAB newbie: error using sprintf. Function is not defined for 'matlab.graphics.GraphicsPlaceholder' inputs

Today I tried to run a MATLAB m-file that someone gave me. It works fine for him, but I encountered a warning and errors (below). I am using a Mac with OS X Yosemite (10.10.5) and a new version of MATLAB (R2015b). The person who prepared the m-file would have used an older one and Windows.
From a blog at Mathworks and posts online/here, the error seems to be due to a MATLAB update--a change from using numeric values to point towards graphics objects to using objects themselves. I understand this in theory, but don't know how to fix my code (it has been years since I used MATLAB regularly, so I'm pretty lost).
Warning: Text handle output is not supported when a contour handle
argument is supplied and label placement is automatic.
In clabel (line 214)
In control_volume_20150706>plot_xxx (line 733)
In control_volume_20150706 (line 104)
In run (line 96)
Error using sprintf
Function is not defined for
'matlab.graphics.GraphicsPlaceholder' inputs.
Error in control_volume_20150706>plot_xxx (line 734)
sprintf('%10.4f \n',text_handle);
Error in control_volume_20150706 (line 104) plot_xxx (nr,
xwidevec, yhighvec, omegamat, psimat, umat, vmat, ...
Error in run (line 96) evalin('caller', [script ';']);
This is what the code looks like in the vicinity of line 733:
Line 731 contourlevels = omegamat(1, :) ;
Line 732 [C,h] = contour(X,
Y, flipud(omegamat), contourlevels, 'LineWidth', 2 );
Line 733
text_handle = clabel(C,h);
Line 734 sprintf('%10.4f \n',text_handle);
I would be very grateful for any hints about how to deal with this.
If h is a handle which refers to some object, then in R2015a and later this is the object itself, while in previous versions it's a double which points to an object (as you noted in the question). You can use h.double in R2015a and later to get what would previously be h. E.g., pre-R2015a h = figure(999) would set h to 999, a double; with R2015a and later h is an object and h.double is 999.

Function works with lsqcurvefit but not nlinfit

I'm attempting to get a nonlinear least squares fit for the following function:
Nloc = 250;
d = 1 / Nloc;
m = 0.5; %Initial guess
ncmfun = #(m, p) arrayfun(#(p) betainc(d, Nloc*m .* p, Nloc*m .* (1 - p), 'upper'), p);
Where m is the parameter being fit, Nloc and d are constants, and p and freq are vectors of positive real numbers and of the same length (I triple checked). When I use lsqcurvefit everything works fine:
[mfit,resnorm,] = lsqcurvefit(ncmfun, m, p, freq, 0, 1)
Also, if I use any m to evaluate the function, everything works fine as well. However when I use nlinfit:
[mfit,R,Jac,CovB,MSE,ErrorModelInfo] = nlinfit(p, freq, ncmfun, m)
I get the following error(s):
Error using betainc
Z must be real and non-negative.
Error in #(p)betainc(d,Nloc*m.*p,Nloc*m.*(1-p),'upper')
Error in
#(m,p)arrayfun(#(p)betainc(d,Nloc*m.*p,Nloc*m.*(1-p),'upper'),p)
Error in nlinfit>#(b,x)w.*model(b,x) (line 206)
modelw = #(b,x) w.*model(b,x);
Error in nlinfit>LMfit (line 486)
yfit = model(beta,X);
Error in nlinfit (line 207)
[beta,J,~,cause,fullr] = LMfit(X,yw,
modelw,beta,options,verbose,maxiter);
Error in Sloan_NCM_Parameterize_Nm (line 37)
[mfit,R,Jac,CovB,MSE,ErrorModelInfo] = nlinfit(p, freq,
ncmfun, m);
What's especially frustrating was this same script was working a couple weeks ago. I then tried to use it again and it no longer works. I tried to go through and see if I accidentally changed something and didn't remember, but I can't find any errors. Furthermore, I'm confused as to why lsqcurvefit works but not nlinfit. I'd like to use nlinfit because it provides me with more statistical information about the error.
Thanks in advance for any help you can provide!
They both use the same algorithm to identify a solution, however, you are explicitly stating an upper and lower bound for your solution in lsqcurvefit which ensures your incomplete beta function behaves. You don't have this option in nlinfit. I'm not sure what you did before (you can always look at the command history)
You have a few options from this point:
1 - programatically intercept every value that goes to ncmfun, by either expending your anonymous functions in what my nightmares are made of, or creating your own m-file for it. If the value is outside of [0,1] return progressively higher error value (with the boundaries being >>> then any possible value within the set)
2 - Try to force a quicker convergence by playing with some of the parameters (perhaps by using a robust fitting option (cf documentation))