How to determine if an output is being ignored with ~ [duplicate] - matlab

This question already has an answer here:
How to determine if an output of a function-call is unused?
(1 answer)
Closed 5 years ago.
In Matlab, you can ignore an output with the following syntax:
[~, ixMax] = max(foo);
I have a function, with signature
[out, out1, out2, out3] = function foo(in1, in2, in3)
out1, out2 and out3 are optional outputs, and each is only needed in very specific (unusual) circumstances. Foo is computationally expensive, and out1/out2/out3 are all even more computationally expensive, but rely on intermediate state generated by foo. I'd like to be able to avoid computing out1/out2/out3 if the caller is using a ~ to ignore them. How can I check for that in the definition of foo?

It won't accelerate the process. The ~ is a way to the reader to tell him you won't need these outputs. It also saves the memory usage of this variable.
Matlab documentation says:
However, some functions return results that use much more memory. If you do not need those variables, they waste space on your system.
So it does not improve performance because these values are internally calculated anyway.
The book Accelerating MATLAB Performance: 1001 tips to speed up MATLAB programs by Yair M. Altman says (p187):
However, without using the ~, and if the first output is needed, the user will gain computational time by just removing the ~ and the brackets, and writing.
out = function foo(in1, in2, in3)

Related

Can Matlab optimize an external process? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm considering buying Matlab Home + Optimization module for home use, however I'm not sure it can do what I want it to.
I have an external process (not Matlab) that takes input, runs a process, and produces output. I want to tie in the input and output to Matlab so that Matlab can "optimize" these inputs, completely blind to the discrete process itself. Does Matlab have discrete optimization capabilities, or do all of its optimization functions rely on having internal access to the process itself?
Thanks!
-Stephen
if your external process is capable to assimilate parameters and give response to a external program using any methods eg, command line, or files, yes it is possible just configure your objective function to send and read the parameters and response data to the external process.
For the discrete optimization, the optimization toolbox do not work with discrete optimizations problems, but the documentation give a hint about rounding the parameter inside the objective function and then running again in the responses variable.
for example, this can be a function to optimize a volume of a prism
which is coded in a external program written in python (just for demonstration purpose with single objetive genetic algorithm (ga)):
function f = optim(x)
%Optimization criteria
l = round(x(1));
h = round(x(2));
w = round(x(3));
%String to produce the external proccess call as a system command
commandStr = ['python -c "print ' num2str(l) ' * ' num2str(h) ' * ' num2str(w) ' "'];
%Execute the system command, status = 0 for good execution
[status, commandOut] = system(commandStr);
%Convert the output of the external program from strin to doble and assign as the response of the optimization funcition
f = str2double(commandOut)
Then you can use the optimtool using this funcion as objetive as:
Then export the result to workspace and round() it.
Or make it programmable with a code like this:
function [x,fval] = runOptimization(lb,ub)
options = gaoptimset;
options = gaoptimset(options,'Display', 'off');
[x,fval] =ga(#optim,3,[],[],[],[],lb,ub,[],[],options);
x = round(x)
fval = optim(x)
And run as
[x,fval] = runOptimization([1 1 1],[3 4 5])
NOTE. the round() functions its only to demonstrate how to do discrete optimization as suggested in the documentation

Is it possible to enforce input argument data types in MATLAB?

I would like to ensure that the input arguments to a user-defined MATLAB function (contained in an m-file) are of a certain type. I understand that MATLAB automatically assigns data types to variables (to the liking of some and the dismay of others), but I would like to know if there is an option of "strict data typing" in MATLAB, or something of the sort, especially for input arguments for a user-defined function.
I found a helpful explanation of MATLAB's "fundamental classes" (data types) at these two webpages:
http://www.mathworks.com/help/matlab/matlab_prog/fundamental-matlab-classes.html
http://www.mathworks.com/help/matlab/data-types_data-types.html
However, I have been unable to find an answer to the question of strict data typing, particularly for function input arguments. I thought it would be a pretty basic question that already had been answered in numerous places, but after extensive searching I have not yet found a conclusive answer. For now, I have been manually checking the data type using the is[TYPE]() functions and displaying an error message if it does not comply, though this seems sloppy and I wish I could just get MATLAB to enforce it for me.
Below is an example of a function in which I would like to specify the input argument data type. It resides in a file called strict_data_type_test.m in MATLAB's current path. In this function, I would like to force the variable yes_or_no to be of MATLAB's logical data type. I know I can use the islogical() function to manually check, but my question is if it is possible to have MATLAB enforce it for me. I also know that any non-zero double evaluates to true and a zero evaluates to false, but I want to force the user to send a logical to make sure the wrong argument was not sent in by accident, for example. Here is the example function:
function y = strict_data_type_test( x, yes_or_no )
% manual data type check can go here, but manual check is not desirable
if (yes_or_no)
y = 2 .* x;
else
y = -5 .* x;
end
end
Adding the data type before the input argument variable name (like in most programming languages) treats the data type text as another variable name instead of a data type identifier. From that it would seem that strict data typing is not possible in MATLAB by any means, but maybe one of you many gurus knows a useful trick, feature, or syntax that I have not been able to find.
validateattributes might also work for you, if there is an appropriate attribute for your case. For example if you want to enforce that yes_or_no is a logical scalar, you could try:
validateattributes(yes_or_no,{'logical'},{'scalar'})
Otherwise maybe an attribute like 'nonempty'.
I've gotten some great responses so I can't pick just one as the "accepted answer", but to summarize what I've learned from you all so far:
No, MATLAB does not have built-in strict data typing for function input arguments
MATLAB compiles the code before running, so manual validation checking should not be very taxing on performance (the profiler can be used to assess this)
Many helpful methods of doing the manual validation checking exist, listed here in order of most relevant to least relevant for what I was trying to do:
inputParser class
validateattributes()
Error/exception handling (throw(), error(), assert(), etc.)
MATLAB's built-in state detection functions (a.k.a predicate functions)
I can look through some MathWorks-provided MATLAB functions (or Statistics toolbox functions) for ideas on how to validate input arguments by typing edit followed by the function name. Two suggested functions to look at are normpdf() (from the Statistics toolbox) and integral(). Some other functions I found helpful to look at are dot() and cross().
Other thoughts:
It would appear that the inputParser class was the overall concensus on the most professional way to validate input arguments. It was noted on a related (but not duplicate) stackoverflow post that the newer MathWorks functions tend to make use of this class, suggesting that it may be the best and most up-to-date choice.
Since the MathWorks-provided MATLAB functions do not appear to enforce strict input argument data typing, this further suggests that even if it was possible to do so, it may not be a recommended approach.
MATLAB seems to regard "error handling" and "exception handling" as two different concepts. For example, here are two links to MATLAB's Documentation Center that show how MathWorks considers "error handling" and "exception handling" differently: MathWorks Documentation Center article on Error Handling, MathWorks Documentation Center article on Exception Handling. A relevant StackOverflow post has been made on this topic and can be found here (link). I contacted MathWorks and added some new information about this topic to that post, so if you are interested you may read more by following that link.
Matlab provides an 'inputParser' which allows to check inputs. Besides this you can use assertions:
assert(islogical(yes_or_no),'logical input expected')
To ensure the correct number of input arguments, use narginchk.
btw: Take a look in some Matlab functions like edit integral and check how tmw deals with this.
You may find writing this sort of code tedious or worry that it degrades performance:
if ~islogical(yes_or_no) && ~isscalar(yes_or_no)
error('test:NotLogicalType','Second argument must be logical (Boolean).');
end
if yes_or_no
y = 2 .* x;
else
y = -5 .* x;
end
Recall, however, that Matlab compiles the code before running so even if you need to test many conditions it will be quite fast. Run the profiler to see.
Another option in some cases (maybe not your example) is to use a lazier method. This option lets your code run with whatever inputs were provided, but uses a try/catch block to trap any error:
try
if yes_or_no
y = 2 .* x;
else
y = -5 .* x;
end
catch me
...
error('test:NotLogicalType','Second argument must be logical (Boolean).');
% rethrow(me);
end
The code above would produce an error if yes_or_no was a cell array for example (it will still allow non-Boolean, non-scalar, etc. values for yes_or_no though, but Matlab is often overly permissive). You can then either generate a custom error message, detect, what kind of error was thrown and try something else, etc. Many of the functions in the Statistics toolbox use this approach (e.g., type edit normpdf in your command window) for better or worse.

Minimize inputs by loading values in MATLAB functions

In MATLAB is it be better (as far as optimization is concerned):
1)To have a function "foo" with a lot of inputs that come from the outputs from other functions
or
2)Save at the end of the functions the results to a results.mat file and load it in the "foo" function and minimize its inputs this way?
almost always: option 1.
As option 2 depends on file IO, and thus one write and one read to/from a hard disk, SSD or similar, it will likely lose out against keeping variables in RAM. Moreover, if you pass arguments to a function, and that function only reads them, no explicit copies of that variable are made. This is not true for the .mat file solution, as something that you already have in memory will be explicitly copied onto an extremely slow device (HDD, SSD), and then again read back into memory from the extremely slow device, just to save on a few input arguments.
So, unless you're working with big data sets and your variables give you out-of-memory errors, keep everything in RAM as much as possible.
You can minimize argument count by simply collecting data in a container data type. MATLAB has cell and struct for this purpose (or classdef, if you include value classes). You can transform this:
[outarg1, outarg2] = function(arg1, arg2, arg3,...)
into
[outarg1, outarg2] = function(S)
where
S = struct(...
'arg1', function1(X),...
'arg2', function2(X,Y,Z),...
'arg3', function3(X,Z),...
%// etc.
);
or
S = {
function1(X)
function2(X,Y,Z)
function3(X,Z)
%// etc.
}
or similar. Or you can make use of the special cell/functions called varargin/nargin and varargout/nargout:
varargout = function(varargin)
% rename input arguments
arg1 = varargin{1};
arg2 = varargin{2};
%// etc.
% assign all output arguments in one go
[varargout{1:nargout}] = deal(outargs{:}));
end % function
You can read more about all these things by typing help <thing> on the MATLAB command prompt. For example,
help cell
will give you a wealth of information on what a cell is and how to use it.
I think using global variables is a better way to optimize memory and processing requirements.
you can use keyword global.

