Simulink misses data points in a from-workspace block for discrete simulation - matlab

I have a simulation running at 50 Hz, and some data that comes in at 10 Hz. I have extra 'in-between' points with dummy data at the following 50 Hz time points, and interpolation set to off. This should in theory ensure that between 10 Hz time steps, the dummy data is being held and only at the 10 Hz steps is the actual data present. For example, my data vector would be
[0.0 0.8 0.1 0.12 0.2 0.22 0.3 0.32 0.4 0.42 0.5 0.52 ...
-1 -1 1 -1 2 -1 3 -1 4 -1 5 -1 ...]
However, with a scope attached directly from the 'from-workspace' block, simulink is returning this:
[0.0 0.8 0.1 0.12 0.2 0.22 0.3 0.32 0.34 0.4 0.42 0.5 0.52...
-1 -1 -1 -1 2 -1 3 3 -1 4 -1 5 5...]
where some values are skipped and others are repeated in a consistent pattern. Is there something with simulinks time-step algorithms that would cause this?
Edit: A solution I ended up finding was to offset the entire time vector by 1/100th of a second so that the sim was taking data between points rather than on points, and that seemed to fix it. Not ideal, but functional.

Related

Octave - why is surf not working but trisurf does?

I am able to plot a trisurf chart, but surf does not work.
What am I doing wrong?
pkg load statistics;
figure (1,'name','Matrix Map');
colormap('hot');
t = dlmread('C:\Map3D.csv');
tx =t(:,1);ty=t(:,2);tz=t(:,3);
tri = delaunay(tx,ty);
handle = surf(tx,ty,tz); #This does NOT work
#handle = trisurf(tri,tx,ty,tz); #This does work
`error: surface: rows (Z) must be the same as length (Y) and columns (Z) must be the same as length
(X)
My data is in a CSV (commas not shown here)
1 2 -0.32
2 2 0.33
3 2 0.39
4 2 0.09
5 2 0.14
1 2.5 -0.19
2 2.5 0.13
3 2.5 0.15
4 2.5 0.24
5 2.5 0.33
1 3 0.06
2 3 0.44
3 3 0.36
4 3 0.45
5 3 0.51
1 3.5 0.72
2 3.5 0.79
3 3.5 0.98
4 3.5 0.47
5 3.5 0.55
1 4 0.61
2 4 0.13
3 4 0.44
4 4 0.47
5 4 0.58
1 4.5 0.85
surf error message is different in Matlab or in Octave.
Error message from Matlab:
Z must be a matrix, not a scalar or vector.
The problem is pretty clear here since you specified Z (for you tz) as a vector.
Error message from Octave:
surface: rows (Z) must be the same as length (Y) and columns (Z) must be the same as length (X)
You are wrong here since on your example, columns (Z) = 1, but length (X) = 26, so here is the mistake.
One of the consequences of that is that with surf you cannot have "holes" or undefined points on your grid. On your case you have a X-grid from 1 to 5 and a Y-grid from 2 to 4.5 but point of coordinate (2, 4.5) is not defined.
#Luis Mendo, Matlab and Octave do allow the prototype surf(matrix_x, matrix_y, matrix_z) but the third argument matrix_z still have to be a matrix (not a scalar or vector). Apparently, a matrix of only one line or column is not considered as a matrix.
To solve the issue, I suggest something like:
tx = 1:5; % tx is a vector of length 5
ty = 2:0.5:4.5; % ty is a vector of length 6
tz = [-0.32 0.33 0.39 0.09 0.14;
-0.19 0.13 0.15 0.24 0.33;
0.06 0.44 0.36 0.45 0.51;
0.72 0.79 0.98 0.47 0.55;
0.61 0.13 0.44 0.47 0.58;
0.85 0. 0. 0. 0.]; % tz is a matrix of size 6*5
surf(tx,ty,tz);
Note that I had to invent some values at the points where your grid was not defined, I put 0. but you can change it with the value you prefer.

How can I find the average of largest set of non-zero values in an array

How can I find the the starting point of A array and calculate average starting from starting points to 1 second
A=[0 0 0 0 0 -0.01 -0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.01 0.02 0.03 0.04 0.1 0.2 0.3 0.4 0.7 0.8 1 1.2 1.3 1.4 1.5]
Time=[0 0.1 .2 .3 .4 .5 .6 .7 .8 .9 1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.8 3 3.1]
By removing the noise the starting point should be A(17) which is equal to 0.01
Then calculate average of A starting from starting point after 1 seconds
Code is self explanatory
A=[0 0 0 0 0 -0.01 -0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.01 0.02 0.03 0.04 0.1 0.2 0.3 0.4 0.7 0.8 1 1.2 1.3 1.4 1.5] ;
Time=[0 0.1 .2 .3 .4 .5 .6 .7 .8 .9 1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.8 3 3.1];
%make negative values zero
A(A<0)=0;
%get non negative values position and add padding
mask=[0,A>0,0];
%get starting points
startingPoints =strfind(mask,[0 1]);
%get length of continuous values from starting points
temp =diff(find(~mask))-1;
length = temp(temp>0);
%get the index of largest length
[~,index]=max(length);
%get starting point
dataStartingIndex = startingPoints(index)
%starting point value
A(dataStartingIndex)
%get ending point after 1 seconds
dataEndingIndex=find((Time(dataStartingIndex)+1)==Time);
%find average
avg=mean(A(dataStartingIndex:dataEndingIndex))
This really depends on your data. It is a bit unclear but in your example it seems that noise can exceed your 'information value'. So you can't detect it just with a threshold.
Maybe get the position where A is always superior to something like 0.01 :
startpos= (A>0).argmax()
truedata=A[startpos:]
time=T[startpos:]
you can calculate average with the method .mean()

Is it possible to filter a matrix by a tagged array?

I have a 10 dimensional matrix with many, many columns (in the hundreds of thousands). I have however, implemented a tag based on the day of an experiment and a condition
So my original matrix looks something like
0.1 0.25 0.64 0.15 0.1 0.96 0.01 0.05....
.
.
.
.
0.2 0.3 0.049 0 0.3 0.71 0.4 0.45....
I was able to implement a tag for the day and experiment type so my matrix looks like
0.1 0.25 0.64 0.15 0.1 0.96 0.01 0.05....
.
.
.
.
0.2 0.3 0.049 0 0.3 0.71 0.4 0.45....
1 1 1 1 2 2 2 2
1 1 2 2 2 3 3 3
The top row represents a day, and the bottom row represents a condition. Is there anyway to "filter" this matrix, call it A, by day and condition in MATLAB? So for example, if I want the day 1 condition 2 "mini-matrix", I can get
0.64 0.15
.
.
.
0.049 0
Yes, you can do this by accessing only the columns matching a certain value in your day or condition rows.
For example, say your input matrix is A, and that the entries in the third row A(3,:) are the days, and the entries in the fourth row A(4,:) are the conditions.
Then A(:, A(3,:) == 2) will give you the subset of columns in A where the day is 2.
And A(:, A(3,:) == 2 & A(4,:) == 1) will give you the columns where the day is 2 and the condition is 1.

Draw network or graph from matrix in matlab

How do I draw a sequence of frames of a network with the help of a transition matrix?
I have a matrix that denotes a graph. The matrix changes with iterations. Can anyone give me an insight of what functions I can use to create the series of the network?
original=[0.06 0.57 0.37 0 0;
0.57 0.06 0.37 0 0;
0.37 0.57 0.03 0.03 0;
0 0 0.03 0.13 0.84;
0 0 0 0.84 0.16];
Suppose the, above is the matrix in question. Then the graph should be
This question is related to this earlier query and this one. But here's an answer specific to your situation.
Given a weighted adjacency matrix:
original = [0.06 0.57 0.37 0 0;
0.57 0.06 0.37 0 0;
0.37 0.57 0.03 0.03 0;
0 0 0.03 0.13 0.84;
0 0 0 0.84 0.16];
you can first define the number of nodes in the network:
N = size(original,1);
and then a corresponding set of coordinates on the perimeter of a circle:
coords = [cos(2*pi*(1:N)/N); sin(2*pi*(1:N)/N)]';
Then you can plot the graph using gplot:
gplot(original, coords)
and mark the vertices using text:
text(coords(:,1) - 0.1, coords(:,2) + 0.1, num2str((1:N)'), 'FontSize', 14)
Note that the gplot function does not weight the lines by connection strength; the matrix element (i,j) is treated as binary, indicating absence or presence of a link between nodes i and j.

Estimating two matrix using Hidden markov model toolbox in MATLAB

I am trying to apply Hidden Markov Model to improve my detection accuracy.
In my program, there are two states, 1 and 0. I used Bayes detector to generate the probability for each instance to be in class 1 and 0. For example, I have a sequence Actual states: 1 1 1 1 1 0 0 0 0 0
probability in class 1: 0.5 0.6 0.7 0.8 0.9 0.2 0.3 0.4 0.5 0.5
probability in class 0: 0.5 0.4 0.3 0.2 0.1 0.8 0.7 0.6 0.5 0.5
I tried to "use probability in class 1" as the "seq" and "Actual states" as "states" in function hmmestimate ([estimateTR, estimateE] = hmmestimate(seq,states);)
But it seems that "seq" must be integers, and I do not understand what is the requirement for the input arguments.
Thanks in advance!