Get acces to handles while in a Callback function - matlab

I have a Problem with my callback functions.
I wrote a small Example For it :
function drawMeAnImrect
Numbers = [1,2,3];
h = imrect();
h.addNewPositionCallback(#(h)Randomfunc(Numbers));
h.wait();
Numbers = [1,2,3,4];
end
function Randomfunc(Numbers)
disp(Numbers)
end
everytime i move the rect i will print the Numbers 1,2 and 3, even if i change the Numbers. Ist there a way to avoid this ? It works with global variables but i dont wanna use many global variables. I hope someone can help me. Thx

Related

Create an array that grows at a regular interval on Matlab

I have been thinking about how to create an array that grows at a regular interval of time (for instance every 5 seconds) on Matlab.
I figured out 2 ways, either using tic/ toc or timer function. Later this program will be complexified. I am not sure which way is the best but so far I am trying with using timer.
Here is what I have tried :
clc;
period=5;%period at which the file should be updated
freq=4;
l=freq*period;
time=[0];
a = timer('ExecutionMode','fixedRate','Period',period,'TimerFcn',{#time_append, time,l,freq},'TasksToExecute',3 );
start(a);
function [time]=time_append(obj,event,time,l,freq)
time_append=zeros(l,1);
last_time=time(end)
for i=1:1:l
time_append(i)=last_time+i/freq;
end
time=[time;time_append];
end
After compiling this code, I only get a time array of length 1 containing the value 0 wheras it should contain values from 0 to 3x5 =15 I think it is a stupid mistake but I can't see why. I have tried the debug mode and it seems that at the end of the line time=[time;time_append], the concatenation works but the time array is reinitialised when we go out of the function. Also I have read that callback function can't have output. Does someone would know how I could proceed? Using globals? Any other suggestion?
Thank you for reading
You can do this by using nested functions. Nested functions allow you to access "uplevel variables", and you can modify those. Here's one way to do it:
function [a, fcn] = buildTimer()
period=5;%period at which the file should be updated
freq=4;
l=freq*period;
time=0;
function time_append(~,~,l,freq)
time_append=zeros(l,1);
last_time=time(end);
for i=1:1:l
time_append(i)=last_time+i/freq;
end
time=[time;time_append];
end
function out = time_get()
out = time;
end
fcn = #time_get;
a = timer('ExecutionMode','fixedRate',...
'Period',period,...
'TimerFcn',{#time_append,l,freq},...
'TasksToExecute',3 );
start(a);
end
Note that the variable time is shared by time_append and time_get. The timer object invokes time_append, and updates time. You need to hand out the function handle time_get to retrieve the current value of time.
>> [a,fcn] = buildTimer; size(fcn()), pause(10); size(fcn())
ans =
21 1
ans =
61 1

Save values that are calculated in a function for each iteration of fminsearch

I want to find the Minimum of a function using
[x,fval] = fminsearch(#(param) esm6(param,identi),result(k,1:end-1),options)
now for each Iteration step i want some values that the function 'esm6' calculates to be saved in an Array. I tried the following:
In the first line of the function i wrote
identi.sim.i_optiIter = identi.sim.i_optiIter + 1;
to have an iteration-variable counting the iteration steps of fminsearch. And later to catch the values that I need I used
identi.sim.guete_werte.gew(identi.sim.i_optiIter,:,:) = y_sim;
identi.sim.guete_werte.ungew(identi.sim.i_optiIter,:,:) = y_sim_ungew;
and to make sure that I use the new values of the identi-struct for the next function call, I wrote this at the end of the function:
assignin('base','identi',identi);
Now unfortunatly it doesn't do what I wanted it to do. Can anyone help me with this?
EDIT:
I made another attempt on it, using an Output function. I extendend my Options like this:
options = optimset('Display','iter','MaxIter',3,'OutputFcn',#outfun);
But now the Problem is that i cannot figure out where to put this outfun. The outfun Looks like this:
function stop = outfun(x,optimvalues,state,iteration,y_sim,y_sim_ungew)
stop = false;
if state == 'iter'
guete_werte.gew(iteration,:,:) = y_sim;
guete_werte.ungew(iteration,:,:) = y_sim_ungew;
end
end
Now the Problem with it is, that i can not put it in the file, where i call the fminsearch, because that is a script. If i put the outputfunction into a separate .m-function file, it is not able to Access the variables of the esm6 function. And if I add it to the esm6-function file, matlab can't find the function and says
??? Error using ==> feval Undefined function or method 'outfun' for
input arguments of type 'struct'.

How to save function variable to file in MATLAB

I want to make a script that saves multiple base variables from the "base name". My attempt looks like this :
function [outargs] = save_with_basename(b)
basePath = 'C:\path\';
Var1 = evalin('base', [b '_1']);
Var2 = evalin('base', [b '_2']); % .. etc
for i=1:N
save([basePath b '_' int2str(i) '.mat'], ['Var' int2str(i)]);
end
end
This saves the files but the variable saved in the file is called Var1 (see the pic.), but I want it to be called 'Foo_1' if the function was called with :
save_with_basename('Foo');
I think the second argument to save works with the function variable, so it looks like I have to change its name dynamically (which is probably not possible?) , so I wonder if there is a way I can do it.
Here is the problem :
Thanks for any help !
For the sake of everything that is holy, please do not do this.
If you really have to, please please please do not do this.
If you really really really have to want to, you indeed need to use dynamic variables (but that doesn't make much of a difference now, does it?):
for i=1:N %what's N again?
evalin('base',['Var' num2str(i) '=' b '_' num2str(i)]);
evalin('base',['save([''' basePath b '_' num2str(i) '.mat''], [''Var' num2str(i) '''])']);
end
This will essentially perform
Var1 = "b"_1; %with whatever b is
Var2 = "b"_2;
...
save(['C:\path\b_1.mat'],['Var1']); %with whatever b is
save(['C:\path\b_2.mat'],['Var2']);
in your base workspace, so it will generate the Var* variables there. Small price to pay for selling your soul to the devil. Note that I may have missed the escaping of the single quotes in the second evalin.

MATLAB : dynamic variables not updated directly in the workspace

I have a problem with some varaibles.
I create variables dynamically in a loop.
for i=1:nbr
assignin('base', ['x_',num2str(i)],0)
end
And after, I would like to put the result of my function in these variables. But the variables in the base of the workspace are not updated directly so I have an error "Undefined function or variable". How can I fix my problem ?
for i=1:nbr
['x_',num2str(i)]= fonction(input);
end
Thank you in advance
Best regard
Instead, use a cell array:
x{i} = function(input);
Then return the entire cell array back to the caller, so that you never need to use assignin. The whole function body would look like this:
function x = myfunction(someinput)
for i=1:nbr
x{i} = someotherfunction(input);
end
% Cell array x is returned from the function

How to access a matrix to a m file from another m file?

Suppose the matrix is A which is in a m file new1.m . Now I want to access this matrix to another m file new2.m . How can it be done ?
Your question is a little nonspecific, but I'll try to answer.
There are several ways to do this,
Assuming that you have a m-file (script) named 'new1' with (for example) A = rand(4) in it. You could just run it in new2.m before you want to use A
new1;
B = 2*A;
Note that new1 will return all the other variables assigned in it, flooding your workspace. Perhaps not a problem, but if so, you could just clear them with
clear var1 var2 var2 etc.
Another way is to make new1 into a function and return (only) A
function A = new1()
but I'm guessing that might ruin some other purposes of new1.
In that case you could return A only if the function is called with a special input argument (for example 'getA')
function new1(varargin)
...
... % some code
...
if nargin && strcmp(varargin{1},'getA')
assignin('caller','A',A);
end
And so from new2, just call the function.
new1('getA');