Too many output arguments - matlab

I am not a very hardcore coder in MATLAB, i have learned every thing from youtube and books. This might be a very simple question but i do not know what search for answer.
In MATLAB i am trying to do something like this.
>>[a,b,c] = [1,2,3]
and i want output like this.
>> a = 1
b = 2
c = 3
So Bsically question is that : - User will define the matrix of variables([a,b,c]) in staring of code and during process of the code similar matrix will be displayed and as input a matrix will be asked([1,2,3]). I dont know how do this without writing a loop code in which i will take every single variable from variable matrix and save the value in that variable by eval function.
well above written code is wrong and i know, i can do this with "for" loop and "eval" function.
but problem is that no. of variables(a,b,c) will never be constant and i want know if there exist any in built function or method in MATLAB which will work better than a for loop.
As i told earlier i don't know what to search for such a problem and either this is a very common question.
Either way i will be happy if you can at least tell me what to search or redirect me to a related question.
Please do write if you want any more information or for any correction.
Thank you.

The deal function can do this for a fixed number of inputs:
[A,B,C]=deal(1,2,3)
If you don't know how many inputs you will get beforehand, you have to do some fooling around. This is what I've come up with:
V=[1,2,3,4,5,6,7]
if length(V)>1
for i=1:length(V)
S{i}=['A' num2str(i)];
G{i}=['V(' num2str(i) ')'];
end
T=[S{1} ','];
R=[G{1} ','];
for i=2:length(V)-1
T=[T S{i} ','];
R=[R G{i} ','];
end
T=[T S{length(V)}];
R=[R G{length(V)}];
eval(['[' T ']=deal(' R ')'])
else
A1=V
end
But then dealing with A1, ... , An when you don't know how many there are will be a pain!

This is somehow known as "tuple unpacking" (at least it's what I would search in python!). I could find this thread which explains that you could do this in Octave (I checked and it works in Matlab also). You have to transform the vector into a cell array before:
values = num2cell([1,2,3])
[a,b,c] = values{:}

Related

How to get the zeros of the given equation using fzero in MATLAB?

I have the following function that I wish to solve using fzero:
f = lambda* exp(lambda^2)* erfc(lambda) - frac {C (T_m - T_i)}/{L_f*sqrt(pi)}
Here, C, T_m, T_i, and L_f are all input by the user.
On trying to solve using fzero, MATLAB gives the following error.
Undefined function or variable 'X'.
(where X are the variables stated above)
This error is understandable. But is there a way around it? How do I solve this?
This is answered to the best of my understanding after reading your question as it's not really clear what you are exactly trying and what you want exactly.
Posting the exact lines of code helps a big deal in understanding(as clean as possible, remove clutter). If then the output that matlab gives is added it becomes a whole lot easier to make sure we answer your question properly and it allows us to try it out. Usually it's a good idea to give some example values for data that is to be entered by the user anyway.
First of to make it a function it either needs a handle.
Or if you have it saved it as a matlab file you generally do not want other inputs in your m file then the variable.
So,
function [out]=yourfun(in)
constants=your values; %you can set a input or inputdlg to get a value from the user
out= something something, your lambda thingy probably; %this is the equation/function you're solving for
end
Now since that is not all that convenient I suggest the following
%declare or get your constants here, above the function makes it easier
syms lambda
f = lambda* exp(lambda^2)* erfc(lambda) - frac {C (T_m - T_i)}/{L_f*sqrt(pi)};
hf=matlabFunction(f); %this way matlab automatically converts it to a function handle, alternatively put #(lambda) in front
fzero(hf,x0)
Also this matlab page might help you as well ;)

vectorizing "for" loop with bidirectionally related variables

Last week I asked the following:
https://stackoverflow.com/questions/32658199/vectorizing-gibbs-sampler-in-matlab
Perhaps it was not that clear what I want to do, so this might be more clear.
I would like to vectorize a "for" loop in matlab, where some variables inside of the loop are bidirectionally related. So, here is an example:
A=2;
B=3;
for i=1:10000
A=3*B;
B=exp(A*(-1/2))
end
Thank you once again for your time.
A quick Excel calculation indicates that this quickly converges to 0.483908 (after much less than 10000 loops - so one way of speeding it up would be to check for convergence). If A and B are always 2 and 3 respectively, you could just replace the loop with this value.
Alternatively, using some series analysis you might be able to come up with an analytical expression for B when i is large - although with the nested exponents deriving this is a bit beyond my own abilities!
Edit
A bit of googling reveals this. Wikipedia states that for a tetration of x to infinity (i.e. x^x^x^x^x...), the solution y satisfies y = x^y. In your case, for example, 0.483908 = e^(-3/2)^0.483908, so 0.483908 is a solution. Not sure how you would exploit this though.
Wikipedia also gives a convergence condition, which might be of use to you: x lies between e^-e and e^1/e.
Final Edit (?)
Turns out you need Lambert's W function to solve for equations of the form of y = x^y. There seems to be no native function for this, but there seems to be something in the FileExchange - see here and here.

Vectorising matlab function

