SML NJ - match nonexhausitive - not sure how to handle - smlnj

I want to define a function that takes 3 parameters and returns a list. The parameters will be of any type and then other two parameters are of lists of any types. This is an example...
fun func x [y] [z] = [x, y, z];
Even though the function evaluates to the proper data types, I get a match non-exhaustive warning.
In this example, I don't get the same warning...
fun func x y = (y, x);
It should be because of the lists but I'm not sure how to handle it so I don't actually see a warning.

You are getting that warning because you have only told your function what to do when passed an element and two lists, where each of the lists has only 1-element. What happens if one or both of those lists have fewer than 1 or more than 1 element?
Are you familiar with #? It might help you write the function that you seem intent on writing, but without that warning.

Related

How to write an anonymous function with a variable number of output arguments?

Using deal we can write anonymous functions that have multiple output arguments, like for example
minmax = #(x)deal(min(x),max(x));
[u,v] = minmax([1,2,3,4]); % outputs u = 1, v = 4
But if you want to provide a function with its gradient to the optimization function fminunc this does not work. The function fminunc calls the input function sometimes with one and sometimes with two output arguments. (EDIT: This is not true, you just have to specify whether you actually want to use the gradient or not, using e.g. optimset('SpecifyObjectiveGradient',true). Then within one call it always asks for the same number of arguments.)
We have to provide something like
function [f,g] = myFun(x)
f = x^2; % function
g = 2*x; % gradient
which can be called with one or two output arguments.
So is there a way to do the same inline without using the function keyword?
Yes there is, it involves a technique used in this question about recursive anonymous functions. First we define a helper function
helper = #(c,n)deal(c{1:n});
which accepts a cell array c of the possible outputs as well as an integer n that says how many outputs we need. To write our actual function we just need to define the cell array and pass nargout (the number of expected output arguments) to helper:
myFun = #(x)helper({x^2,2*x,2},nargout);
This now works perfectly when calling fminunc:
x = fminunc(myFun,1);
The OP's solution is good in that it's concise and useful in many cases.
However, it has one main shortcoming, in that it's less scalable than otherwise possible. This claim is made because all functions ({x^2,2*x,2}) are evaluated, regardless of whether they're needed as outputs or not - which results in "wasted" computation time and memory consumption when less than 3 outputs are requested.
In the example of this question this is not an issue because the function and its derivatives are very easy to compute and the input x is a scalar, but under different circumstances, this can be a very real issue.
I'm providing a modified version, which although uglier, avoids the aforementioned problem and is somewhat more general:
funcs_to_apply = {#(x)x.^2, #(x)2*x, #(x)2};
unpacker = #(x)deal(x{:});
myFun = #(x)unpacker(cellfun(#(c)feval(c,x),...
funcs_to_apply(1:evalin('caller','nargout')),...
'UniformOutput',false)...
);
Notes:
The additional functions I use are cellfun, evalin and feval.
The 'UniformOutput' argument was only added so that the output of cellfun is a cell (and can be "unpacked" to a comma-separated list; we could've wrapped it in num2cell instead).
The evalin trick is required since in the myFun scope we don't know how many outputs were requested from unpacker.
While eval in its various forms (here: evalin) is usually discouraged, in this case we know exactly who the caller is and that this is a safe operation.

What does a function with this ~ mean? (e.g. function=f(~, x, y))

I am doing another coursera assignemnt, this time with aerial robotics. I have to program a pd controller using the matlab ode45 (ordinary diff. equation). And the file that has to contain this code gets called as follows:
pd_controller(~, s, s_des, params)
I searched around but couldn't find anthing that explain this to me and how it works.
In the main program the function is called with a time variable which I would need for my ODE:
controlhandle(t, s, s_des, params)
Where this controlhandle is the functionhandler for pd_controller.
So, what does this mean? And can I access whatever is behind ~?
Besides:
I found one example, but the other around. A function, let's call it function = f(a,b) was called with f(~, b) where a and b has been declared inside the function.
The symbol is called a tilde, and it signifies that you are ignoring that input argument.
See the documentation here: https://mathworks.com/help/matlab/matlab_prog/ignore-function-inputs.html
In your case, the function controlhandle will not be passed a t variable, and probably has (should have) some check for this and perhaps a default t if none is given.
This works the same with output arguments, for example if you want the index of a max in an array, but not the max itself, you would use
a = [pi, 3.6, 1];
[~, idx] = max(a); % idx = 2, we don't know what the max value is
It means you don't need pass this parameter in this function call. Also, you can use it in the output of some functions too. For example:
A = [1 4 2 2 41];
[~, B] = sort(A);
this means you don't need the second output, and you can ignore that.
In your case, when no value sent for the first parameter t, probably the function acts on a default value for t in his computation.
Also, you can find more about that in matlab documentation.
I should have mentioned that this post exists as an answer, but it might be here instead.

How to achieve vector input/output with different operations using anonymous functions?

Suppose I want to create an anonymous function that does the following
f: [a, b] -> [a^2, b/2]
Since the operation is different on a and b I haven't been able to figure out how. Is this at all possible in matlab? My function will have the constraints R^2 -> R^2
Because of the specific constraints, it would have to be something like this:
f = #(x) [x(1)^2, x(2)/2];
You can't explicitly define outputs in an anonymous function any other way.
Though you already accepted PQL's answer your question actually reads like you're looking for this solution using deal:
f = #(x,y) deal( x^2, y/2 );
[u,v] = f(2,2)
returning:
u =
4
v =
1
Looking at the matlab help for anonymous functions looking at section functions with multiple inputs or outputs, I would think that you would be able to do something like the code below
Second edit Turns out if you use deal (as given by thewaywewalk) or if you dereference the anonymous function you can get the same thing.
crazyfunction=#(a,b) {(a^2),(b/2)};
[x y]=crazyfunction(a,b);
Quick and dirty test shows that this will give no syntax errors
>> f = #(x,y) {x^2, y/2};
>> f(2,2)
ans =
[4] [1]
EDIT Fired up matlab to see my original answer would actually work, doesn't look like it (see second edit you need to use {}).
You would either daisy chain two anonymous functions together in such a way that a and b are part of anonymous function c or use a struct of anonymous functions effectively as shown below
crazyfunction={#(a) (a^2); #(b) (b/2);}
[crazyfunction{1](7) crazyfunction{2}(9)]
ans =
49.0000 4.5

What does this matlab statement do

I have a statement in my MATLAB program:
f = #(A)DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus);
I understood that f is defined as the function handle to the function distancegauss which contains the parameters/arg list present inside the parentheses.
What does the variable A in #(A) do? Does it have any importance? While browsing I found that the variables within parentheses after # would be the input arguments for an anonymous function..
Can anyone explain what does that A do? Will this handle work even without that A after the # symbol ? Because it is already present as an argument to be passed after the function name.
Your code will create an anonymous function f which accepts one input A. In particular f will call the function DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus); where the value of A is whatever you input with f(A) and the other inputs must already exist in your workspace and will be passed to the function. Note: if the other variables don't exist you should get an error when calling f.
Now a reasonable question is why would you want to do this you could just call DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus); directly with whatever values you want, without having to worry about whether some of them exist.
There are two main reasons I can think of why you would do this (I'm sure there are others). Firstly for simplicity where your other inputs don't change and you don't want to have to keep retyping them or have users accidentally change them.
The other reason where you would want this is when optimizing/minimizing a function, for example with fminsearch. The matlab optimization functions will vary all inputs. If you want only vary some of them you can use this sort of syntax to reduce the number of input variables.
As to what A actually is in your case this will depend on what it does in DistanceGauss, which is not a standard MATLAB function so I suggest you look at the code for that.
"f(A)" or "f of A" or "The function of A" here has the handle "f"
DistanceGauss() here is another function that was defined elsewhere in your code.
You would set x_axis, Y_target, Y_initial, numOf, & modus before creating the function f. These arguments would stay the same for Function f, even if you try and set them again later.
'A' though, is different. You don't set it before you make the function. You can later operate on all values of A, such as if you plot the function or get the integral of the function. In that case, it would be performing the DistanceGauss function on every value of 'A', (though we can't see here what DistanceGauss function does. )
Anonymous function should be defined such as:
sqr = #(x) x.^2;
in which x shows the variable of the the function and there is no name for it (it is called anonymous!).
Although you can do something like this:
c = 10;
mygrid = #(x,y) ndgrid((-x:x/c:x),(-y:y/c:y));
[x,y] = mygrid(pi,2*pi);
in which you are modifying an existing function ndgrid to make a new anonymous function.
In your case also:
f = #(A)DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus);
This is a new anonymous function by modifying the function DistanceGauss that you may want to have a single variable A.
If you remove (A) from the code, then f would be a handle to the existing function DistanceGauss:
f = #DistanceGauss;
Now you can evaluate the function simply by using the handle:
f(A,x_axis,...)