How to avoid allocating memory for the returned value each time a function is called

I have a function that returns a large vector and is called multiple times, with some logic going on between calls that makes vectorization not an option.
An example of the function is
function a=f(X,i)
a=zeros(size(X,1),1);
a(:)=X(:,i);
end
and I am doing
for i=1:n a=f(X,i); end
When profiling this (size(X,1)=5.10^5, n=100 ) times are 0.12s for the zeros line and 0.22s for a(:)=X(:,i) the second line. As expected memory is allocated at each call of f in the 'zeros' line.
To get rid of that line and its 0.12s, I thought of allocating the returned value just once, and passing it in as return space each time to an appropriate function g like so:
function a=g(X,i,a)
a(:)=X(:,i);
end
and doing
a=zeros(m,1);
for i=1:n a=g(X,i,a); end
What is surprising to me is that profiling inside g still shows memory being allocated in the same amounts at the a(:)=X(:,i); line, and the time taken is very much like 0.12+0.22s..
1)Is this just "lazy copy on write" because I am writing into a?
2)Going forward, what are the options?
-a global variable for a (messy..)?
-writing a matrix handle class (must I really?)
(The nested function way means some heavy redesigning to make a nesting function to which X is known (the matrix A with notations from that answer)..)
Perhaps this is a bit tangential to your question, but if this is a performance critical application, I think a good way to go is to rewrite your function as a mex file. Here is a quote from http://www.mathworks.com/support/tech-notes/1600/1605.html#intro,
The main reasons to write a MEX-file are:...
Speed; you can rewrite bottleneck computations (like for-loops) as a MEX-file for efficiency.
If you are not familiar with mex files, the link above should get you started. Converting your existing function to C/C++ should not be overly difficult. The yprime.c example included with MATLAB is similar to what you're trying to do, since it is iteratively being called to calculate the derivatives inside ode45, etc.

