How do I flip a timeseries data in Simulink? - matlab

I have been trying to multiply 2 sets of timeseries data in Simulink, At and Bt, and I expected the result to be like this:
ans = sum(A(1:t)*B(t:-1:1))
For instance, when t = 3, the result should be
ans =At1*Bt1 + (At2*Bt1 + At1*Bt2) + (At3*Bt1 + At2*Bt2 + At3*Bt1)
I got these 2 datasets from one of my Simulink models and I want to continue my simulation with the same model.
To achieve this, I guess I need to flip one of those 2 datasets.
So I tried the Matlab function flip(), but it doesn't work when the argument is a timeseries.
Then I tried to first output those data to Matlab workspace as arrays and flipped them, and then input them back to my Simulink model, but this didn't work as well because in those arrays there are no any columns storing Time information.
At last, I found that there is a block called "Flip" in the DSP Toolbox, but the thing is that I don't have this toolbox, probably we won't buy it, and I am not sure if this block works.

If that is what you need, then write a function to do that:
function C = multiply_timeseries(A, B)
Alen = length(A.Data);
Blen = length(B.Data);
if ~(Alen == Blen)
error("A and B length should be the same")
end
C = timeseries(zeros(1,Alen,'like',A.Data), A.Time);
for t = 1:Alen
C.Data(t) = sum( A(1:t) * B(t:-1:1) );
end
end
Modify the above to suit your needs.

Related

Fit simulation to data with multiple fitting parameters

I have a set of experimental points
Xdata=[xd1 xd2...]
Ydata=[yd1 yd2...]
And a function y=myfunction(xsimul,a,b,c) that indirectly simulates:
Ysimul=[ys1 ys2...]
for a Xsimul=Xdata
By indirectly I mean there is no direct calculation y=Function(x,a,b,c). It is instead obtained within two for loops by minimization of another function g=f(z)(using fminsearch) followed by Ysimul=(g(targetvalue)).
The goal is to fit the simulation to the experimental data and retrieve optimum a, b and c values by a least-squares method.
I can give a good initial guess to the parameters. However having 3 fitting parameters, along with the already big computing time for determining Ysimul makes this problem quite cumbersome.
So what I would like to know is:
Is this problem feasible using functions like lsqcurvefit?
If so, can you provide hints on how to do it?
Just the solution
This is a pretty standard use of lsqnonlin, you just need to get it formatted correctly. That means something like this:
%First, define a function whose inputs are a single vector, and whose
%outputs can be minimized
funToMinimize = #(abc) myfunction(Xdata,abc(1), abc(2), abc(3)) - Ydata;
%Define an initial guess of the values (including the size of the vector)
abcInitial = [0 0 0]; %Or whatever your best guess is
%Then use the nonlinear fit
abcFit = lsqnonlin(funToMinimize , abcInitial);
Demonstration
I obviously can't generate a solution to your myfunction problem, but we can still walk through the important steps.
First, let's define a function to simulate your myfunction, Xdata, and Ydata.
%Define some complicated-ish "myfuction", with inputs that match yours
myfunction = #(xsimul, a, b, c) sqrt(abs(xsimul))*a + sin(xsimul)*b*a^2 + c;
%Define "Xdata"
Xdata = linspace(0,10,100);
%Define "Ydata", note that I'm sneaking in a set of (a, b, c) values here
Ydata = myfunction(Xdata, 1, 2, 3);
Now, let's run the steps in the answer above:
funToMinimize = #(abc) myfunction(Xdata,abc(1), abc(2), abc(3)) - Ydata;
abcInitial = [0 0 0];
abcFit = lsqnonlin(funToMinimize , abcInitial)
The last step should return [1 2 3], matching the (a, b, c) values used to generate Ydata.

Matlab slow performance using closures

