Application of cellfun with multiple arguments - matlab

So I have a lot of cell manipulation in code I'm writing right now where it helps greatly to have cell functions of two arguments (e.g., to concatenate arrays in cells of the same size). However, MatLab is reacting confusingly to even simple uses of multiple-input cellfun calls, so I'd like to find out what I'm doing wrong (as I'm just following the MatLab function reference). For instance,
B = {[1 2;3 4] , [5 6;7 8]}
cellfun(mtimes,B,B)
returns
??? Error using ==> mtimes
Not enough input arguments.
In fact, it returns the same message if I input
cellfun(mtimes,B)
or
cellfun(mtimes,B,B,B,B)
Help?

As per the MATLAB CELLFUN documentation the first argument to CELLFUN has to be a function handle, not just the "raw" name of a function. So, something like this...
B = {[1 2;3 4] , [5 6;7 8]}
cellfun(#mtimes,B,B)
(notice the # sign in front of mtimes on the second line).
By putting in a "raw" mtimes, MATLAB is trying to evaluate the function MTIMES on no arguments, and use the result of that as the first argument to CELLFUN. But, as the error messages indicate, MTIMES acting on no arguments is an error.
Instead, use #mtimes to mean the function handle that "points to" the MTIMES function.

Related

Passing vector input into MATLAB function

I am trying to write a function in MATLAB that takes 1x3 vectors as input. My code looks something like this:
function myFunction=([x1, x2, x3], [y1, y2, y3], [z1, z2, z3])
where all inputs are numbers, and then in the body of the function I perform some calculations indexing through the numerical values in the vectors. i want the vectors to be user input, so the user will enter the vectors and their components (x1, x2, etc.) into the function argument. However, I am getting an error saying "Invalid expression. When calling a function or indexing a variable, use parentheses. Otherwise, check for mismatched delimiters." Therefore I believe I either have the syntax or something else wrong. I know MATLAB is supposed to be able to take vector input in functions, so please let me know what I am doing wrong. Thanks!
What you need to do is declare your function like this:
function myFunction(x,y,z)
% your function code here
end
Then within your function you can access the individual elements of the vectors using x(1), y(2), etc.
To call the function, including whatever number you like, you can enter on the Matlab command window (for example),
myFunction([1 2 3],[4 5 6],[7 8 9]) and the code in your function will be called with the x variable set to the vector [1,2,3], the y variable set to [4,5,6] and z to [7,8,9]. The use of commas to delineate values is optional. If your function then accesses y(2) it will get the second value of the y vector which will be 5 - it is important to note that indexing in Matlab is 1-based so the 1st element of x is obtained with x(1).
If you need to return values you can use:
function [a,b,c] = myFunction(x,y,z)
Then just assign the a, b or c in your code before the end statement.
See the offical Matlab documentation for more info.
I would add that much of the advantage of matlab is dealing with data in a vectorised form, so if you can avoid splitting out into separate elements I would do so. For example, if you need to add two vecors, you could do z = [x(1)+y(1), x(2)+y(2), x(3)+y(3)], but much better (more readable, more maintainable, faster) is z=x+y.

How to use fminunc with summation in matlab?

I am trying to solve the following function with fminunc:
Σ((x(i)-1).^2) for i = 1 to 20
My code is below:
fun4 = #(x) sum((x(i)-1).^2, i, 1, 20)
[x,fval,exitflag,output]= fminunc(fun4,[1,1])
And, it gives the following error:
??? Error using ==> sym.sym>notimplemented at 2514
Function 'subsindex' is not implemented for MuPAD symbolic objects.
Could you help me, please?
You should check out the sum documentation for details about how to use it to sum over a vector.
In your case, if you have a vector x of at least 20 elements, you can get the subvector of "x(i) for i in the range 1 to 20" by x(1:20).
You can subtract scalars from a vector just by using the standard subtract sign, but to then square all of the elements individually you should use an "element-wise" operator (having a dot before the operator, like .^). As it happens, you were already doing this anyway.
The 2nd, 3rd and 4th arguments you were passing to sum are causing an error, because sum doesn't expect the arguments you are passing to it. For further details on the inputs it does expect see the linked docs.
All of this means your function can be simplified:
fun4 = #(x) sum((x(1:20)-1).^2);

applying function to each element in matrix --arrayfun

I'm trying to apply a function I wrote to each element in a matrix using arrayfun, but I'm either using the wrong function or getting my syntax wrong.
I've written a function with 3 inputs, 1 output and saved it to an m file in the same directory. I'd like to call that function, with 1 input being an element in the matrix and the 2 remaining inputs being set, and get an output matrix.
My code looks like:
fun = #(x) my_function(x,input2,input3);
B = arrayfun(#(x) fun, A)
I get the following error
Error using arrayfun function_handle output type is not currently implemented.
The correct syntax is
B = arrayfun(fun, A);
because fun is already a handle to your anonymous function.
Note that variables input1, input2 have to be defined before you define your function. The values of those variables get "hard-wired" into the function definition. If you later change those variables, that will have no effect on the function.

How to call a custom function with exponentiation for every element of a matrix in GNU Octave?

Trying to find a way to call the exponentiation function ( ^ ) used in a custom function for every item in a matrix in GNU Octave.
I am quite a beginner, and I suppose that this is very simple, but I can't get it to work.
The code looks like this:
function result = the_function(the_val)
result = (the_val - 5) ^ 2
endfunction
I have tried to call it like this:
>> A = [1,2,3];
>> the_function(A);
>> arrayfun(#the_function, A);
>> A .#the_function 2;
None of these have worked (the last one I believe is simply not correct syntax), throwing the error:
error: for A^b, A must be a square matrix
This, I guess, means it is trying to square the matrix, not the elements inside of it.
How should I do this?
Thanks very much!
It is correct to call the function as the_function(A), but you have to make sure the function can handle a vector input. As you say, (the_val - 5)^2 tries to square the matrix (and it thus gives an error if the_val is not square). To compute an element-wise power you use .^ instead of ^.
So: in the definition of your function, you need to change
result = (the_val-5)^2;
to
result = (the_val-5).^2;
As an additional note, since your code as it stands does work with scalar inputs, you could also use the arrayfun approach. The correct syntax would be (remove the #):
arrayfun(the_function, A)
However, using arrayfun is usually slower than defining your function such that it works directly with vector inputs (or "vectorizing" it). So, whenever possible, vectorize your function. That's what my .^suggestion above does.

matlab: subs on symbolic constant returns scalar instead of vector for a vector input

usually, symbolic functions return vectors for vector inputs:
syms('x');
f=x*2;
subs(f,[1 2 3])
outputs: [2 4 6]
but doing
f=sym('0');
subs(f,[1 2 3]);
outputs: 0
and not: [0 0 0]
so basically, my questions is how do I make f behave as a "normal" symbolic function.
I can do something ugly like f=x-x to create a function that always returns zero, but is there a prettier way?
Actually, there is no way.
sym('0') creates a symbolic constant (0, in this case). subs() replaces all variables with each value from the given vector. However, you have no variables, so subs() just returns the given symbolic constant.
It gets better. sym() internally does some simplification, so sym('0*x') or sym('x-x') both become sym('0') and you get the exact same behavior. Similarly, sym('x/x') turns into sym('1') and you just get the scalar 1 back from subs() even if you pass it a vector.
The only way you're going to get around this is by writing a helper function that detects if the size() of the output from subs() is less than the vector, and turns it into the correct size of a vector if needed.
I don't have the Symbolic Toolbox so this is a blind guess. Your function declarations don't look identical enough:
syms('x');
f=x*2;
against
f=sym('0');
Perhaps what you have done in the first case is define a function which returns the double of its inputs, in the second case defined a function which returns 0 whatever its inputs. Maybe
syms('x');
f=x*0;
is what you need ?