Can you call a matrix from a string - matlab

I have to make a call to read in a matrix with a name that is created from a strcat, in Matlab. For example
person = 2;
Index_XNY = strcat('Index_X',num2str(person),'Y');
Big_Index = find(Index_XNY(1,:)==1);
This works if I replace Index_XNY with Index_X2Y for this example.
I have tried a number of different things to obtain Big_Index, but so far I have not been successful. Can this be done, as there is a large collection of data elements that need to be called.

You can use the eval function to evaluate a Matlab expression in a string:
expr = strcat('find(Index_X',num2str(person),'Y(1,:)==1)');
Big_Index = eval(expr);
Of course, a lot of alternative ways to do this with eval function exist, depending on how much you would like to put into the string and how much would be left out.

Related

How to apply the result and index of the result of max() to an array on a single line

I was given a problem in MatLab where I needed to write a single line of code that starts with
variableName =
and find the max value of a 2d array and it's index. I don't use matlab at all, and this seems infuriatingly simple in any language I know. I know to get the value & index of the result of max, you do something like
[M,I] = max(stuffToCheck)
I just dont understand how to assign the array that creates to a variable name. I've spent some time googling but this feels like a very weird constraint so I haven't found anything yet. How do I do this on one line?
use the variable you want to assign the result:
[variableName(:,1),variableName(:,2)] = max(stuffToCheck)
its the only way because in matlab if you write :
variable = function();
matlab return only the first output, to get other ouput you have to write:
[output1,output2,...] = function();

Passing multiple inputs into a MATLAB function via loop?

I have multiple variables var_1, var_2, var_3....var_9 (they are named like that) that I want to pass in a function. All of the variables are saved in the workspace. The function takes 2 variables, and spits out an output. I want to compare var_1 with all the variables, including itself, so I prefer to automate it in a loop.
So I want to execute
function(var_1,var_1)--> display answer, function(var_1,var_2)--> display answer...function(var_1,var_9)-->display answer all at once in a loop. I've tried the following, with no luck:
for i=1:7
functionname(var_1,var_'num2str(i)')
end
Where did I go wrong?
You cannot make a dynamic variable name directly. But you can use the eval-function to evaluate an expression as a string. The string can be generated with sprintf and replaces %d with your value.
for i=1:7
eval(sprintf('functionname(var_1,var_%d)', i));
end
But: Whenever you can, you should avoid using the eval function. A much better solution is to use a cell array for this purpose. In the documentation of Matlab there is a whole article about the why and possible alternatives. To make it short, here is the code that uses a cell array:
arr = {val_1, val_2, val_3, val_4, val_5, val_6, val_7, val_8, val_9};
for i = 1:length(arr)
functionname(arr{1},arr{i})
end

Avoid repeat calling simulation/function with same arguments

This is a general algorithm question, but my primary environment is Matlab.
I have a function
out=f(arg1,arg2,,.....)
which takes a long time to execute and is expensive to compute (i.e. cluster time). A given argument argn can be a string, integer, vector, and even a function handle
For this reason, I want to avoid calling f(args) for the same argument values. Inside my program, this can occur in ways that are not necessarily controllable by the programmer.
So, I want to call f() once for each possible value of args, and save the results to disk. Then, whenever it is called the next time, check if there is currently a result for those argument values. If so, I would load it from disk.
My current idea is to create a cell variable, with one row for each function call. In the first column is out. In column 2:N are the values of argn, and check the equivalence of each individually.
Since the variable types of the arguments vary, how would I go about doing this?
Is there a better algorithm?
More generally, how do people deal with saving simulation results to disk and storing metadata? (other than cramming everything into a filename!)
You can implement a function that looks something like this:
function result = myfun(input)
persistent cache
if isempty(cache)
cachedInputs = [];
cachedOutputs = [];
cache = {cachedInputs, cachedOutputs};
end
[isCached, idx] = ismember(input, cache{1});
if isCached
result = cache{2}(idx);
else
result = doHardThingOnCluster(input);
cache{1}(end+1) = input;
cache{2}(end+1) = result;
end
This simple example assumes that your inputs and outputs are both scalar numbers that can be stored in an array. If you have to deal with strings, or anything more complicated, you could use a cell array for caching rather than an array. Or in fact, maybe a containers.Map might be even better. Alternatively, if you have to cache really massive results, you might be better off saving it to a file and caching the file name, then loading the file in if you find it's been cached.
Hope that helps!

Matlab: Slicing matrix inside a containers.Map always requires intermediate referencing?

Prologue:
I am in the process of designing/prototyping a piece of code in Matlab.
As at the moment it is not clear to me which matrices should be returned by my functions, I chose, as a general approach, to bind my returned values in containers.Map (as I would do e.g. in python).
Hence, the general setting is
function output = myfoo(args)
output = containers.Map;
...some stuff
output('outname1') = ...
output('outname2') = ...
end
this approach should have the advantage of allowing me to add more returned data without messing up the other code too much or break backwards compatibility.
Issue:
How to deal in a elegant way with matrix slicing?
Say that I need to do something like
output('outname1')(2:end) = ...
(which gives an error as two indexes are not allowed and a boring workaround like
temp = output('outname1')
temp(2:end) = ...
output('outname1') = temp
is required).
Question:
Is there a proficient way to deal with this, avoiding all this referencing/copying job?
No, there is no way to do it without a temporary variable. The only case in which a double index is valid in Matlab is for a cell array. In that case, you can use
output{...}(...)
However, in any other case, a double index results in an error.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.