Need help understanding several MATLAB statement - matlab

All are from this post.
What does these statement mean:
error(nargchk(5, 6, nargin));
plot(p(:,1), p(:,2), '.-'), axis equal
And what's this kinda syntax which I haven't quite often seen:
if nargin<6, steps = 36; end

I hope I don't come over as too unhelpful, but have you tried:
using Matlab's built-in help facilities to discover for yourself what the various statements mean ? or
running any of the code ?
All the statements are Matlab intrinsics and well documented. The use of , to separate statements on the same line is a bit unusual (I, for one, would usually put the statements on different lines in your examples), but not incorrect

Take a look at
help plot
help axis
help nargin

Related

matlab - find start and stop of an interesting signal

I have a signal that looks like this :
I would like to find a way to locate the start and end of the portion of the middle.
What I did, is for the values above and below 0.5 to be a constant ==> 1, and if I find many times 1 in the row it means that it's my signal... but it's not a good way I guess! First my "threshold" would not be every time 0.5, and I am sure it exists some better way to do so.
If you guys have some documentations or ideas about that..
Thank you very much.
As mentioned by the others it is more of a DSP question and dsp.stackexchange.com will propably give you a better answer, but until then this might help:
data=csvread('acceleration.txt',1)
threshold_y=max(data)*0.5; %Thanks to GameOfThrows
thershold_x=101; %how many zeros can be between to ones to still count as continuous
addframe=50; %if you want a little bit of data before and after the active area
logic_index=data>threshold_y;
num_index=find(logic_index);
distance=diff(num_index);
gaps=[1 ; find(distance>thershold_x)]; %find the gaps bigger than your threshold
final_index=false(length(data),1);
for i=1:length(gaps)-1 %add ones between
final_index(num_index(gaps(i)+1)-addframe:num_index(gaps(i+1))+addframe)=true;
end
plot(x,data,x,final_index);
it is basically what you decribed in your question but with the addition of dealing with the zeros inbetween an area. thanks to #GameofThrows for the threshold idea.

Speeding up integration methods MATLAB

