MatLab - Applying a function to each row in a matrix - function

I have a matrix with rows of 4 integers, with an unspecified number of columns (depends on the text file).
I'm wanting to apply a function to each row of the matrix, independently. The function has 4 inputs, and 2 outputs.
I'm trying to use the arrayfun function to do this, but whenever I call the function, I get an error saying: "Not enough input arguments."
Here is the function call:
[gain,phase]=arrayfun(#(x) GainPhaseComp(B(x,1:4)), 1:size(B));
where b is an n by 4 matrix.
Here is the function:
function [gain,phase] = GainPhaseComp(InAmp,InPhase,OutAmp,OutPhase)
gain = 20*log10(OutAmp\InAmp);
phase = (OutPhase - InPhase);
end
Any help would be greatly appreciated!

Your function GainPhaseComp has 4 input arguments, but you pass only 1 row vector. Vector with 4 elements is still one variable, not 4. You need either to change the function definition or split the vector elements.
1st option:
function [gain,phase] = GainPhaseComp(inputvector)
% function body
2nd option:
[gain,phase]=arrayfun(#(x) GainPhaseComp(B(x,1),B(x,2),B(x,3),B(x,4)), 1:size(B,1));

Related

function handle to nested function not working for some values of parameter

This function is supposed to return a function handle to the nested function inside, but if the variable x is set to a negative value in the outer function, it doesn't work.
The inner nested function is just a constant function returning the value of the variable x that is set in the outer function.
function t=test(x)
x=-1;
function y=f()
y=x;
endfunction
t=#f;
endfunction
If I try to evaluate the returned function, e.g. test()(3), I get an error about x being undefined. The same happens if x is defined as a vector with at least one negative entry or if x is argument of the function and a negative default value is used for evaluation. But if I instead define it as some nonnegative value
function t=test(x)
x=1;
function y=f()
y=x;
endfunction
t=#f;
endfunction,
then the returned function works just fine. Also if I remove the internal definition of x and give the value for x as an argument to the outer function (negative or not), like
function t=test(x)
function y=f()
y=x;
endfunction
t=#f;
endfunction
and then evaluate e.g. test(-1)(3), the error doesn't occur either. Is this a bug or am misunderstanding how function handles or nested functions work?
The Octave documentation recommends using subfunctions instead of nested functions, but they cannot access the local variables of their parent function and I need the returned function to depend on the input of the function returning it. Any ideas how to go about this?
This is a bug that was tracked here:
https://savannah.gnu.org/bugs/?func=detailitem&item_id=60137
Looks like it was fixed and will be gone in the next release.
Also, to explain the different behavior of negative and positive numbers: I experimented a bit, and no variable that is assigned a computed value is being captured:
function t=tst()
x = [5,3;0,0]; # captured
y = [5,3;0,0+1]; # not captured
z = x + 1; # not captured
function y=f()
endfunction
t=#f;
endfunction
>> functions(tst)
ans =
scalar structure containing the fields:
function = f
type = nested
file =
workspace =
{
[1,1] =
scalar structure containing the fields:
t = #f
x =
5 3
0 0
}
The different behavior of negative and positive numbers are probably caused by the minus sign - before the numbers being treated as a unary operator (uminus).
As of octave version 5.2.0 the nested function handles were not supported at all. I'm going to guess that is the novelty of the version 6.
In octave functions are not variables, the engine compiles\translates them at the moment of reading the file. My guess would be that behavior you are observing is influenced by your current workspace at the time of function loading.
The common way for doing what you are trying to do was to generate the anonymous (lambda) functions:
function t = test1(x=-1)
t = #()x;
end
function t = test2(x=-1)
function s = calc(y,z)
s = y + 2*z;
end
t = #(a=1)calc(a,x);
end
Note that default parameters for the generated function should be stated in lambda definition. Otherwise if you'd call it like test2()() it would not know what to put into a when calling calc(a,x).
If you are trying to create a closure (a function with associated state), octave has limited options for that. In such a case you could have a look at octave's object oriented functionality. Classdef might be useful for quick solutions.

map function with multiple arguments to each row of Array in Julia

In an attempt to simplify my code in Julia, I have the following command:
L=rand(50,50)
function f(l)
n=mapslices(function g(x) partialsortperm(x,1:l,rev=true) end,L,dims=2)
return n
end
map(f,[34; 24 ;17])
This command is supposed to apply the function g to each row of the Array L, where at each time, the function is applied with 3 different values of the argument l. I attempted to create a unique function, to eliminate the function inside a function:
function f(A::Array,l::Int64)
partialsortperm(A,1:l,rev=true)
end
and tried to use map(f,eachrow(L),[34; 24; 17]) but not getting what I want, because the function f has now 2 arguments and I don't know how to use 2 arguments with map or mapslices.

Scilab not returning variables in variable window

I have created a function that returns the magnitude of a vector.the output is 360x3 dimension matrix. the input is 360x2.
Everything works fine outside the function. how do i get it to work ?
clc
P_dot_ij_om_13= rand(360,2); // 360x2 values of omega in vectors i and j
//P_dot_ij_om_13(:,3)=0;
function [A]=mag_x(A)
//b="P_dot_ijOmag_"+ string(k);
//execstr(b+'=[]'); // declare indexed matrix P_dot_ijOmag_k
//disp(b)
for i=1:1:360
//funcprot(0);
A(i,3)=(A(i,2)^2+A(i,1)^2)^0.5; //calculates magnitude of i and j and adds 3rd column
disp(A(i,3),"vector magnitude")
end
funcprot(1);
return [A] // should return P_dot_ijOmag_k in the variable browser [360x3 dim]
endfunction
mag_x(P_dot_ij_om_13);
//i=1;
//P_dot_ij_om_13(i,3)= (P_dot_ij_om_13(i,2)^2+P_dot_ij_om_13(i,1)^2)^0.5;// example
You never assigned mag_x(P_dot_ij_om_13) to any variable, so the output of this function disappears into nowhere. The variable A is local to this function, it does not exist outside of it.
To have the result of calculation available, assign it to some variable:
res = mag_x(P_dot_ij_om_13)
or A = mag_x(P_dot_ij_om_13) if you want to use the same name outside of the function as was used inside of it.
By the way, the Scilab documentation discourages the use of return, as it leads to confusion. The Scilab / Matlab function syntax is different from the languages in which return specifies the output of a function:
function y = sq(x)
y = x^2
endfunction
disp(sq(3)) // displays 9
No need for return here.

Adding an arbitrary number of functions into a function handle MATLAB

I'm trying to generate .bmp graphics in MATLAB and I'm having trouble summing functions together. I'm designing my function such that given an arbitrary set of inputs, my function will add an arbitrary number of functions together and output a function handle. The inputs are coefficients to my general function so I can specify any number of functions (that only differ due to their coefficients) and then add them together into a function handle. What I've tried to do is create each function as a string and then concatenate them and then write them as a function handle. The main problem is that because x and y aren't defined (because I'm trying to create a function handle) MATLAB can't add them regularly. My current attempt:
function HGHG = anyHGadd(multi) %my array of inputs
m=length(multi);
for k=3:3:m;
m1=multi(k-2); %these three are the coefficients that I'd like to specify
n1=multi(k-1);
w1=multi(k);
HGarrm1=hermite(m1); %these generate arrays
HGarrn1=hermite(n1);
arrm1=[length(HGarrm1)-1:-1:0];%these generate arrays with the same length
arrn1=[length(HGarrn1)-1:-1:0];%the function below is the general form of my equation
t{k/3}=num2str(((sum(((sqrt(2)*x/w1).^arrm1).*HGarrm1))*(sum(((sqrt(2)*y/w1).^arrn1).*HGarrn1))*exp(-(x^2+y^2)/(w1^2))));
end
a=cell2mat(t(1:length(t)));
str2func(x,y)(a);
Any help would be much appreciated. I haven't seen much on here about this, and I'm not even sure this is entirely possible. If my question isn't clear, please say so and I'll try again.
Edit: The fourth from last line shouldn't produce a number because x and y aren't defined. They can't be because I need them to be preserved as a part of my function handle. As for a stripped down version of my code, hopefully this gets the point across:
function HGHG = anyHGadd(multi) %my array of inputs
m=length(multi);
for k=3:3:m;
m1=multi(k-2); %these three are the coefficients that I'd like to specify
n1=multi(k-1);
w1=multi(k);
t{k/3}=num2str(genericfunction(x,y,n1,m1,n1,w1); %where x and y are unspecified
end
a=cell2mat(t(1:length(t)));
str2func(x,y)(a);
Edit I am expecting this to output a single function handle that is the sum of an arbitrary number of my functions. However, I'm not sure if using strings would be the best method or not.
Your question is not very clear to me, but I think you are trying to create a function that generate output functions parametrized by some input.
One way is to use closures (nested function that access its parent function workspace). Let me illustrate with an example:
function fh = combineFunctions(funcHandles)
%# return a function handle
fh = #myGeneralFunction;
%# nested function. Implements the formula:
%# f(x) = cos( f1(x) + f2(x) + ... + fN(x) )
%# where f1,..,fN are the passed function handles
function y = myGeneralFunction(x)
%# evaluate all functions on the input x
y = cellfun(#(fcn) fcn(x), funcHandles);
%# apply cos(.) to the sum of all the previous results
%# (you can make this any formula you want)
y = cos( sum(y) );
end
end
Now say we wanted to create the function #(x) cos(sin(x)+sin(2x)+sin(5x)), we would call the above generator function, and give it three function handles as follows:
f = combineFunctions({#(x) sin(x), #(x) sin(2*x), #(x) sin(5*x)});
Now we can evaluate this created function given any input:
>> f(2*pi/5) %# evaluate f(x) at x=2*pi/5
ans =
0.031949
Note: The function returned will work on scalars and return a scalar value. If you want it vectorized (so that you can apply it on whole vector at once f(1:100)), you'll have to set UniformOutput to false in cellfun, then combine the vectors into a matrix, sum them along the correct dimension, and apply your formula to get a vector result.
If your goal is to create a function handle that sums the output of an arbitrary number functions, you can do the following:
n = 3; %# number of function handles
parameters = [1 2 4];
store = cell(2,3);
for i=1:n
store{1,i} = sprintf('sin(t/%i)',parameters(i));
store{2,i} = '+'; %# operator
end
%# combine such that we get
%# sin(t)+sin(t/2)+sin(t/4)
funStr = ['#(t)',store{1:end-1}]; %# ignore last operator
functionHandle = str2func(funStr)
functionHandle =
#(t)sin(t/1)+sin(t/2)+sin(t/4)

How to write arbitrary datatypes into Matlab cell array

This is a general question, not related to a particular operation. I would like to be able to write the results of an arbitrary function into elements of a cell array without regard for the data type the function returns. Consider this pseudocode:
zout = cell(n,m);
myfunc = str2func('inputname'); %assume myfunc puts out m values to match zout dimensions
zout(1,:) = myfunc(x,y);
That will work for "inputname" == "strcat" , for example, given that x and y are strings or cells of strings with appropriate dimension. But if "inputname" == "strcmp" then the output is a logical array, and Matlab throws an error. I'd need to do
zout(1,:) = num2cell(strcmp(x,y));
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
(I'm usually an R user, where I could just use a list variable without any pain)
Edit: To simplify the overall scope, add the following "requirement" :
Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout . But when this output is a vector of N values or a vector of cells (i.e. Nx1 cell array), these N values get mapped to zout(1,1:N) .
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y) ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
The answer provided by #NotBoStyf is almost there, but not quite. Cell arrays are the right way to go. However, the answer very much depends on the number of outputs from the function.
Functions with only one output
The function strcmp has only one output, which is an array. The reason that
zout{1,:} = strcmp(x,y)
gives you an error message, when zout is dimensioned N x 2, is that the left-hand side (zout{1,:}) expects two outputs from the right-hand side. You can fix this with:
[zout{1,:}] = num2cell(strcmp(x,y)); % notice the square brackets on the LHS
However, there's really no reason to do this. You can simply define zout as an N x 1 cell array and capture the results:
zout = cell(1,1);
x = 'a';
y = { 'a', 'b' };
zout{1} = strcmp(x,y);
% Referring to the results:
x_is_y_1 = zout{1}(1);
x_is_y_2 = zout{1}(2);
There's one more case to consider...
Functions with multiple outputs
If your function produces multiple outputs (as opposed to a single output that is an array), then this will only capture the first output. Functions that produce multiple outputs are defined like this:
function [outA,outB] = do_something( a, b )
outA = a + 1;
outB = b + 2;
end
Here, you need to explicitly capture both output arguments. Otherwise, you just get a. For example:
outA = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4]
[outA,outB] = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4], outB is [6,7,8]
Z1 = cell(1,1);
Z1{1,1} = do_something( [1,2,3], [4,5,6] ); % Z1{1,1} is [2,3,4]
Z2 = cell(1,2);
Z2{1,1:2} = do_something( [1,2,3], [4,5,6] ); % Same error as above.
% NB: You really never want to have a cell expansion that is not surrounded
% by square brackets.
% Do this instead:
[Z2{1,1:2}] = do_something( [1,2,3], [4,5,6] ); % Z2{1,1} is [2,3,4], Z2{1,2} is [6,7,8]
This can also be done programmatically, with some limits. Let's say we're given function
func that takes one input and returns a constant (but unknown) number of outputs. We
have cell array inp that contains the inputs we want to process, and we want to collect the results in cell around outp:
N = numel(inp);
M = nargout(#func); % number of outputs produced by func
outp = cell(N,M);
for i=1:N
[ outp{i,:} ] = func( inp{i} );
end
This approach has a few caveats:
It captures all of the outputs. This is not always what you want.
Capturing all of the outputs can often change the behavior of the function. For example, the find function returns linear indices if only one output is used, row/column indices if two outputs are used, and row/column/value if three outputs are used.
It won't work for functions that have a variable number of outputs. These functions are defined as function [a,b,...,varargout] = func( ... ). nargout will return a negative number if the function has varargout declared in its output list, because there's no way for Matlab to know how many outputs will be produced.
Unpacking array and cell outputs into a cell
All true so far, but: what I am hoping for is a generic solution. I can't use num2cell if the function produces cell outputs. So what worked for strcmp will fail for strcat and vice versa. Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout – Carl Witthoft
To provide a uniform output syntax for all functions that return either a cell or an array, use an adapter function. Here is an example that handles numeric arrays and cells:
function [cellOut] = cellify(input)
if iscell(input)
cellOut = input;
elseif isnumeric(input)
cellOut = num2cell(input);
else
error('cellify currently does not support structs or objects');
end
end
To unpack the output into a 2-D cell array, the size of each output must be constant. Assuming M outputs:
N = numel(inp);
% M is known and constant
outp = cell(N,M);
for i=1:N
outp(i,:) = cellify( func( inp{i} ) ); % NB: parentheses instead of curlies on LHS
end
The output can then be addressed as outp{i,j}. An alternate approach allows the size of the output to vary:
N = numel(inp);
% M is not necessary here
outp = cell(N,1);
for i=1:N
outp{i} = cellify( func( inp{i} ) ); % NB: back to curlies on LHS
end
The output can then be addressed as outp{i}{j}, and the size of the output can vary.
A few things to keep in mind:
Matlab cells are basically inefficient pointers. The JIT compiler does not always optimize them as well as numeric arrays.
Splitting numeric arrays into cells can cost quite a bit of memory. Each split value is actually a numeric array, which has size and type information associated with it. In numeric array form, this occurs once for each array. When the array is split, this incurs once for each element.
Use curly braces instead when asigning a value.
Using
zout{1,:} = strcmp(x,y);
instead should work.