How to get all outputs (MatLab)?

Suppose I have a function that gives out unknown number of output arguments (it depends on input,thus change through the loops). How to get all of them?
nargout doesn't help as the function uses varargout (the result is -1)
And of course I can't rewrite the function, otherwise the question wouldn't arise :- )
Well, thanks to all partisipated in discussion. Summing up, it seems the problem has no general solution, because MatLab itself estimates the number of desired outputs before the function call to use inside it. Three cases can be pointed out though:
1) The funcrion doesn't have varargout in definition, thus nOut=nargout(#fcn) returns positive number.
Then nOut is an actual number of outputs and we can use a cell array and a column list trick.
X=cell(1,nOut);
[X{:}]=fcn(inputs);
2) The funcrion has varargout in definition, thus nOut=nargout(#fcn) returns negative number. However some correlation with inputs can be found (like length(varargin)=length(varargout)).
Then we can calculate the resulting nOut from inputs and perform the above column list trick.
3) You know the fcn developer.
Ask him fot assistance. For example to make the function's output to be a cell array.
One of ways I usually use in this case is to store all outputs in a cell array inside the function. Getting the cell array outside the function's body, you might investigate its length and other properties.
Here is how you could deal with the problem in general. I didn't mention this solution earlier because... it is horrible.
Suppose a function can have 1 or 2 output arguments:
try
[a, b] = f(x)
catch
a = f(x)
end
Of course it is possible to do this for any number of output arguments, but you really don't want to.