Return a field from a function that returns a struct - matlab

I'm using the function dbstack to get the name of the currently executing function. dbstack returns a struct, with three fields: file, name and line. I'm only interested in name. Is there any way of returning just the name field when I call the dbstack function, or do I need to use two lines (the following)?
thisFunction = dbstack;
thisFunctionName = thisFunction.name;

Your solution is the easiest (and propebly the best) way of doing what you want.
Alternatively, you can use getfield
>> thisFunctionName = getfield( dbstack, 'name' )

Related

Retrieve name of output arguments within a function

It is possible to use the function inputname to retrieve the workspace variable name passed in the call to the currently executing function. However, is there any equivalent function to obtain the name of the output arguments specified in the call to the currently executing function?
Imagine I have the following function:
function [a,b,c] = test(x)
disp([ouputname(1),ouputname(2),ouputname(3)])
end
When running this function:
[my,name,is] = test(x)
The expected result should be:
mynameis
Simply: no there isn't.
Complicated: Matlab code is "compiled" on run-time, and there is no way, that it knows [my,name,is] before it returns the result of test(x).
Workaround: if you want to ensure, that the strings used within the function are equal to the variables returned to the workspace, you can do the following using assignin:
function test(x, varnames)
a = 1;
outputname{1} = varnames{1};
assigin('base', outputname{1}, a)
...
c = 3;
outputname{3} = varnames{3};
assigin('base', outputname{3}, c)
disp([outputname{:}])
end
and call your function like:
text(x,{'my','name','is'})
and you will have exactly this variables in your workspace afterwards and your function output:
"mynameis"

Matlab: specifying argument's name when passing it to function (Ruby `hash`)

Is it possible to define and use a function like this?
generate_mode_matrix_and_mode_frequency_and_Hw(generate_Hw: true);
function generate_mode_matrix_and_mode_frequency_and_Hw(generate_Hw)
if generate_Hw ## NOTICE: this argument is optional
.....
end
end
What I want is to specify the name of the argument when passing it. In ruby it's called hash.
The point of doing this is that, when using it, the coder know what the true mean without comment. This is
Compare this 2:
generate_mode_matrix_and_mode_frequency_and_Hw(generate_Hw: true)
generate_mode_matrix_and_mode_frequency_and_Hw(true)
Clearly, the first one is more clear.
Notice: generate_Hw is an optional argument. So without specifying it, the function would also work.
You can use something similar to Property\Value pairs:
function Foo(varargin)
for n=1:2:nargin
switch varargin{n}
case 'var1'
var1 = varargin{n+1};
case 'var2'
var2 = varargin{n+1};
end
end
In this example if you use Foo('var1',value) then var1 would get the desired value. If you don't specify the pair 'var1',value in the input, then var1 will not exist in Foo.

Call a function with several properties of an object

For (MEX) function calls it would be really nice to pass several properties of one object at once. Instead of foo(myObj.propA, myObj.propB) I want something like foo(myObj.[propA,propB].
Is this even possible?
With structs it is possible to use the getfield() function to get the data from more than one field, e.g.:
getfield(myStruct, {index}, {'fieldA', 'fieldB'})
But unfortunately, the following attempt to get more than one property from an object results in an error (Index exceeds matrix dimensions):
getfield(myObj, {index}, {'propA', 'propB'})
Maybe the only possibility is to write a function which returns several output arguments:
[varargout] = getProps(object,propnames)
for p=1:numel(propnames)
varargout{p} = object.(propnames{p});
end
But if I call another function with that function as input, e.g. sum(getProps(myObj,propnames)) only the first output argument of getProps is passed and I fall into despair. Is there any other way?
For an object, you'd use get, not getfield (or dynamic access in a loop like you showed).
>> h = figure;
>> get(h,{'Position','Renderer'})
ans =
[1x4 double] 'opengl'
This doesn't work for all objects, but for MATLAB graphics objects it does work. To deal with any class, you can use your function, but with a custom cell output instead of varargout:
function C = getProps(object,propnames)
for p = 1:numel(propnames),
C{p} = object.(propnames{p});
end
Then inside whatever function you write, you can get a comma-separated list of all properties with C{:}, which will be suitable for a function that expects each property name input as a separate argument (e.g. C = getProps(myObj,propnames); x = myFun(h,C{:}).

Assigning to variables using dynamic naming

I am creating a function with two inputs, and would like to know how I can name the output accorinding to the name of the inputs.
E.g.
function [padded_*input_name*] = padstruct(S, F)
later in code...
else
padded_*input_name* = padarray(toPad, (longest - size(toPad,1)), NaN('double'), 'post');
So if I enter a struct (labelled as S in the input arguments) called my_struct, I would like to get an output called padded_my_struct. But this should be free to change according to the name of the input struct. I want to do this because I have a lot of structs to run through this function and I want to explicitly know from the output name, which is which.
I am a beginner with Matlab and so would appreciate any exaplanation or references to literature.
I don't quite give you what you want. Instead, I have a function that, given the inputs Account and F, produces in the base workspace a variable "padded_Account", and returns the name of the variable it creates.
function padded_Sname_str=padstruct(Sin,F)
%get the name of the structure used in the function call here
Sname=inputname(1);
%do stuff to Sin here
Sin.pad=F; %this is just my test operation
%create the name of the new variable you want
padded_Sname_str=['padded_',Sname];
%this creates it in the base workspace, since passing back as an
%output argument doesn't preserve the name
assignin('base',padded_Sname_str,Sin)
return
Hope this is helpful. Cheers!
Try this -
function [padded_*input_name*] = padstruct(S, F)
%// .. later on in code
else
value = padarray(toPad, (longest - size(toPad,1)), NaN('double'), 'post');
evalc(['padded_' inputname(1) '= value']);
Let us know if it works for you!

MATLAB assign variable name

I have a variable called 'int' with alot of data in it. I would like to find a way to programically rename this variable with a user input. So I can query the user indentifcation information about the data, say the response is 'AA1', I want either rename the variable 'int' to 'AA1' or make 'AA1' a variable that is identical to int.
A problem using the input command arises because it allows the user to assign a value to an already created varialbe, instead of actually creating a variable name. Would using the eval function, or a variation of it, help me achieve this? Or is there an easier way?
Thanks!
Just for the record, int is a rather poor variable name choice.
That aside, you can do what you want as follows
say foo is the variable that holds a string that the user input. You can do the following:
% eliminate leading/trailing whitespace
foo = strtrim(foo);
a = regexp('[a-zA-Z][a-zA-Z0-9_]*',foo));
if numel(a) == 0
fprintf('Sorry, %s is not a valid variable name in matlab\n', foo);
elseif a ~= 1
fprintf('Sorry, %s is not a valid variable name in matlab\n', foo);
elseif 2 == exist(foo,'var')
fprintf('Sorry, %s already in use as a variable name.');
else
eval([foo,' = int']);
end
Assuming int (and now foo) is a structure with field named bar, you can read bar as follows:
barVal = eval([foo,'.bar']);
This is all somewhat clunky.
An alternative approach, that is far less clunky is to use an associative array, and let the user store various values of int in the array. The Matlab approach for associative arrays is Maps. That would be my preferred approach to this problem. Here is an example using the same variables as above.
nameValueMap = containers.Map;
nameValueMap(foo) = int;
The above creates the association between the name stored in foo with the data in the variable int.
To get at the data, you just do the following:
intValue = nameValueMap(foo);