Perform a function on each value of a vector in matlab? - matlab

I have a vector, a, shape (10000,1) filled with values. I also have vector b, same shape, filled with zeros. I want to take my function, apply it to each value in vector a, return those values into vector b. Below is what I tried, as well as a few variations of this. How can I perform this function on each value of the vector and replace each zero in vector b with what that function returns?
for i=1:length(a)
b(i) = function(a)
end

You can use arrayfun to do this
b = arrayfun(#someFunction, a); % Calls b(i) = someFunction(a(i)) for all elements of a
(Although it's common in MATLAB to try and make someFunction be "vectorised", so that you can instead say simple b = someFunction(a))

Related

bsxfun doesn't work as I expect on a constant function

In Matlab R2016a, I have a large set of small X-vectors and Y-vectors which are paired (e.g. 10,000 1x3 X-vectors paired with 10,000 1x3 Y vectors). For each {X,Y} pair, I want to calculate a 2-scalar-argument function for every pairwise combination of the elements in X and Y, (so in my example I would get 10,000 3x3 matrices).
I thought I could use bsxfun to perform these calculations, but it doesn't work when I try to do some simple tests. bsxfun(#(x,y) x*y,[1 2],[1 2]') returns:
ans =
1 2
2 4
Which is what I would expect. However, bsxfun(#(x,y) 1,[1 2],[1 2]') returns:
Error using bsxfun
Specified function handle produces invalid output dimensions. The function handle
must be a binary elementwise function.
Which makes no sense. The function handle is a binary elementwise function that always returns the scalar 1, so bsxfun should give the same result as ones(2,2), unless I'm not understanding how bsxfun works.
The inputs to the function handle that are passed to bsxfun are not scalars. In versions prior to R2016b, the inputs are either scalar or they are the same size.
FUNC can also be a handle to any binary element-wise function not listed
above. A binary element-wise function in the form of C = FUNC(A,B)
accepts arrays A and B of arbitrary but equal size and returns output
of the same size. Each element in the output array C is the result
of an operation on the corresponding elements of A and B only. FUNC must
also support scalar expansion, such that if A or B is a scalar, C is the
result of applying the scalar to every element in the other input array.
In releases since R2016b, they do not have to be equal sizes, but should be compatible sizes
In the example you have shown, the first input to the function handle is a scalar and the second is a vector (y) and the function is evaluated for every element of x and the output is expected to be the size of y
In the case you've posted, the call to bsxfun is essentially the equivalent of:
x = [1 2];
y = [1 2].';
yourfunc = #(x,y)x * y;
for k = 1:numel(x)
output(:,k) = yourfunc(x(k), y)
end
If you want to return a 1 for every entry, you need to replace your function with something that yields the appropriately sized output.
bsxfun(#(x,y)ones(max(size(x), size(y))), [1 2], [1 2]')
How you formulate the function handle really depends upon your specific problem

Get an array of results of a function using as input an array of values (in Matlab)

I want to get the array of results of a function using as input an array of values. The function receives two variables (x1, x2) and a constant x3, so I'm trying to input all combination of it in a range using mesh.
The result is incorrect, I'm missing something.
Sample:
fun = #(x1,x2,x3) (x2-x1^2)^2+(1-x1)^2 + x3;
x3 = 7;
fun2 = #(x) fun(x(1,1),x(1,2),x3);
x0 = [2 3];
min = fminsearch(fun2, x0);
disp(min);
x = min(1)-10:1:min(1)+10;
y = min(2)-10:1:min(2)+10;
[X,Y] = meshgrid(x,y);
% I'm getting strange values here, like z < 0, how it is possible if everything is squared in the function.
Z = fun(X,Y,x3);
It's important to note that there is a difference between matrix and element-wise operations in MATLAB.
Matrix operations are defined via plain operators, such as *, or ^. So for example, A*B performs a matrix multiplication between A and B.
Element-wise operators make use of the dot . before the operator, i.e., .*, .^, and so on. Thus, A.*B performs an element-wise multiplication of A and B. The end result of this operation is an array of the same size as A and B (whose sizes must be equal), where the jj'th element of the array is equal to A(jj)*B(jj).
Now, consider your definition of fun:
fun = #(x1,x2,x3) (x2-x1^2)^2+(1-x1)^2 + x3;
What happens when MATLAB evaluates this expression is that it applies the matrix operations, such as ^ to the input arrays. However, to obtain your desired result of applying the operation to every individual element in your input arrays x1, x2, you should be using element-wise operations.
A new definition
fun = #(x1,x2,x3) (x2-x1.^2).^2+(1-x1).^2 + x3;
should provide the desired result.

Apply a function to each sub-cell of a cell in Matlab?

I have a cell C in Matlab of dimension mx1, e.g. m=3
C={{1 2 3} {4 5 6} {7 8 9 10}}
Then I have a function g written in a separate m-file
function D=g(C{i},a,b)
...
end
that takes any sub-cell C{i} of C and using some other parameters a and b gives a vector D of dimension fx1.
I want to apply the function g to each sub-cell of C and assemble the obtained fx1 vectors in a matrix fxm without using loops. I have seen the command cellfun but I don't know how to make it working with a function written by myself. Any suggestion?
Simple. First make a handle to the function where the only input is the cell array:
h = #(x) D(x, a, b);
Here, x would be a cell from the cell array. Also, I'm going to assume that a and b are already defined in your workspace. After, just do this:
out = cellfun(h, C, 'uni', 0);
The first argument is a handle to the function, which we've already defined. The next parameter is the cell array you want to operate on and apply the function h to every cell in your array. You need to specify the uni=0 flag because the output is non-uniform. Because your function outputs a vector per cell, this is mandatory. If your function outputted a single value, then this declaration of uni=0 is not required.
Alternatively, you can do this in a loop... which is what cellfun ultimately performs:
out = cell(numel(C), 1);
for idx = 1 : numel(C)
out{idx} = D(C{idx}, a, b);
end
To me, the second option is more suitable for those who aren't used to using cellfun.

How to take elements of a Matrix and use each one as Input-Variable for the same function?

I have given a matrix with 485x1 elements. MatLab shall take the first 12 of them and make them a new matrix.
Then I have a variable named C and a function f(C).
MatLab shall take the first element of the new matrix and make it C. Then it shall perform f(C) and save the result as result1.
Then it should take the second element of the new matrix and make it C. Then it shall perform f(C) again and save the result as result2 and so on.
So in the end I need 12 result variables.
How can I program this?
This is question asks for very basic stuff. Like adressing the first 12 elements of a matrix. You might want to consider reading a few FAQs.
However a basic solution can look like this:
M = [1:485]'; %// a 485x1 matrix (vector)
newMatrix = M(1:12); %// newMatrix contains the first 12 elements of M (also vector)
result = cell(1,12); %// result as a cell
f = #(x) x+1; % a function f
for i = 1:12
C = newMatrix(i); % get each value from newMatrix, call it C
result{i} = f(C); % apply f() on c and store the result
end
It is not a good idea to generate variables result1, result2, ..., result12, you can read more about it here. Better use a cell for storing the variables, you can then adress the i-th result as result{i}.

Apply function to every pair of columns in two matrices in MATLAB

In MATLAB, I'd like to apply a function to every pair of column vectors in matrices A and B. I know there must be an efficient (non for) way of doing this, but I can't figure it out. The function will output a scalar.
Try
na = size(A,1);
nb = size(B,1);
newvector = bsxfun(#(j,k)(func(A(j,:),B(k,:))),1:na,(1:nb)');
bsxfun performs singleton expansion on 1:na and (1:nb)'. The end result, in this case, is that func will be applied to every pair of column vectors drawn from A and B.
Note that bsxfun can be tricky: it can require that the applied function support singleton expansion itself. In this case it will work to do the job you want.
Do you mean pairwise? So in a for-loop the function will work as scalar_val = func(A(i),B(i))?
If A and B have the same size you can apply ARRAYFUN function:
newvector = arrayfun(#(x) func(A(x),B(x)), 1:numel(A));
UPDATE:
According your comment you need to run all combinations of A and B as scalar_val = func(A(i), B(j)). This is a little more complicated and for large vectors can fill the memory quickly.
If your function is one of standard you can try using BSXFUN:
out = bsxfun(#plus, A, B');
Another way is to use MESHGRID and ARRAYFUN:
[Am, Bm] = meshgrid(A,B);
out = arrayfun(#(x) func(Am(x),Bm(x)), 1:numel(Am));
out = reshape(out, numel(A), numel(B));
I believe it should work, but I don't have time to test it now.