I'm coding a solution for Poisson equation on a 2d rectangle using finite elements. In order to simplify the code I store handles to the basis functions in an array and then loop over these basis functions to create my matrix and right hand side. The problem with this is that even for very coarse grids it is prohibitively slow. For a 9x9 grid (using Dirichlet BC, there are 49 nodes to solve for) it takes around 20 seconds. Using the profile I've noticed that around half the time is spent accessing (not executing) my basis functions.
The profiler says matrix_assembly>#(x,y)bilinearBasisFunction(x,y,xc(k-1),xc(k),xc(k+1),yc(j-1),yc(j),yc(j+1)) (156800 calls, 11.558 sec), the self time (not executing the bilinear basis code) is over 9 seconds. Any ideas as to why this might be so slow?
Here's some of the code, I can post more if needed:
%% setting up the basis functions, storing them in cell array
basisFunctions = cell(nu, 1); %nu is #unknowns
i = 1;
for j = 2:length(yc) - 1
for k = 2:length(xc) - 1
basisFunctions{i} = #(x,y) bilinearBasisFunction(x,y, xc(k-1), xc(k),...
xc(k+1), yc(j-1), yc(j), yc(j+1)); %my code for bilinear basis functions
i = i+1;
end
end
%% Assemble matrices and RHS
M = zeros(nu,nu);
S = zeros(nu,nu);
F = zeros(nu, 1);
for iE = 1:ne
for iBF = 1:nu
[z1, dx1, dy1] = basisFunctions{iBF}(qx(iE), qy(iE));
F(iBF) = F(iBF) + z1*forcing_handle(qx(iE),qy(iE))/ae(iE);
for jBF = 1:nu
[z2, dx2, dy2] = basisFunctions{jBF}(qx(iE), qy(iE));
%M(iBF,jBF) = M(iBF,jBF) + z1*z2/ae(iE);
S(iBF,jBF) = S(iBF, jBF) + (dx1*dx2 + dy1*dy2)/ae(iE);
end
end
end
Try to change basisFunctions from being a cell array to being a regular array.
You can also try to inline the direct call to bilinearBasisFunctionwithin your jBF loop, rather than using basisFunctions. Creating and later using anonymous functions in Matlab is always slower than directly using the target function. The code may be slightly more verbose this way, but will be faster.

How can I plot data to a “best fit” cos² graph in Matlab?

