MATLAB nesting multiple input functions - matlab

Given a multiple-input MATLAB function
out=f(in1, in2)
I would like to write a second function g which generates the inputs for f, e.g.
[in1, in2]=g(in)
so that I can call something like:
out=f(g(in))
I have tried writing g as a single output function that stores in1 and in2 in a cell array so that I can feed the output of g to f using the colon operator:
in_c=g(in);
out=f(in_c{:})
but I was looking for a one-line solution, which seems not possible to achieve this way as I read in this Stack Overflow question
Is there any other way to do this?

As discussed recently, this is not possible in Matlab.
However, if you do not want to re-write your function g(x,y) to return a cell array, you can still do everything in two lines:
[in4f{1}, in4f{2}] = g(in);
out = f(in4f{:});
As an aside: Unless you're really hurting for memory, it doesn't make a lot of sense to try and force one-line statements everywhere by avoiding temporary variables. Sure, you can make your code look like CrazyPerl, but in the long run, you'll be glad for the added readability.

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 ;)

How to use a M-.file in a parfor loop in Matlab?

my code inside a parfor loop is getting longer and longer and I would like to split it up. Having parts of the code saved in different script files seems logical and very attractive and since it doesn't change anything except where the code is saved it seems like it should work. But it doesn't.
I get the usual "Transparency violation error".
The problem seems typical but I did not find this question asked or answered anywhere.
Below is a small working example.
(Yes, this could be made as a function. But in case of many more Input and Output variables this becomes really ugly imo and probably also slower due to communicating the arguments)
C = NaN(10,1); %Result vector
parfor loop = 1:10
a = 1;
b = 2;
MFile_Test %Run the m-file which contains only one line:
% c = a + b;
C(loop)=c;
end
the MFile_Test is a script just containing the line one line c = a + b.
I am beginning to understand why parallel computing has an issue here but not how to solve it. Since this would be possible without any problem if I just had the line c = a + b inside the parfor file I cannot belief there is no simple way to solve this (e.g. in the worst case something like tell matlab to load the text from another file and run it as code here and now).
If there are alternative ways to structure my code without using the script files (and, if possible, without using only functions ;)) I would appreciate such comments as well, of course.
Many thanks,
Daniel
parfor has various constraints that make using scripts inside the loop generally a bad option. The main constraint is that the text of the parfor loop must be analysable to see what new variables might be created - this is referred to as "transparency" in the doc. Try using a function instead.
So, for other people or for possible hints to improve, here is how I did it with a function and loading the input variables.
a = 1;
b = 2;
save('Input.mat');
pseudo_input = NaN;%for the function
D= NaN(10,1);%result vector
parfor loop = 1:10
D(loop) = Parfor_Fun_Test(pseudo_input);
end
And the function looks like this:
function d = Parfor_Fun_Test(InputArgs)
load('Input.mat');
d = a + b ;
end
I would have preferred to also save the output, i.e. 'd', within the function and then load it in the parfor loop, but that causes an error, probably because the same file is accessed for loading and saving at the same time by different parallel workers. So this will have to do it. (This can apparently be circumvented by saving under a different name each time, but that would probably really slow down the code.)
By the way, it seems that using cells or structures is slightly faster, but then I have to write the code inside the function as this, I assume:
d = Input.a + Input.b ;
which is more ugly and more work. So I use the save and load method as above for now.

How to create serially numbered variables in workspace? [duplicate]

This question already has answers here:
Dynamic variables matlab
(2 answers)
Closed 8 years ago.
I was wondering how I can use a for loop to create multiple matrix when given a certain number.
Such as If 3 was given I would need three matricies called: C1, C2 and C3.
k = 3
for i = 1:K
C... = [ ]
end
Not sure how to implement this.
The first thing coming in mind is the eval function mentioned by Dennis Jaheruddin, and yes, it is bad practice. So does the documentation say:
Why Avoid the eval Function?
Although the eval function is very powerful and flexible, it not
always the best solution to a programming problem. Code that calls
eval is often less efficient and more difficult to read and debug than
code that uses other functions or language constructs. For example:
MATLABĀ® compiles code the first time you run it to enhance performance for future runs. However, because code in an eval
statement can change at run time, it is not compiled.
Code within an eval statement can unexpectedly create or assign to a variable already in the current workspace, overwriting existing
data.
Concatenating strings within an eval statement is often difficult to read. Other language constructs can simplify the syntax in your
code.
The "safer" alternative is the function assignin:
The following will do exactly what you want:
letter = 'C';
numbers = 1:3;
arrayfun(#(x) assignin('base',[letter num2str(x)],[]),numbers)
I know cases where you need to create variables likes this, but in most cases it is better and more convenient to use cell arrays or structs.
The trick is to use a cell array:
k=3
C=cell(k,1)
for t=1:k
C{t}= rand(t)
end
If each matrix is of equal size, you would probably just want a three dimensional matrix rather than a cell array.
You now have one cell array,but can access the matrices like this:
C{2} %Access the second matrix.
The use of eval is almost inevitable in this case:
k = 3;
for i = 1:k
eval(sprintf('C%d = [];', i));
end;
Mind you that generating variable names for data storage rather than indexing them (numerically -- see the solution of Dennis Jaheruddin based on cell arrays -- or creating a dynamic struct with named fields that store the data) is almost always a bad idea. Unless you do so to cope up with some weird scripts that you don't want to / cannot modify that need some variables already created in the global workspace.

Too many output arguments

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{:}

When using a multiple-output matlab function, do i need to callback all variables?

When using a multiple-output matlab function, do i need to callback all variables? or can I just take the first two variables? (if so..is it not recommended?)
lets say in function.m
[a, b, c] = function( )
in main.m
[var1, var2] = function;
When calling (almost) any function in matlab you can request fewer outputs than it specifies. So, yes the example you give should work perfectly fine.
There are some clever things you can do with this, such as using nargout within a function to see how many output arguments have been requested and only calculating the values that have been requested as an optimisation trick.
It depends on the definition of the function, and exactly which of the outputs you want to get.
Not all the function allow to do it, you can find all the options for each function in the beginning of the help documentation on the specific function.
If you want only the 2nd, or 3rd outputs, and you want also to save the computation-time of the results that does not interesting, you can use ~ option, like this (for versions 2009b and later):
[~, var1, var2]=function
Many functions allow for options to passed that change how the function behaves. I used/wrote various numerical solving functions a bit and one that nice amount of option, for instance is the LSMR function(s).
Otherwise, if you can manipulate the original either introduce an input(s) to do so before or at the end with an inline subroutine to generate the outputs you want.
Or if you can't it will return as either a cell array or a vector and you can pass an anonymous function to generate the desired outputs that way.
Really, can be done many ways. Very contextual.