I am using MATLAB to execute a triple integral using integral3 and it is running very slow. I was wondering if there ways to speed it. I am guessing its due to the fact that I set the abstol wrong. Not sure how to handle it. PS the code below works with no syntax error. There are a couple of things I dont know how to pick, abstol, method etc..
clear all
syms gamma1
syms gamma2
syms z
syms v
Nt=16; sigmanoise=10^(-7.9); c3=0.129; c1=(1-c3)/2;a2=0;b2=0;
a1=0.0030; b1= 0.0030; A1= 1.5625e-04,A2=0; B1= 7.8125e-05;B2=0;
theta= 3.1623;lambda1= 4.9736e-05;lambda2=0;p1=1;p2=0; alpha1=2; alpha2=4;delta1=2/alpha1; delta2=2/alpha2;beta1=0.025; beta2=0.025;
a= gamma1^-1+gamma2^-1+2*gamma1^(-0.5)*gamma2^(-0.5);
laplacesgi=(exp(+2*pi*j.*z*a)-1)./(2*pi*j*z);
laplacesgi=matlabFunction(laplacesgi);
laplacenoi=exp(-2*pi*j.*z*theta*sigmanoise/Nt);
laplacenoi=matlabFunction(laplacenoi);
interfere= #(gamma1,gamma2,v,z)( (1 -2*c1-c3./(1+2*pi*j*z*theta*v.^(-1))).*(A1.*(v).^(delta1-1).*exp(-a1.*(v).^ (delta1./2))+B1.*(v).^(delta2-1) .*(1-exp(-b1.*(v).^ (delta2./2)))));
gscalar =#(gamma1,gamma2,z)integral(#(v)(interfere(gamma1,gamma2,v,z)),gamma2,inf);
g = #(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z);
lp= A1*(gamma1)^(delta1-1)*exp(-a1*(gamma1)^ (delta1/2))+B1*(gamma1)^(delta2-1)*(1-exp(-b1*(gamma1)^ (delta2/2)))+A2*gamma1^(delta1-1)*exp(-a2*gamma1^(delta1/2))+ B2*gamma1^(delta2-1)*(1-exp(-b2*gamma1^ (delta2/2)));%;
dk1=((2*pi*lambda1))/(beta1^2)*(1-exp(-a1*(gamma2)^(delta1/2))*(1+(gamma2)^(delta1/2)*a1))+ pi*lambda1*gamma2^(delta2)*p1^delta2-((2*pi*lambda1)/(beta1^2))*(1-exp(-b1*(gamma2)^(delta2/2))*(1+(gamma2)^(delta2/2)*b1));
dk2=((2*pi*lambda2))/(beta2^2)*(1-exp(-a2*(gamma2)^(delta1/2))*(1+(gamma2)^(delta1/2)*a2))+ pi*lambda2*gamma2^(delta2)*p2^delta2-((2*pi*lambda2)/(beta2^2))*(1-exp(-b2*(gamma2)^(delta2/2))*(1+(gamma2)^(delta2/2)*b2));
dk=dk1+dk2;
lcp= A1*(gamma2)^(delta1-1)*exp(-a1*(gamma2)^ (delta1/2))+B1*(gamma2)^(delta2-1)*(1-exp(-b1*(gamma2)^ (delta2/2)))+A2*gamma2^(delta1-1)*exp(-a2*gamma2^ (delta1/2))+ B2*gamma2^(delta2-1)*(1-exp(-b2*gamma2^(delta2/2)));%;
pdflast=lp*lcp*exp(-dk);
pdflast=matlabFunction(pdflast);
pdflast= #(gamma1,gamma2)arrayfun(pdflast,gamma1,gamma2);
gamma2min=#(gamma1)gamma1;
warning('off','MATLAB:integral:MinStepSize');
T = integral3(#(gamma1,gamma2,z)(laplacenoi(z).*laplacesgi(gamma1,gamma2,z).*pdflast(gamma1,gamma2).*exp(-g(gamma1,gamma2,z))),0,inf,#(gamma2)gamma2,inf,0.05,1000,'abstol',1e-3)
I appreciate any ideas or suggestions.
This is getting way too long for a comment, and while it doesn't really give an answer either, I think it may be helpful anyway, so I will slightly abuse the answer form for it.
Code Readability
I don't think your code as it stands fulfills the basic fundamental purpose of code: Communicating with a human being, probably yourself down the road.
I don't know if the variable names are unambiguous enough that in six months, they will still tell you exactly what is what. If they are, great. If not, you may want to improve upon them. (And yes, naming stuff is one of the hardest parts of programming, but that doesn't make it less important.)
The same holds true for comments: If you don't need comments on your formulas, more power to you. I have no idea what you are computing, so the fact that I don't understand your formulas doesn't mean much. But again, think of yourself in a few months, looking for a problem: Would you have wished for a comment such that you know if that factor is really correct or off by one?
Here's something I do know: Your formulas are simply too wide to be comprehended at once. Simple reformatting helps to see the structure better. Here's how I reformatted your code to start making heads or tails from it:
clear all
syms gamma1
syms gamma2
syms z
syms v
Nt=16;
sigmanoise=10^(-7.9);
c3=0.129;
c1=(1-c3)/2;
a2=0;
b2=0;
a1=0.0030;
b1=0.0030;
A1=1.5625e-04;
A2=0;
B1=7.8125e-05;
B2=0;
theta=3.1623;
lambda1=4.9736e-05;
lambda2=0;
p1=1;
p2=0;
alpha1=2;
alpha2=4;
delta1=2/alpha1;
delta2=2/alpha2;
beta1=0.025;
beta2=0.025;
a=gamma1^(-1)+gamma2^(-1)+2*gamma1^(-0.5)*gamma2^(-0.5);
laplacesgi=matlabFunction((exp(2*pi*1j*z*a)-1)./(2*pi*1j*z));
laplacenoi=matlabFunction(exp(-2*pi*1j*z*theta*sigmanoise/Nt));
interfere= #(gamma1,gamma2,v,z)( ...
(1 -2*c1-c3./(1+2*pi*j*z*theta*v.^(-1))).*(A1.*v.^(delta1-1).* ...
exp(-a1.*v.^(delta1./2))+B1.*v.^(delta2-1).*(1-exp(-b1.*v.^(delta2./2)))));
gscalar=#(gamma1,gamma2,z)integral(#(v)(interfere(gamma1,gamma2,v,z)),gamma2,inf);
g=#(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z);
lp=A1*gamma1^(delta1-1)*exp(-a1*gamma1^(delta1/2))+ ...
B1*gamma1^(delta2-1)*(1-exp(-b1*gamma1^(delta2/2)))+ ...
A2*gamma1^(delta1-1)*exp(-a2*gamma1^(delta1/2))+ ...
B2*gamma1^(delta2-1)*(1-exp(-b2*gamma1^(delta2/2)));
dk1=((2*pi*lambda1))/(beta1^2)*(1-exp(-a1*gamma2^(delta1/2))*(1+gamma2^(delta1/2)*a1))+ ...
pi*lambda1*gamma2^(delta2)*p1^delta2- ...
((2*pi*lambda1)/(beta1^2))*(1-exp(-b1*gamma2^(delta2/2))*(1+gamma2^(delta2/2)*b1));
dk2=((2*pi*lambda2))/(beta2^2)*(1-exp(-a2*gamma2^(delta1/2))*(1+gamma2^(delta1/2)*a2))+ ...
pi*lambda2*gamma2^(delta2)*p2^delta2- ...
((2*pi*lambda2)/(beta2^2))*(1-exp(-b2*gamma2^(delta2/2))*(1+gamma2^(delta2/2)*b2));
dk=dk1+dk2;
lcp=A1*gamma2^(delta1-1)*exp(-a1*gamma2^(delta1/2))+ ...
B1*gamma2^(delta2-1)*(1-exp(-b1*gamma2^(delta2/2)))+ ...
A2*gamma2^(delta1-1)*exp(-a2*gamma2^(delta1/2))+ ...
B2*gamma2^(delta2-1)*(1-exp(-b2*gamma2^(delta2/2)));
pdflast=matlabFunction(lp*lcp*exp(-dk));
pdflast=#(gamma1,gamma2)arrayfun(pdflast,gamma1,gamma2);
gamma2min=#(gamma1)gamma1;
T = integral3(#(gamma1,gamma2,z)( ...
laplacenoi(z).*laplacesgi(gamma1,gamma2,z).*pdflast(gamma1,gamma2).*exp(-g(gamma1,gamma2,z))), ...
0,inf,...
#(gamma2)gamma2,inf,...
0.05,1000,...
'abstol',1e-3)
A few notes one this:
MATLAB is one of the languages that require an indication that the logical line should continue after the physical line break. The indication in MATLAB is three dots.
Get rid of any and all warnings the MATLAB editor shows you. In very rare cases, by disabling the warning for this line; usually, by correcting your code. Some of these warnings may seem over-protective, but coe quickly reaches the point where none of us can have enough of it in our minds to see the more subtle problems, and linting helps avoid a fair number of them, in my experience.
Consistent spacing helps, in the same way “proper” (i.e., standardized) spelling makes reading English easier: The patterns are just much more obvious.
Line breaks should in general not be done haphazardly, but emphasizing the structure of commands and formulas. In several of your formulas, I have seen symmetries between input parameters and tried to make them obvious by placing the line breaks accordingly. That helps a lot when looking for typos.
Your code has lines such as these:
pdflast=lp*lcp*exp(-dk);
pdflast=matlabFunction(pdflast);
I used to recycle variables like that, too. Over time, I learned the hard way that it helps for debugging and readability not to, especially if your values have different types, as they do here.
There are a few points I would still clean up at this point. For example, pdflast works just fine on arrays and the line pdflast= #(gamma1,gamma2)arrayfun(pdflast,gamma1,gamma2); should be deleted, and the lower bound for gamma2 in the integral3 call is a function of gamma1 and should be changed to #(gamma1)gamma1.
Does the computer/MATLAB care about any of this? Maybe something slipped in where it does, but basically: No. All of these changes are for you, and if you send your code in an SO post, for us, the readers.
(Likely) Bug: Vectorization
I think your definition of g is wrong:
g=#(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z);
The cubature (i.e., integral3) will try to call this function with non-scalar values for one or more of the parameters. Most likely, these will not all be of the same size, and even if they were, it would expect to get a 3D result, not a vector. Try calling your g that way:
>> g(1:2,1,1)
Error using arrayfun
All of the input arguments must be of the same size and shape.
Previous inputs had size 2 in dimension 2. Input #3 has size 1
Error in #(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z)
It's really a good idea to check intermediate building blocks like that. What your really need to have is an arrayfun over gamma2, something like this:
gscalar=#(gamma1,gamma2,z) ...
integral(#(v)(interfere(gamma1,gamma2,v,z)),gamma2,inf, ...
'ArrayValued',true);
g = #(gamma1,gamma2,z)arrayfun(#(gamma2)gscalar(gamma1,gamma2,z),gamma2);
(Possible) Bug: Definition of interfere
I don't know if you tried checking interfere against any known or suspected values. (Sanity checks for formulas I just typed seem a really good idea to me.) I somehow doubt that the formula is correctly capturing your intent:
interfere=#(gamma1,gamma2,v,z)( ...
(1-2*c1-c3./(1+2*pi*1j*z*theta*v.^(-1))).*(A1.*v.^(delta1-1).* ...
exp(-a1.*v.^(delta1./2))+B1.*v.^(delta2-1).*(1-exp(-b1.*v.^(delta2./2)))));
The potential problem with this formula (apart from a somewhat inconsistent use of * vs. .* etc.) is that the values do not depend on gamma1 and gamma2 at all.
Of course, that can happen, but if you actually mean it to be the case, what is the rationale for including gamma1 in the formula in the first place?
If this is as it should be, you may need to still make the result the proper size: Right now, interfere simply ignores its first two inputs, which may trip up the integrator: interfere(1:3,1,1,1) should return a 3-element vector.
Concluding Thoughts
As you may have noticed, your question did not get a satisfying answer yet. Nor do I think in its current form it will. To get volunteers to look at your problem, you need to make it easy to understand what you are doing:
Start by simplifying your formulas. They may not be of interest to you anymore, but right now, they're just clutter.
Trim down your parameters. That is somehow part of the above.
Throw out things that are probably irrelevant. Apart from the point that you don't need (and probably don't want) an additional arrayfun around the matlabFunction results, symbolic math is likely to be irrelevant to your actua question on integral3. If you can ask your question without it, it may attract more attention.
For anything you cannot trim down, consider explaining what is happening.
Of course, in this process, for each iteration, test your code (after saying clear all or in a fresh MATLAB session!) to check if the problem is still there. If it is not, you may have found a hint where your basic problem is hiding.
For a longer discussion on the topic, see https://meta.stackexchange.com/questions/18584/how-to-ask-a-smart-question and the guides linked to within that discussion.