I’m currently a Physics student and for several weeks have been compiling data related to ‘Quantum Entanglement’. I’ve now got to a point where I have to plot my data (which should resemble a cos² graph - and does) to a sort of “best fit” cos² graph. The lab script says the following:
A more precise determination of the visibility V (this is basically how 'clean' the data is) follows from the best fit to the measured data using the function:
f(b) = A/2[1-Vsin(b-b(center)/P)]
Granted this probably doesn’t mean much out of context, but essentially A is the amplitude, b is an angle and P is the periodicity. Hence this is also a “wave” like the experimental data I have found.
From this I understand, as previously mentioned, I am making a “best fit” curve. However, I have been told that this isn’t possible with Excel and that the best approach is Matlab.
I know intermediate JavaScript but do not know Matlab and was hoping for some direction.
Is there a tutorial I can read for this? Is it possible for someone to go through it with me? I really have no idea what it entails, so any feed back would be greatly appreciated.
Thanks a lot!
Initial steps
I guess we should begin by getting a representation in Matlab of the function that you're trying to model. A direct translation of your formula looks like this:
function y = targetfunction(A,V,P,bc,b)
y = (A/2) * (1 - V * sin((b-bc) / P));
end
Getting hold of the data
My next step is going to be to generate some data to work with (you'll use your own data, naturally). So here's a function that generates some noisy data. Notice that I've supplied some values for the parameters.
function [y b] = generateData(npoints,noise)
A = 2;
V = 1;
P = 0.7;
bc = 0;
b = 2 * pi * rand(npoints,1);
y = targetfunction(A,V,P,bc,b) + noise * randn(npoints,1);
end
The function rand generates random points on the interval [0,1], and I multiplied those by 2*pi to get points randomly on the interval [0, 2*pi]. I then applied the target function at those points, and added a bit of noise (the function randn generates normally distributed random variables).
Fitting parameters
The most complicated function is the one that fits a model to your data. For this I use the function fminunc, which does unconstrained minimization. The routine looks like this:
function [A V P bc] = bestfit(y,b)
x0(1) = 1; %# A
x0(2) = 1; %# V
x0(3) = 0.5; %# P
x0(4) = 0; %# bc
f = #(x) norm(y - targetfunction(x(1),x(2),x(3),x(4),b));
x = fminunc(f,x0);
A = x(1);
V = x(2);
P = x(3);
bc = x(4);
end
Let's go through line by line. First, I define the function f that I want to minimize. This isn't too hard. To minimize a function in Matlab, it needs to take a single vector as a parameter. Therefore we have to pack our four parameters into a vector, which I do in the first four lines. I used values that are close, but not the same, as the ones that I used to generate the data.
Then I define the function I want to minimize. It takes a single argument x, which it unpacks and feeds to the targetfunction, along with the points b in our dataset. Hopefully these are close to y. We measure how far they are from y by subtracting from y and applying the function norm, which squares every component, adds them up and takes the square root (i.e. it computes the root mean square error).
Then I call fminunc with our function to be minimized, and the initial guess for the parameters. This uses an internal routine to find the closest match for each of the parameters, and returns them in the vector x.
Finally, I unpack the parameters from the vector x.
Putting it all together
We now have all the components we need, so we just want one final function to tie them together. Here it is:
function master
%# Generate some data (you should read in your own data here)
[f b] = generateData(1000,1);
%# Find the best fitting parameters
[A V P bc] = bestfit(f,b);
%# Print them to the screen
fprintf('A = %f\n',A)
fprintf('V = %f\n',V)
fprintf('P = %f\n',P)
fprintf('bc = %f\n',bc)
%# Make plots of the data and the function we have fitted
plot(b,f,'.');
hold on
plot(sort(b),targetfunction(A,V,P,bc,sort(b)),'r','LineWidth',2)
end
If I run this function, I see this being printed to the screen:
>> master
Local minimum found.
Optimization completed because the size of the gradient is less than
the default value of the function tolerance.
A = 1.991727
V = 0.979819
P = 0.695265
bc = 0.067431
And the following plot appears:
That fit looks good enough to me. Let me know if you have any questions about anything I've done here.
I am a bit surprised as you mention f(a) and your function does not contain an a, but in general, suppose you want to plot f(x) = cos(x)^2
First determine for which values of x you want to make a plot, for example
xmin = 0;
stepsize = 1/100;
xmax = 6.5;
x = xmin:stepsize:xmax;
y = cos(x).^2;
plot(x,y)
However, note that this approach works just as well in excel, you just have to do some work to get your x values and function in the right cells.

Tabulated values's management in MATLAB

I have to build a function from tabulated values (two columns) which are written in a text file. The process to make it is the following:
Use the command importdata to read the data file
Xp = importdata('Xp.dat','\t',1);
Store each column in a variable
x = Xp(1:18304,1);
y = Xp(1:18304,2);
Make a curve fitting with both variables
ft = fittype('linearinterp');
datos.f_Xp = fit(x,y,ft);
However, when I am profiling the code I have found out that my bottleneck are the built-in functions fittype.fittype, fittype.evaluate, cfit.feval, ppval and cfit.subsref
which are related to the curve fitting. So I ask myself how I should manage the tabulated values for improving my code.
you're trying to fit 18304 data points to a curve. Also, you're using linearinterp... which means a routine is being run in a piecewise fashion. if you want to make the code faster use less datapoints.
Or perhaps try:
ft = fittype('poly1');
Not sure is it will be the answer you need as I don't have access to the data
May be "Eval" function could work in your case,
some simple example :
A = '1+4'; eval(A)
ans =
5
P = 'pwd'; eval(P)
ans =
/home/myname
and a bit more advanced!
for n = 1:12
eval(['M',int2str(n),' = magic(n)'])
end
Also, it has a sister name "feval"
guess, what does it do !
[V,D] = feval('eig',A)
[V,D] = eig(A)
and here
function plotf(fun,x)
y = feval(fun,x);
plot(x,y)
You are right ! all are equivalent,
check out here and find more relevant function

block processing with multiple input matrices

I'm working in matlab processing images for steganography. In my work so far I have been working with block processing command blockproc to break the image up into blocks to work on it. I'm now looking to start working with two image, the secret and the cover, but i can't find anyway to use blockproc with two input matrices instead of one.
Would anyone knowof a way to do this?
blockproc allows you to iterate over a single image only, but doesn't stop you from operating on whatever data you would like. The signature of the user function takes as input a "block struct", which contains not only the data field (which is used in all the blockproc examples) but also several other fields, one of which is "location". You can use this to determine "where you are" in your input image and to determine what other data you need to operate on that block.
for example, here's how you could do element-wise multiplication on 2 same-size images. This is a pretty clunky example but just here to demonstrate how this could look:
im1 = rand(100);
im2 = rand(100);
fun = #(bs) bs.data .* ...
im2(bs.location(1):bs.location(1)+9,bs.location(2):bs.location(2)+9);
im3 = blockproc(im1,[10 10],fun);
im4 = im1 .* im2;
isequal(im3,im4)
Using the "location" field of the block struct you can figure out the appropriate parts of a 2nd, 3rd, 4th, etc. data set you need for that particular block.
hope this helps!
-brendan
I was struggling with the same thing recently and solved it by combining both my input matrices into a single 3D matrix as follows. The commented out lines were my original code, prior to introducing block processing to it. The other problem I had was using variables other than the image matrix in the function: I had to do that part of the calculation first. If someone can simplify it please let me know!
%%LAB1 - L*a*b nearest neighbour classification
%distance_FG = ((A-FG_A).^2 + (B-FG_B).^2).^0.5;
%distance_BG = ((A-BG_A).^2 + (B-BG_B).^2).^0.5;
distAB = #(bs) ((bs.data(:,:,1)).^2 + (bs.data(:,:,2)).^2).^0.5;
AB = A - FG_A; AB(:,:,2) = B - FG_B;
distance_FG = blockproc(AB, [1000, 1000], distAB);
clear AB
AB = A - BG_A; AB(:,:,2) = B - BG_B;
distance_BG = blockproc(AB, [1000, 1000], distAB);
clear AB
I assume the solution to your problem lies in creating a new matrix that contains both input matrices.
e.g. A(:,:,1) = I1; A(:,:,2) = I2;
Now you can use blockproc on A.