MATLAB: alternatives to calling feval in ode45

I hope I am on topic here. I'm asking here since it said on the faq page: a question concerning (among others) a software algorithm :) So here it goes:
I need to solve a system of ODEs (like $ \dot x = A(t) x$. The Matrix A may change and is given as a string in the function call (Calc_EDS_v2('Sys_EDS_a',...)
Then I'm using ode45 in a loop to find my x:
function [intervals, testing] = EDS_calc_v2(smA,options,debug)
[..]
for t=t_start:t_step:t_end)
[Te,Qe]=func_int(#intQ_2_v2,[t,t+t_step],q);
q=Qe(end,:);
[..]
end
[..]
with func_int being ode45 and #intQ_2_v2 my m-file. q is given back to the call as the starting vector. As you can see I'm just using ode45 on the intervall [t, t+t_step]. That's because my system matrix A can force ode45 to use a lot of steps, leading it to hit the AbsTol or RelTol very fast.
Now my A is something like B(t)*Q(t), so in the m-file intQ_2_v2.m I need to evaluate both B and Q at the times t.
I first done it like so: (v1 -file, so function name is different)
function q=intQ_2_v1(t,X)
[..]
B(1)=...; ... B(4)=...;
Q(1)=...; ...
than that is naturally only with the assumption that A is a 2x2 matrix. With that setup it took a basic system somewhere between 10 and 15 seconds to compute.
Instead of the above I now use the files B1.m to B4.m and Q1.m to B4.m (I know that that's not elegant, but I need to use quadgk on B later and quadgk doesn't support matrix functions.)
function q=intQ_2_v2(t,X)
[..]
global funcnameQ, funcnameB, d
for k=1:d
Q(k)=feval(str2func([funcnameQ,int2str(k)]),t);
B(k)=feval(str2func([funcnameB,int2str(k)]),t);
end
[..]
funcname (string) referring to B or Q (with added k) and d is dimension of the system.
Now I knew that it would cost me more time than the first version but I'm seeing the computing times are ten times as high! (getting 150 to 160 seconds) I do understand that opening 4 files and evaluate roughly 40 times per ode-loop is costly... and I also can't pre-evalute B and Q, since ode45 uses adaptive step sizes...
Is there a way to not use that last loop?
Mostly I'm interested in a solution to drive down the computing times. I do have a feeling that I'm missing something... but can't really put my finger on it. With that one taking nearly three minutes instead of 10 seconds I can get a coffee in between each testrun now... (plz don't tell me to get a faster computer)
(sorry for such a long question )
I'm not sure that I fully understand what you're doing here, but I can offer a few tips.
Use the profiler, it will help you understand exactly where the bottlenecks are.
Using feval is slower than using function handles directly, especially when using str2func to build the handle each time. There is also a slowdown from using the global variables (and it's a good habit to avoid these unless absolutely necessary). Each of these really adds up when using them repeatedly (as it looks like here). Store function handles to each of your mfiles in a cell array and either pass them directly to the function or use nested function for the optimization so that the cell array of handles is visible to the function being optimized. Personally, I prefer the nested method, but passing is better if you will use those mfiles elsewhere.
I expect this will get your runtime back to close to what the first method gave. Be sure to tell us if this was the problem or if you found another solution.