Create an array that grows at a regular interval on Matlab - 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

Related

How to save and pass a variable in Matlab

I can find / identify all digits in a number using a recursive function.
My issue is trying to sum the number through each recursion.
I had to initialize sum = 0 at the top of my function statement, and when I return through recursion, I'm always resetting sum back to zero. I do not know how to save a variable without first initalizing it.
Code is below;
function output= digit_sum(input)
sum=0
if input < 10
output = input
else
y=rem(input,10);
sum=sum+y
z=floor(input/10);
digit_sum(z)
end
output=sum
end

use structure in matlab

I want to use structure in matlab but in first iteration it's run correctly and in other iteration give that message .
1x2 struct array with fields:
my code is :
for i=1:lenfd
currow=rees(i,:)
maxcn=max(currow)
if maxcn~=0
maxin=find(currow==maxcn)
ress(i).x =maxin
end
end
thank you.
That message is not a warning or error. That's just MATLAB printing the output of an operation. And it does that by default, unless you suppress it by appending a semicolon to the command:
for ii = 1:lenfd
currow = rees(ii,:); % <=== NOTE: semicolons at the end
maxcn = max(currow);
if maxcn ~= 0
ress(ii).x = find(currow==maxcn);
end
end
Note that max() may have 2 outputs, the second output being the first index into the array where the maximum occurred. If you know beforehand that any maximum will occur only once, you can skip the call to find() and use the second output of max().

function passed as parameter does not evaluate more than once matlab

I am writing a Matlab script which requires the repeated generation of random numbers. I am running into an issue where if I pass my random generation function as a parameter to another function, then within the function to which it is passed, it only evaluates once.
Here is some example code:
This is my file randgen.m:
function number = randgen()
'HELLO WORLD'
number = rand(1);
end
Here is my file problemtester.m:
function arr = problemtester(rgen)
firstrand = rgen();
for i = 1:1000
arr(i) = rgen();
end
When I run the command
x = problemtester(randgen);
HELLO WORLD is printed once, and x is filled with 1000 copies of the same random number, so the function must only have evaluated once even though the loop ran 1000 times. Why is this function only evaluating once, despite the repeated calls to it, and more importantly, how do I make it call on each loop iteration?
By calling the function with
x = problemtester(randgen)
MATLAB will first evaluate randgen, as this is a function (and is callable without any parameters). At that time, HELLO WORLD is printed. The return value of that function call is then passed to problemtester, which saves this one value 1000 times into arr and returns that.
To make problemtester call the function randgen, you have to supply a function handle, which is MATLAB's equivalent to function pointers.
x = problemtester(#randgen)
This prints HELLO WORLD a thousand times, and returns a nice random vector.

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'.

Designing Function to Reduce Return Variables in Matlab

This is NOT a question where I need to know how to add A+B in MATLAB. This is more of a code design question.
I have few function files that return a numeric matrix and index info on the matrix. For example
function [Mat1, IdxID, IdxDate, IdxVal, IdxMarker, IdxOpen, ...] = First ()
....
.... % where IdxId = 1 ; IdxDate = 2 ; ...
end
function [Mat1, IdxUid, IdxName, IdxVal, Mat2, IdxUid2, IdxSalary2, ...] = Second ()
....
.... % where IdxUid= 1 ; IdxName= 2 ; ...
end
As you can see the code becomes clunky and when I call these functions, I have to declare an equal number of outputs to catch all the indices. The advantage is if I suddenly swap ID & Date columns, the calling functions do not change as I simply make ID=2, Date=1. I also have the advantage of renaming these variables inside the function.
Is there a better way to do this? I'm testing whether struct or cell can be used for indices. I can't use datasets or cell for returning numeric matrix. Too much time is lost in translating it into numbers. Thanks.
Yes, you can return arrays/cells/structs instead. For instance, id can be a struct with multiple variables. Your function definition could be as follows.
function [Mat, Id] = Second ()
...
end
In your function, have the following set:
Id.Name
Id.Val
Id.Salary
...
If you find that you have multiple structs with the same exact structure, you can even consider objects.
Please clarify with more details on the structure if you want a more detailed answer.