Matlab find the maximum and minimum value for each point of series of arrays (with negative values) - matlab

lets say that we have the next series of arrays:
A = [1, 2, -2, -24];
B = [1, 4, -7, -2];
C = [3, 1, -7, -14];
D = [11, 4, -7, -1];
E = [1, 2, -3, -4];
F = [5, 14, -17, -12];
I would like to create two arrays,
the first will be the maximum of each column for all arrays,
i.e.
Maxi = [11,14,-2 -1];
the second will be the minimum of each column for all arrays
i.e.
Mini= [1,1,-17 -24];
I am trying all day, using loops, with max, and abs but I cant make it work
in my problem have a matrix (100,200), so with the above example i am trying to easily approach the problem. The ultimate goal is to get a kinda fitting of the 100 y_lines of 200 x_points. The idea is to calculate two lines (i.e. max,min), that will be the "visual" boarders of all lines (maximum and minimum values for each x). The next step will be to calculate an array of the average of these two arrays, so in the end will be a line between all lines.
any help is more than welcome!

How about this?
Suppose you stack all the row vectors , namely A,B...,F as
arr=[A;B;C;D;E;F];% stack the vectors
And then use the max(), min() and mean() functions provided by Matlab. That is,
Maxi = max(arr); % Maxi is a row vector carrying the max of each column of arr
Mini = min(arr);
Meani = mean(arr);
You just have to stack them as shown above. But if you have 100s of row vectors, use a loop to stack them into array arr as shown above.

Related

How can I find each max element of three matrices as new matrix?

Maybe the question is a little bit confused, I'll make an example below.
Let's say I have a 3 matrices a, b, c with same size.
a = [2, 5; 6, 9];
b = [3, 3; 8, 1];
c = [5, 5; 2, 7];
How can I get the new matrix max with each max element in all three matrices?
max = [5, 5; 8, 9]
I know I could create logical matrix like a>b and then do the math, calc it out, is there any other more efficient way to do it?
You can concatenate the matrices into one 2x2x3 matrix using
d=cat(3,a,b,c)
and then use max-function to get your desired output:
maxValues=max(d,[],3)
The 3rd input to max defines along which dimension of the first input you want to find the maximum value.

Add and remove element of vector at specific position

Let X = [1, 2, 3, 4, 5] and Y = [1, 2, 1, 0, 1] be vectors where X maps into Y.
Now I want to identify the maximum and minimum of Y, which is easy: [value_min, id_min] = min(Y) = [0, 4] and [value_max, id_max] = max(Y) = [2, 2].
Then I want to remove the element from X corresponding to the minimum in Y and expand evenly around the element in X corresponding to the maximum in Y, while keeping the number of points equal. For this example we remove X(4)=[]. Then we expand like X(2)=(X(2) - X(1))/2 and X(3)=(X(3) - X(2))/2 such that X looks like X = [1, 1.5, 2.5, 3, 5]. How can I achieve this? I think there is a general pattwern.
Solution
Now the following snipped should work for any vector of length N. Note that the first and final element are fixed.
[value_max, id_max] = max(Y(2:N-1));
X(id_max) = (X(id_max) - X(id_max-1))/2;
X(id_max+1) = (X(id_max+1) - X(id_max))/2;
[value_min, id_min] = min(Y(2:N-1));
X(id_min)=[];
Here is a solution to your problem but there are a few things you should take care of
% Any Vector should work
X=[1 2 3 4 5];
Y=[1 2 1 0 1];
%We dont need the actual min max
[~,MIN]=min(Y(2:end-1));
[~,MAX]=max(Y(2:end-1));
%you dont look at the first element so the index has to be increased by 1
MIN=MIN+1;
MAX=MAX+1;
X(MIN)=[];%taking out the smallest element
Xnew= [X(1:MAX) X(MAX:end)]; %Extend the vector by taking the MAX value twice
%the mean for 2 elements is A+B/2
Xnew(MAX)=mean(Xnew(MAX-1:MAX)); %the left one and the element next to it
Xnew(MAX+1)=mean(Xnew(MAX+1:MAX+2)); %the right one and the element next ot it
%rewrite X and clear Xnew
X=Xnew;
clear Xnew;
First of all this isnt very efficient, but if its just used to
modify some vectors and not get called a million times a day it will
do the trick.
In your text you say remove the minima then stretch
around the maxima, in your solution metacode it is the other way
around. this will influence the outcome when min and max are next to
each other, so please check which way you prefer.
Y isnt changed in this at all so it cant be performed multiple times on the same vector.
Is N (the length) of any importance later on? if not you can always just refer to "end"

MATLAB: scan the row of a matrix and use values to search another matrix