Failed to plot simple graph in Octave

I want to draw a line on a graph to find the intersection point with another line. However, there's no response after I executed the script below. May I know what is the problem and how can I solve it?
x=1:2^20;
y2=2^24;
plot(x,y2);
Thanks!
What you want is to plot a line on 2^24. However, there are too many points for you computer probably, and you run out of memory
I am guessing that you'll need to plot your other inequality as well.
Something like
x=1:100:2^20;
% As Zoran and others suggested, You may not want all the points!
% It is too much memory
y2=2^24*ones(size(x)); % This ones is optional, but its good to know what you are doing (personal opinion)
plot(x,y2);
hold on
y1=(x+1).*log(x);
plot(x,y1);
However, you are still not there!
Another solution, which does not rely on plotting:
>> f = #(x) (x+1)*log(x)-2^24;
>> soln = fzero(f,1e6)
soln = 1.1987e+006
>> f(soln)
ans = 3.7253e-009
So your intersection point is at 1.1987e6.
Apparently,you have too many points for x, 2^20
Have to wait program to calculate, or plot,for example, every 100th point
This solution works for Matlab
x=1:100:2^20;
y2=2^2;
plot(x,y2,'o');
There is one more and maybe a bit smarter way: if you want to solve ((k+1)(ln k)<2^24) as you've commented above, use fsolve function to get just solution of an equation(!). Then use that solution to specify the area of your interest, so you won't have to plot the domain of 2^20.
(All functions are continuous so you don't have to worry about any wild singularities. Just examine the neigborhood of ks for which (k+1)(ln k)-2^24=0.)

for loop range syntax

I spent a couple of hours debugging a problem that I would have thought would have been a syntax error.
a = zeros(3);
for i=1:1size(a,2) % note the missing colon between 1 and size(a,2)
i
end
The following only displays
ans = 3
1
Essentially, it seems Matlab/Octave parses the above as:
for i=1:1
size(a,2)
i
end
Note however that
i=1:1size(a,2)
produces a syntax error. Is there a good reason that Matlab/Octave has this for loop syntax? Is there something that it's supposed to make easier? Just curious if anyone else has any thoughts about it. Thanks.
It is indeed a bit of a surprise that Matlab's syntax allows this. I don't know why this is allowed. One reason might be to allow for-loops on one line:
>> for i=1:3 disp(i);end
1
2
3
But interestingly, removing the space is not allowed:
>> for i=1:3disp(i);end
for i=1:3disp(i);end
|
Error: Unexpected MATLAB operator.
This reason for this is probably that a number followed by d is another way of writing a floating point number (3d10 == 3e10), so the parser/tokenizer initially thinks you define a number, but then gets confused when it sees the i. Daniel's example with fprintf does work, since a number followed by an f is not a valid number, so the tokenizer understands that you started a new token.
I guess that many years ago (>30?), when they defined matlab's syntax, they did not foresee that this could introduce this kind of hard-to-spot problems. I guess matlab was originally written by engineers for engineers, and not by someone who knows how to design a general purpose programming language. Other languages like C or Python use punctuation to separate loop conditions from loop body, so there is no ambiguity. I don't know if it is still possible to correct Matlab's syntax, since it might break old code that relies on the current behavior.
At least, if you use a recent version of Matlab, the editor warns for various problems in your code. Paying attention to the small red dashes in the right hand border could have saved you a few hours of debugging time (but maybe you were using octave). I try to make it a habit to fix all the warnings it indicates. For your code, it shows the following:
Your code is equivalent to
a = zeros(3);
for i=1:1
size(a,2)
i
end
There are some places where everyone would use newline or white space, but the parser itself does not require.
A minimal loop:
for i=1:3fprintf('%d',i),end
but I recommend to use at least a comma seperated version, everything else is horrible to read:
for i=1:3,fprintf('%d',i),end

Patch with transparency and timestamp indexes breaks figure

I am having trouble plotting a patch on a figure with transparency and timestamp index varying in datenum range of 735k, which is more or less the datenum you will acquire for the actual dates.
The following example illustrate my issue:
k=[735172.912437674 735172.941375799 0 7830];
figure;
axis(k);
p=patch([k(1) k(1) k(2) k(2)], [k(3) k(4) k(4) k(3)],[0 0 0 0],'r', 'FaceAlpha', 0.1);
Are you able to reproduce this bug? Any suggestions? I've seen this other post and searched about it, but no clue. I wouldn't like to remove the minimum from my time stamps, I would have to adapt all the code just because of this x(
I was learning about this other question and they led me to study a bit the new Handle Graphics that may finally appear this or next year (?) — looks like trying to discovering trends at financial business, guess when this will go out, if it will haha. It may be used by adding -hgVersion 2 option at your matlab launch. And by doing so, the resulting figure looks like this \o/:
Great… but beware that there are some differences on the usage from the HG1 to the HG2 that may lead your code not to work (specially if you are using listeners) but if you want to explore this even more undocumented code add an if in your codes where it breaks:
if feature('UseHG2')
% HG2 approach
else
% HG1 approach
end
One good thing it's that at least we can get the meta.class from the handles, so we can explore them easier x) and the usage is quite more intuitive with the matlab oop development way.