Matlab fminsearch options/restrictions - function

I have this function in Matlab which is supposed to find the smallest value possible for minValuePossible, by varying the two initial set values of inValues. How can I set the fmin search function to NOT try negative values while trying to find the minimum? Also how can I set the number of different variations the fminsearch function performs while trying to find the minimum? Because currently it tries somewhere around 20 different combinations of the two inValues and then completes. Maybe define the amount by which it changes each value? How would I do that?
function Valueminimiser
inValues = [50,50];
minValuePossible = fminsearch(#minimiser, inValues);
function result = minimiser(inValues)
x=inValues(1);
y=inValues(2);
RunMode = 2;
ValueOne = x;
ValueTwo = y;
[maxSCRAout] = main(RunMode,ValueOne,ValueTwo);
result = minValuePossible;
end
end

How can I set the fmin search function to NOT try negative values while trying to find the minimum?
Add the constrains of the values of your minimiser function at its beginning. If you meet this constrains then return a huge function value of minimizer. This will prevent fminsearch consider numbers which are not in your interest:
function result = minimiser(inValues)
if (sum(inValues < 0) > 1) % check if there is any negative number in input variable
result = hugeValue; % give a big value to the result
return; % return to fminsearch - do not execute the rest of the code
end
x=inValues(1);
y=inValues(2);
RunMode = 2;
ValueOne = x;
ValueTwo = y;
[maxSCRAout] = main(RunMode,ValueOne,ValueTwo);
result = minValuePossible;
Also how can I set the number of different variations the fminsearch function performs while trying to find the minimum?
You can define options of fminsearch by using optimset function. The parameter of optimset 'MaxFunEvals' is the maximum number of evaluations -- notice that this cout even the values you constrained, so maybe setting 'TolX' as advised by #slayton might be better if you are concerned about the accuarcy.
options = optimset('MaxFunEvals',numberOfVariations);
minValuePossible = fminsearch(#minimiser, inValues,options);

The docs for fminsearch don't describe a way to restrict the domain of the function you want to minimize.
If you want to restrict the range to all non-negative numbers then you can simply wrap your function in a call to abs, depending on the syntax .
minValuePossible = fminsearch( #(x)(minimiser( abs(x) ) ), inValues);
If you are worried about it constantly converging to the same minima then try a variety of different initial values.
Lastly you can alter the termination tolerances for X and minValuePossible using the TolX and TolFun input parameters. This is done with standard param value syntax: function(...., 'Param', value)
fminsearch( #(x)(minimiser(abs(x))), inValues, 'TolX', x_tolerance);

Related

Use of function / return

I had the task to code the following:
Take a list of integers and returns the value of these numbers added up, but only if they are odd.
Example input: [1,5,3,2]
Output: 9
I did the code below and it worked perfectly.
numbers = [1,5,3,2]
print(numbers)
add_up_the_odds = []
for number in numbers:
if number % 2 == 1:
add_up_the_odds.append(number)
print(add_up_the_odds)
print(sum(add_up_the_odds))
Then I tried to re-code it using function definition / return:
def add_up_the_odds(numbers):
odds = []
for number in range(1,len(numbers)):
if number % 2 == 1:
odds.append(number)
return odds
numbers = [1,5,3,2]
print (sum(odds))
But I couldn’t make it working, anybody can help with that?
Note: I'm going to assume Python 3.x
It looks like you're defining your function, but never calling it.
When the interpreter finishes going through your function definition, the function is now there for you to use - but it never actually executes until you tell it to.
Between the last two lines in your code, you need to call add_up_the_odds() on your numbers array, and assign the result to the odds variable.
i.e. odds = add_up_the_odds(numbers)

Nested function with two variables in matlab

I have three functions and i want two variables to run through all the functions. I tried doing this:
R = rot(mir(sca(P(1,:),P(2,:))));
however i get this error:
Error using mir (line 2)
Not enough input arguments.
Any suggestions?
%rot.m
function rot = rot(x,y)
rot = [ cos(pi/6)*x-sin(pi/6)*y; sin(pi/6)*x+cos(pi/6)*y ];
%mir.m
function mir = mir(x,y)
mir = [x;(-y)];
%sca.m
function sca = sca(x,y)
sca = [2*x;2*y];
You should not be surprised about the error. Function mir expect two parameters (in fact, all of your functions expect that), but you provide only one. Mind you, a matrix is considered one parameter. You can do either of the following to correct the problem:
Redefine mir to accept one parameter and split it inside the function into two separate variables
Redefine sca to return two values:
function [outx, outy] = sca(x, y)
outx = 2 * x;
outy = 2 * y;
and then pass them to mir like so:
[scax, scay] = sca(x, y);
mir(scax, scay);
Obviously, the same needs to be done to function rot as well.
In MATLAB if you have more then one output argument you have to explicitly specify the output variables. By default function always returns one (the first) argument.
In your situation one choice can be to change definitions of your functions in such a way that they receive only one input argument as a matrix. For example:
%mir.m
function mir = mir(xy)
mir = [xy(1,:); -xy(2,:)];
or even easier in this case (you can simplify other functions as well):
function xy = mir(xy)
xy(2,:) = -xy(2,:);
I hope you got the idea.
Then you can run:
R = rot(mir(sca(P(1:2,:))));
If you cannot change your function definitions for some reason, you will have to split the one-line call to three function into 3 lines:
S = sca(P(1,:),P(2,:));
M = mir(S(1,:),S(2,:));
R = rot(M(1,:),M(2,:));

Matlab call a function from a function

I have two functions:
function [] = func_one()
S.pb = uicontrol('style','push','unit','pix','posit',[20 20 260 30],
'string','Print Choices','callback',{#func_two,S});
and I have the second function:
function [a] = func_two(varargin)
a = 'alon';
end
I want func_one to return the variable a of func_two. How can I do that please?
I tried:
function [a] = func_one()
But I guess I have to do something with 'callback',{#func_two,S})
Thank you all!
If, as you say, you want func_one to return the value a in func_two then the easiest way to do this without using a callback is:
function [a] = func_one()
S.pb = uicontrol('style','push','unit','pix','posit',[20 20 260 30],
'string','Print Choices');
a = func_two()
The above will allow you to say run a=func_one and a will be the string 'alon'.
If you really really want func_two() to be a callback of your pushbutton, and you want a='alon' to be assigned in the workspace of func_one (the function that calls func_two) then put this in func_two
assignin('caller','a',a)
And if neither is what you want, then maybe you can indicate why you want func_one to return what func_two returns - like the exact interaction you are hoping to have with your GUI and how it differs from what you're actually experiencing.
If you are designing a GUI programmatically, I suggest you use nested functions to share data. Example:
function IncrementExample()
x = 0;
uicontrol('Style','pushbutton', 'String','(0)', ...
'Callback',#callback);
function callback(o,e)
%# you can access the variable x in here
x = x + 1;
%# update button text
set(o, 'String',sprintf('(%d)',x))
drawnow
end
end

Lua - How do I use a function from another script?

I've been looking around and I have not been able to find anything that has worked for me. I'm starting to learn more Lua and to start off I'm making a simple calculator. I was able to get each individual operation onto separate programs, but when I try to combine them I just can't get it to work. My script as it is now is
require "io"
require "operations.lua"
do
print ("Please enter the first number in your problem.")
x = io.read()
print ("Please enter the second number in your problem.")
y = io.read()
print ("Please choose the operation you wish to perform.")
print ("Use 1 for addition, 2 for subtraction, 3 for multiplication, and 4 for division.")
op = io.read()
op = 1 then
function addition
op = 2 then
function subtraction
op = 3 then
function multiplication
op = 4 then
function division
print (answer)
io.read()
end
and my operations.lua script is
function addition
return answer = x+y
end
function subtraction
return answer = x-y
end
function multiplication
return answer = x*y
end
function division
return answer = x/y
end
I've tried using
if op = 1 then
answer = x+y
print(answer)
if op = 2 then
answer = x-y
print(answer)
and I did that completing each operation. But it doesn't work. I can't even get the error code that it's returning because it closes so fast. What should I do?
In your example, make these changes: You require operations.lua without the extension. Include parameters in your operations function definitions. Return the operation expression directly versus returning a statement like answer = x+y.
All together:
Code for operations.lua
function addition(x,y)
return x + y
end
--more functions go here...
function division(x,y)
return x / y
end
Code for your hosting Lua script:
require "operations"
result = addition(5,7)
print(result)
result = division(9,3)
print(result)
Once you get that working, try re-adding your io logic.
Keep in mind that as it's coded, your functions will be defined globally. To avoid polluting the global table, consider defining operations.lua as a module. Take a look at the lua-users.org Modules Tutorial.
The right if-then-else syntax:
if op==1 then
answer = a+b
elseif op==2 then
answer = a*b
end
print(answer)
After: please check the correct function-declaration syntax.
After: return answer=x+y is incorrect. If you want set answer's value, set without return. If you want return the sum, please use return x+y.
And I think you should check Programming in Lua.
First of all, learn to use the command line so you can see the errors (on Windows that would be cmd.exe).
Second, change the second line to require("operations"). The way you did it the interpreter expects a directory operations with an underlying script lua.lua.

Matlab: Abort function call with Strg+C but KEEP return value

I have a function in matlab with something like this:
function [ out ] = myFunc(arg1, arg2)
times = [];
for i = 1:arg1
tic
% do some long calculations
times = [times; toc];
end
% Return
out = times;
end
I want to abort the running function now but keep the values of times which are currently already taken. How to do it? When I press strg+c, I simply loose it because it's only a local function variable which is deleted when the function leaves the scope...
Thanks!
Simplest solution would be to turn it from a function to a script, where times would no longer be a local variable.
The more elegant solution would be to save the times variable to a .mat file within the loop. Depending on the time per iteration, you could do this on every loop, or once every ten loops, etc.
Couldn't you use persistent variables to solve your problem, e.g.
function [ out ] = myFunc(arg1, arg2)
persistent times
if nargin == 0
out = times;
return;
end;
times = [];
for i = 1:arg1
tic
% do some long calculations
times = [times; toc];
end
% Return
out = times;
end
I'm not sure whether persistent variables are cleared upon Ctrl-C, but I don't think it should be the case. What this should do: if you supply arguments, it will run as before. When you omit all arguments however, the last value of times should be returned.
onCleanup functions still fire in the presence of CTRL-C, however I don't think that's really going to help because it will be hard for you to connect the value you want to the onCleanup function handle (there are some tricky variable lifetime issues here). You may have more luck using a MATLAB handle object to track your value. For example
x = containers.Map(); x('Value') = [];
myFcn(x); % updates x('Value')
% CTRL-C
x('Value') % contains latest value
Another possible solution is to use the assignin function to send the data to your workspace on each iteration. e.g.
function [ out ] = myFunc(arg1, arg2)
times = [];
for i = 1:arg1
tic
% do some long calculations
times = [times; toc];
% copy the variable to the base workspace
assignin('base', 'thelasttimes', times)
end
% Return
out = times;
end