I'm writing a function to get the cosine of a given array. It works but I'm presently using a loop in order to iterate over each value in the array whereas I'm assured that it can be vectorised.
Presently the code is:
for i = 1:numel(x)
cos(i) = (sum(((-1).^(0:n)).*(x(i).^(2*(0:n)))./(factorial(2*(0:n)))));
end
and I can't for the life of me think how it vectorises, so any help would be appreciated.
EDIT: Here is the full function http://pastebin.com/n1DG6nUv
2nd EDIT: link updated with new code that doesn't overwrite cos.
Here's one way using bsxfun and gamma:
v = 0:n;
fcos = zeros(size(x));
fcos(:) = sum(bsxfun(#times,bsxfun(#power,x(:),2*v),(-1).^v./gamma(2*v+1)),2)
In the spirit of learning, note that you have several issues with the code in your question. First, you don't preallocate memory. Second, you're overwriting the cos function, which is probably not a good idea. Also, I believe that using gamma(n+1) instead of factorial(n) will be faster. Finally, there are many unnecessary parentheses that make the code hard to read.

Matlab plot won't return correct results

I have written a function that is the beginning of a Poisson Process
function n_t = PoisProc2(t,tao,SIZE)
n_t=0;
for n=1:SIZE
if t>tao(1,n)
n_t=n_t+1;
end
end
end
tao is simply an array of random doubles of length SIZE. For simplicity we'll say [1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,20]
So this functions purpose is to count how many elements of tao that t is greater than for any given t.
This code works fine when I simply write
PoisProc2(3,tao,20);
the answer I get is 19 as expected, but if I write
x=1:.01:20;
y=PoisProc2(x,tao,20);
plot(x,y,'-')
y shows up as 0 in the workspace (I would expect an array of length 1901) and my plot also reads 0. I'm pretty new to Matlab, but this seems like a pretty simply thing I'm trying to do and I must be missing something obvious. Please help!
Your code does not work as you are giving a vector. So your if condition is not working as you expect.
First initialize n_t with a vector :
n_t=zeros(1,length(t))
instead of
if t>tao(1,n)
n_t=n_t+1;
end
Vectorize your expression :
n_t = n_t + (t>tao(1,n))
Cheers
Because x is a vector in your last example, the "if t>tao(1,n)" statement in your function behave totally different from what you think.
This function below should give you the right result.
function ret = PoisProc2(thresholds, vec)
ret = zeros(size(thresholds));
for k = 1:numel(thresholds)
ret(k) = numel(nonzeros(vec > thresholds(k)));
end
Side comments:
Your original function is quite C/Java style. You can see in my function, it's replaced by a one-liner "numel(nonzeros(vec > thresholds(k)))", which is more MATLAB style.
I think this can be done with hist() function. But this probably is easier to understand.

How to sort in ascending order the solution vector in each iteration using ODE?

I've got an ODE system working perfectly. But now, I want in each iteration, sort in ascending order the solution vector. I've tried many ways but I could not do it. Does anyone know how to do?
Here is a simplified code:
function dtemp = tanque1(t,temp)
for i=1:N
if i==1
dtemp(i)=(((-k(i)*At*(temp(i)-temp(i+1)))/(y))-(U*As(i)*(temp(i)-Tamb)))/(ro(i)*vol_nodo*cp(i));
end
if i>1 && i<N
dtemp(i)=(((k(i)*At*(temp(i-1)-temp(i)))/(y))-((k(i)*At*(temp(i)-temp(i+1)))/(y))-(U*As(i)*(temp(i)-Tamb)))/(ro(i)*vol_nodo*cp(i));
end
if i==N
dtemp(i)=(((k(i)*At*(temp(i-1)-temp(i)))/(y))-(U*As(i)*(temp(i)-Tamb)))/(ro(i)*vol_nodo*cp(i));
end
end
end
Test Script:
inicial=343.15*ones(200,1);
[t temp]=ode45(#tanque1,0:360:18000,inicial);
It looks like you have three different sets of differential equations depending on the index i of the solution vector. I don't think you mean "sort," but rather a more efficient way to implement what you've already done - basically vectorization. Provided I haven't accidentally made any typos (you should check), the following should do what you need:
function dtemp = tanque1(t,temp)
dtemp(1) = (-k(1)*At*(temp(1)-temp(2))/y-U*As(1)*(temp(1)-Tamb))/(ro(1)*vol_nodo*cp(1));
dtemp(2:N-1) = (k(2:N-1).*(diff(temp(1:N-1))-diff(temp(2:N)))*At/y-U*As(2:N-1).*(temp(2:N-1)-Tamb))./(vol_nodo*ro(2:N-1).*cp(2:N-1));
dtemp(N) = (k(N)*At*(temp(N-1)-temp(N))/y-U*As(N)*(temp(N)-Tamb))/(ro(N)*vol_nodo*cp(N));
You'll still need to define N and the other parameters and ensure that temp is returned as a column vector. You could also try replacing N with the end keyword, which might be faster. The two uses of diff make the code shorter, but, depending on the value of N, they may also speed up the calculation. They could be replaced with temp(1:N-2)-temp(2:N-1) and temp(2:N-1)-temp(3:N). It may be possible to collapse these down to a single vectorized equation, but I'll leave that as an exercise for you to attempt if you like.
Note that I also removed a great many unnecessary parentheses for clarity. As you learn Matlab you'll to get used to the order of operations and figure out when parentheses are needed.