Efficient Way to Generate Vector of Points Used in Recursive Scheme - matlab

I am implementing the adaptive Simpsons method in Matlab recursively. I wish to store all of the points where function evaluations take place to generate a histogram after integrating. I currently have:
function [S, points] = adsimp(f, a, b, fv, tol, level, points)
...
d = (a+b)*0.25;
e = (a+b)*0.75;
points = [points, d, e];
...
Thus, for every function call, I am increasing the length of points by two. My understanding of Matlab's function input/output scheme is poor. I'd like to know:
1) When the input and output share a variable name, does this use a single variable, or is a local copy made and then returned?
2) If it is a copy, is there a way to pass points by reference and preallocate sufficient memory?

To answer your first question, see here. Most MATLAB variables are passed by value (matrices, etc.) unless it is a handle object (function handle, axis handle etc.) A local copy of an input variable is made only if that variable is altered in the function. ie.
function y = doTheFunc1(x)
x(2) = 17;
y = x;
a copy must be made. As opposed to:
function y = doTheFunc2(x)
y = x(1);
where no copy need be made inside the function. In other words, MATLAB is a "copy on write" language. I am almost certain this is true regardless what your output variable output name is (ie. this holds even if your output and input are both named x).
To answer your second question, look at the first answer here. Consider using a nested function or a handle object.

Related

Inequality indexing using optimization variables in MATLAB

Let the variables A and B be n x 1 doubles and c be a scalar. My goal is to sum the values in A corresponding to indices for which the optimization variable x is greater than B. I have written this up below:
x = optimvar('x',n); % Creates optimization variable
objfun = sum(x); % Creates objective function
constraint = sum(A(x>=B))>=c; % Constraint based on logical indexing
The third line in the code above returns an error message because optimization variables are not compatible with inequality indexing. Specifically, x>=B cannot be input as indexes into A. Is there a way around this? Or am I thinking about this the wrong way?
Thank you!
You need to use function handles for both, the objective function as well as the constraint-function:
objfun = #(var) sum(var);
constraint = #(var) sum(A(var>=B)) >= c;
In fact, for the objective function objfun, you may also use objfun = #sum. This is a function handle. You can think of it as a pointer or reference to a certain function. Function, which work with one input can be used directly (with #). The optimizer calls the function and uses the optimization variable as input.
Now, if you have multiple inputs, you need to create a function, where you define all inputs but one. For this, you create an anonymous function handle, where you tell the handle what variables are placed where: #(var) sum(A(var>=B)) >= c. The variable var is the changing input and the other variables A, B, and c are taken from the workspace at the point of definition (i.e. the function handle is unaffected if you change the variables later or even delete them).

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.

I am having trouble creating function handles. I want to embed a maximizing function within a minimizing function

The following code won't work, but this is the idea I'm trying to get at.
c = #(x)constraints;
%this is where I would initialize sum as 0 but not sure how...
for i = 1:length(c)
sum = #(x)(sum(x) + (min(c(x)(i),0))^2);
end
penFunc = #(x)(funcHandle(x) + sig*sum(x));
where constraints and funcHandle are functions of x. This entire code would iterate for a sequence of sig's.
Obviously c(x)(i) isn't functional. I'm trying to write the function where the minimum of c(x) at i (c(x) is a vector) or 0 is taken and then squared.
I know I could calculate c(x) and then analyze it at each i, but I eventually want to pass penFunc as a handle to another function which calculates the minimum of penFunc, so I need to keep it as a function.
I confess I don't understand entirely what you're trying to achieve, but it appears you're trying to create a function handle of an anonymous function with a changing value sum that you precompute. MATLAB anonymous functions do allow you to do this.
It appears there might be some confusion with anonymous functions here. To start with, the line:
c = #(x)constraints;
is probably supposed to be something else, unless you really want c to be a function handle. The # at the start of the line declares a new anonymous function, when I think you just want to call the existing function constraints. It appears you really want c to be an array of constraints coming from the constraints function, in which case I think you mean to say
c = constraints(x);
Then we get to the sum, which I can't tell if you want as a vector or as a single sum. To start with, let's not name it 'sum', since that's the name of a built-in MATLAB function. Let's call it 'sumval'. If it's just a single value, then it's easy (it's easy both ways, but let's do this.) Start before the for loop with sumval=0; to initialize it, then the loop would be:
sumval = 0;
for i = 1:length(c)
sumval = sumval + (min(c(i),0))^2);
end
All four lines could be vectorized if you like to:
c(c>0) = 0; %Replace all positive values with 0
sumval = sum(c.^2); % Use .^ to do a element by element square.
The last line is obviously where you make your actual function handle, and I'm still not quite sure what is desired here. If sig is a function, then perhaps you really meant to have:
penFunc = #(x)(funcHandle(x) + sig*sumval);
But I'm not sure. If you wanted sum to be a vector, then how we specified it here wouldn't work.
Notice that it is indeed fine to have penFunc be an anonymous function with a variable within it (namely sumval), but it will continue to use the value of sumval that existed at the time of the function handle declaration.
So really the issues are A) the creation of c, which I don't think you meant to be a function handle, and B) the initialization of sum, which should probably be sumval (to not interact with MATLAB's own function), and which probably shouldn't declare a new function handle.

