I\'m doing video analysis.
The end result array I get is something like:
signal =
Columns 1 through 7
73960 73960 73960 73
This VBA
Sub NewGraph()
Dim X
Dim Y
Dim lngRow As Long
Dim lngCnt As Long
Dim Chr As ChartObject
X = Range([a1], Cells(Rows.Count, "b").End(xlUp))
Y = Application.Transpose(X)
For lngRow = 2 To UBound(X, 1) - 1
If X(lngRow, 2) > X(lngRow - 1, 2) Then
If X(lngRow, 2) > X(lngRow + 1, 2) Then
lngCnt = lngCnt + 1
Y(1, lngCnt) = X(lngRow, 1)
Y(2, lngCnt) = X(lngRow, 2)
End If
Else
If X(lngRow, 2) < X(lngRow + 1, 2) Then
lngCnt = lngCnt + 1
Y(1, lngCnt) = X(lngRow, 1)
Y(2, lngCnt) = X(lngRow, 2)
End If
End If
Next lngRow
ReDim Preserve Y(1 To 2, 1 To lngCnt)
Set Chr = ActiveSheet.ChartObjects.Add(250, 175, 275, 200)
With Chr.Chart
With .SeriesCollection.NewSeries
.XValues = Application.Index(Application.Transpose(Y), 0, 1)
.Values = Application.Index(Application.Transpose(Y), 0, 2)
End With
.ChartType = xlXYScatter
End With
End Sub
I would just write a simple loop over the array in Matlab to achieve this. I don't see any fundamental problems there?
If you don't want loops in Matlab, you can do it with some array operations. If you have two equallly long arrays a and b, you can do something like c = a>b, which gives you a list with ones and zeros. You1 can use this as a oneliner for selecting the maxima/minima.
Zo suppose you have an upshifted and downshifted array b, c. Such that (except at endpoints)
b(n-1)=a(n)=c(n+1). You can get an array containing only the extrema and zeros by q=a.*( (a>b).*(a>c) + (a<b).*(a<c) )
One advise: If you signal has noise, than also this selection will be noisy. To smoothen the function, you should apply some kind of moving averaging with a kernel you like.
If you want the maximum and minimum values just use:
[sig_min, idx_min] = min(signal);
[sig_max, idx_max] = max(signal);
But I couldnt understand exactly what you want… since my account is new, I cant comment on your question to try to understand it better.
— edit 1:
Ok, now I understand what you want. I don't know why you have this array with repetitive numbers, but supposing you don't want them, or, at least, that is better to remove them to find local maxima and minima, you should do:
sinal_norep = signal(find(diff(sinal)));
where signal_norep will be your new array containing only values that differs from the last one:
Now we can search for the index where occurs local maxima and minima on this array, by doing:
minimas_idx = find(signal_norep(2:end-1)<signal_norep(1:end-2) & signal_norep(2:end-1)<signal_norep(3:end))+1;
maximas_idx = find(signal_norep(2:end-1)>signal_norep(1:end-2) & signal_norep(2:end-1)>signal_norep(3:end))+1;
And their values:
signal_maximas = signal_norep(maximas_idx);
signal_minimas = signal_norep(minimas_idx);
Thats it x)