I have matrix X and A where
X = [x1, y1, 1, 1; x2, y2, 1, 3; x3, y, 2, 4]
A = [1, 1, 0; 1, 3, 1; 1, 4, 2]
I want to:
1. scan the last two columns for every row in X (FYI, these two number combinations are unique)
2. find those values in the first two columns of A
3. get the value of the last column in that row of A.
For example, for the first row of X, I get 1 and 1, so I find 1 and 1 for the first two columns in A (which appears to be the first row), so the number I want to get is 0.
I think I can do it using a loop and a "find" function if it were just one number I'm working with, but I'm new to matlab and have trouble with a combination of two numbers. I would appreciate your help!
The ismember function may be what you're looking for, along with the () and : operators to extract columns from an array.
% Map rows in X to rows in A
[tf,loc] = ismember(X(:,[3 4]), A(:,[1 2]), 'rows');
% Grab the corresponding value from A
rslt = A(loc, 3);
Now you have a logical vector tf that indicates for each row in X whether it was found in A, and loc, which holds the corresponding indexes in to the rows of A for the ones that matched. Then you use those indexes to index in to A to pull out the "value" or dependent variable columns. These are vectorized operations, so it'll be faster than doing it with loops and find().
Read through the documentation for ismember, unique, paren, and the functions they reference to get more background on Matlab's functions for doing recordwise searching like this.

How to get a regular sampled matrix in Scilab

I'm trying to program a function (or even better it it already exists) in scilab that calculates a regular timed samples of values.
IE: I have a vector 'values' which contains the value of a signal at different times. This times are in the vector 'times'. So at time times(N), the signal has value values(N).
At the moment the times are not regular, so the variable 'times' and 'values' can look like:
times = [0, 2, 6, 8, 14]
values= [5, 9, 10, 1, 6]
This represents that the signal had value 5 from second 0 to second 2. Value 9 from second 2 to second 6, etc.
Therefore, if I want to calculate the signal average value I can not just calculate the average of vector 'values'. This is because for example the signal can be for a long time with the same value, but there will be only one value in the vector.
One option is to take the deltaT to calculate the media, but I will also need to perform other calculations:average, etc.
Other option is to create a function that given a deltaT, samples the time and values vectors to produce an equally spaced time vector and corresponding values. For example, with deltaT=2 and the previous vectors,
[sampledTime, sampledValues] = regularSample(times, values, 2)
sampledTime = [0, 2, 4, 6, 8, 10, 12, 14]
sampledValues = [5, 9, 9, 10, 1, 1, 1, 6]
This is easy if deltaT is small enough to fit exactly with all the times. If the deltaT is bigger, then the average of values or some approximation must be done...
Is there anything already done in Scilab?
How can this function be programmed?
Thanks a lot!
PS: I don't know if this is the correct forum to post scilab questions, so any pointer would also be useful.
If you like to implement it yourself, you can use a weighted sum.
times = [0, 2, 6, 8, 14]
values = [5, 9, 10, 1, 6]
weightedSum = 0
highestIndex = length(times)
for i=1:(highestIndex-1)
// Get the amount of time a certain value contributed
deltaTime = times(i+1) - times(i);
// Add the weighted amount to the total weighted sum
weightedSum = weightedSum + deltaTime * values(i);
end
totalTimeDelta = times($) - times(1);
average = weightedSum / totalTimeDelta
printf( "Result is %f", average )
Or If you want to use functionally the same, but less readable code
timeDeltas = diff(times)
sum(timeDeltas.*values(1:$-1))/sum(timeDeltas)

Dimension Mismatch MatLab; cant figure out why it is mismatching

I think it may be a syntax issue, here is the code.
load ([ 'C:\Users\Abid\Desktop\Inquiry Runs\dtS' ])
dtS((dtS==0))=nan;
for j=2:9;
maxS=max(dtS(j,:));
minS=min(dtS(j,:));
maxval(j,:)=dtS((dtS>(maxS-.1*maxS)));
minval(j,:)=dtS((dtS<(minS+.1*minS)));
avmax(j)=mean(maxval(j,:));
avmin(j)=mean(minval(j,:));
avs(j,:)=[avmax(j) avmin(j)]
end
So I know the the row matrices are different sizes every loop. For example maxval(j,:) will change depending one row it is looking through for certain values.
I did this manually and I see that on the first loop the matrices are size (1,1), however, if I set the loop to run for only j=2, the row length is 13.
Usually if a matrix is changing size on the loop, I only get a warning, but this time I think it is due to a reason I don't understand.
You are right that the problem is with maxval(j, :) being a different size. length(maxval(j, :)) is not length(dtS((dtS>(maxS-.1*maxS)))); this causes a problem since maxval has to be 'rectangular', but if it were extended by this line of code, some of its values would not be defined. Consider:
x = [1, 2; 3, 4];
x(3, :) = [5, 6, 7];
If this code were legal, the result would be:
x: [1, 2, ?;
3, 4, ?;
5, 6, 7]
and because of those undefined values, matlab will not let you do this. You could use a cell array instead:
maxval = cell(9, 1);
avmax = zeros(9, 1);
avs = zeros(9, 2);
for j=2:9;
maxS=max(dtS(j,:));
minS=min(dtS(j,:));
maxval{j} = dtS((dtS>(maxS-.1*maxS)));
minval{j} = dtS((dtS<(minS+.1*minS)));
avmax(j)=mean(maxval{j});
avmin(j)=mean(minval{j});
avs(j,:)=[avmax(j) avmin(j)]
end