MATLAB cell array of function handles - How does it work?

I am trying to understand the following commands of a MATLAB script :
global operatorObj
calcEVR_handles = operatorObj.calcEVR_handles;
m = operatorObj.nInputs
E = zeros(m,1);
V = zeros(m,1);
R = zeros(m,m);
for i=1:m
[E(i), V(i), R(i,i)] = calcEVR_handles{i}(t,x);
end
What can calcEVR_handles be, if t is a float and x is a vector?
calcEVR_handles (to me) looks like a cell array where each element is a handle to a function. Each element in calcEVR_handles is an anonymous function that takes in a single value t and a single vector x. As such, by doing calcEVR_handles{i}, you would access the corresponding function stored at the ith element in the cell array. Once you have access, you then pass your parameters to this function and it gives you those three outputs.
To show you an example of this working, consider the following cell array that works similarly to calcEVR_handles.
calcCellFunc = {#sin, #cos, #tan};
This is a three element cell array, where each element is a handle to a function. The # is a special character in MATLAB that denotes that you are creating a handle to a function. It's also used to create anonymous functions, but let's shelve that for this answer. You can read more about it here if you want to delve into more detail regarding this.
Back to our cell array of handles, we will make handles for sin, cos and tan. You can then iterate over your cell array by accessing the function you want by calcCellFunc{idx} where idx is the element you want in the cell array. This will ultimately give you the function stored at index idx. Once you do that, you can then call the function and specify whatever inputs you want (or none if it doesn't take any inputs). Here's a quick example for you. Let's create a random 5 x 5 matrix, and run through each function with this matrix serving as the input. We then take each of these outputs and store them into a corresponding slot in an output cell array. As such:
rng(123); %// Set seed for reproducibility
M = rand(5);
calcCellFunc = {#sin, #cos, #tan};
out = cell(1, numel(calcCellFunc)); %// To store the results for each function
for idx = 1 : numel(calcCellFunc)
out{idx} = calcCellFunc{idx}(M); %// Get the function, then pass
%// the matrix M to it
end
If you want to make things clear, you could split up the out statement to this instead:
func = calcCellFunc{idx}; %// Get access to the function
out{idx} = func(M); %// Pass M to this function
If you're new to handles / anonymous functions, you should probably use the above code first to make it explicitly clear on what MATLAB is doing. You are first getting access to the function you want that is stored in the cell array, and then you pass your arguments to this function.
If we display the output, we get:
>> celldisp(out)
out{1} =
0.6415 0.4106 0.3365 0.6728 0.5927
0.2823 0.8309 0.6662 0.1815 0.7509
0.2249 0.6325 0.4246 0.1746 0.6627
0.5238 0.4626 0.0596 0.5069 0.5737
0.6590 0.3821 0.3876 0.5071 0.6612
out{2} =
0.7671 0.9118 0.9417 0.7398 0.8054
0.9593 0.5564 0.7458 0.9834 0.6604
0.9744 0.7745 0.9054 0.9846 0.7489
0.8518 0.8866 0.9982 0.8620 0.8191
0.7522 0.9241 0.9218 0.8619 0.7502
out{3} =
0.8363 0.4503 0.3573 0.9094 0.7359
0.2942 1.4934 0.8932 0.1845 1.1370
0.2308 0.8167 0.4690 0.1773 0.8850
0.6149 0.5218 0.0597 0.5880 0.7004
0.8761 0.4135 0.4205 0.5884 0.8814
The first element of the output cell array has the output when you pass M to sin, the second when you pass M to cos, and the third when you pass M to tan.
So the next question you're asking... why is this useful?
Point #1 - Nix the copying and pasting
This kind of code writing is very useful because if you want to use the same inputs and supply them to many different functions, we would naturally be inclined to do some copying and pasting. Take each of your function names, and create a single line for each. Each line would call the corresponding function you want, followed by the input arguments. This can become quite tedious, and so one smart way to do it would be to place your function name as a handle into a cell array, and to write one for loop that goes over all of the functions dynamically. You could even explore cellfun and escape using the for loop to iterate over all of the function handles too, but I'll leave that for you to read up on.
In this way, you have very maintainable code and if you want to remove functions that don't need to be run, just remove the handles from the cell array rather than scrolling down to where the line that invokes this function is located and removing that.
This is actually a very common technique in computer science / software engineering in general. In fact, this is actually quite close to what are known as function pointers. This is MATLAB's cheap way of doing it, but the logic behind this is essentially the same.
Point #2 - Higher Order Functions
Another way this is useful is if you have a function where one (or more than one!) of the inputs is a function, and you also specify inputs into this function as additional parameters to this function. This is what is known as a higher order function. The outputs would be based on using this input function, and the additional inputs you specify to it and the outputs are based on using this input function and the inputs you specify for this function.
One very good example is the fzero function in MATLAB. The goal is to find the root of a non-linear function, and the first parameter is a handle to a function that you specify. The base behaviour behind how fzero works is the same no matter what the function is. All you have to do is specify the function you want to solve and the initial guess of where you think this root is.
All in all, anonymous functions are very useful.

MATLAB: creating a fast function that closes over a large variable

I am trying to create a function that stores a very large variable for use each time the function is called. I have a function myfun(x,y) where y is very large, and therefore slow to execute because MATLAB is pass-by-value. However, I only pass the variable y once during execution of a program, creating a closure that is then passed off to another function to call repeatedly:
Y = create_big_matrix();
newfun = #(x) myfun(x,Y);
some_other_fun(newfun); % This calls newfun several times
I assume that each time newfun is called, it copies the stored value of Y to myfun. This seems very inefficient. Is there a better way to implement newfun so that Y is only copied once, when the newfun is created (and maybe when it's passed to some_other_fun)?
MATLAB has copy-on-write mechanisms that prevent a copy of Y when myfun(x,Y) is called, unless it modifies the input. I do not think you need to worry about performance issues in this case, but I would have to see the code for myfun and run tests to verify.
Quoting this post on a MathWorks blog:
Some users think that because MATLAB behaves as if data are passed by value (as opposed to by reference), that MATLAB always makes copies of the inputs when calling a function. This is not necessarily true.
The article goes on to describe that MATLAB has limited abilities to recognize when a variable is modified by a function and avoids copies when possible. See also this SO answer summarizing the "under the hood" operations during copy-on-write as described in an old newsreader post.
To investigate whether a copy is taking place, use format debug to check the data pointer address pr for Y in the calling function, and again inside myfun. If it is the same, no copy is taking place. Set a breakpoint to step through and examine this pointer.
Since Y is not a parameter of the function handle, it is only passed to the function handle once, namely at the time of it's execution - including all fancy copy-on-write optimizations there might be.
So the function_handle gets its own version of Y right at the time of its definition.
During execution of the function_handle Y is not passed to the function_handle at all.
You can visualize that with a easy example:
>> r = rand();
% at this point the function_handle gets lazy copy of r, stored in its own workspace
>> f = #() r;
>> r
r =
0.6423
% what happens to the original r, doesn't matter to the function-handle:
>> clear r
>> f()
ans =
0.6423
An actual copy should only be made if the original Y gets modified / deleted (where it's really copied on delete might be another question).
You can check whether or not Y gets really copied into the function_handle workspace using functions, with the above example (only with a different value for r):
r =
Structure address = c601538
m = 1
n = 1
pr = 4c834a60
pi = 0
0.4464
>> fcn = functions(f);
>> fcn.workspace{1}.r
ans =
Structure address = c6010c0
m = 1
n = 1
pr = 4c834a60
pi = 0
0.4464
You can see that, as discussed in chappjc's answer, the parameter is only lazily copied at this time - so no full copy is created.