Find element in an array (matlab) with defined position (of time array) - arrays

I have one array that depends on another (i.e. I have the array of the tension (V) in function of the array of the time). I'd like to find the position of an element of the array of the tension at a particular moment of time (i.e. corresponding to a particular position of the time vector). How can I do that?
I have tried the following:
VMpzt = max(V);
%find the maximum value of the array of tensions
idxV = find(V == VMpzt);
%find the corresponding index
idxt = t(idxV);
%find the corresponding index of time vector
diff = 0.0048377328;
idxt2 = idxt-diff;
%in fact, I am interested at the index of time that corresponds to this particular position
Vmpzt = V(idxt2); %find the corresponding position of V array
doing so, I get the error
"Array indices must be positive integers or logical values."

idxt = t(idxV); %find the corresponding index of time vector
This line does not do what your comment suggests. It find the time at that index, not the index. You then subtract diff from it and try use it as an index but it isn't an index, it's a time. I think your variable names confused you. Try this:
[V_max, V_max_index] = max(V);
t_at_v_max = t(V_max_index); %find the TIME where V was max
diff = 0.0048377328;
t_desired = t_at_v_max - diff;
You now want the index where t equals t_desired. Because you are dealing with floating point numbers you can't just do find(t==t_desired) so instead we need to do this:
t_desired_index = find(abs(t-t_desired) < diff/1000); %1000 chosen arbitrarily, you might need to change it
and finally:
Vmpzt = V(t_desired_index );

Related

How to select values in an array until a threshold value?

I will explain my problem. I have a 1x1701 sampled array "resampled_WF", once I found the max value of this array ("peak_WF"), I set a threshold 0.7*peak_WF, and I would like to select the farthest value in the array that gets nearer to this threshold.
Example:
power_vs_time_threshold
As you can see, I was able to select ony the first value that resembles... but I would like to get the last one (around t=2 sec).
I tried to flip the array with "flip" function:
WF_threshold_input = 0.7*peak_WF;
flip_resampled_WF = flip(resampled_WF);
diff_peak_threshold = peak_WF - WF_threshold_input; %power loss at 70% power reduction
diff_peak_WF = peak_WF - flip_resampled_WF;
min_diff_threshold = min(abs(diff_peak_WF-diff_peak_threshold));
Doing that, MATLAB computes minimum difference on the whole array, I would like to stop at the first value, not considering further values.
I tried to select values with values <= WF_threshold_input, but again it selects over the whole dataset.
How can I select the value properly?
Thanks!!
Using operations on the matrix will call the operation on every element in the matrix. What you want to do is use a loop so that you can control exactly what elements are examined and then break out of the loop.
index = length(resampled_WF);
your_threshold = ...
while resampled_WF(index) < your_threshold
index = index - 1;
end
The while loop will continue iteration until it reaches a value that is outside of your defined threshold.
After execution, the value of index will be the index of the furthest value in the array which is outside of your threshold. You can access the furthest value outside the threshold by looking at resampled_wf(index) after execution of the code.
We don't have to worry about the values of index leaving the bounds of the array, ie <1, since the condition resampled_wf < your_threshold is guaranteed to be met by the maximal value that you originally generated the threshold with.

How to find the index value of the quartile values in an array using Matlab?

I have a vector of dimension 1x3000. I have found the percentile value using the percentile function in Matlab. But I am unable to find the index value of the quartile inside the vector.
y = rand(1,3000);
Q_2 = prctile(y,50);
Idx = find(y==Q_2);
Idx is returning an empty value. I should be able to get a value of the index containing the median value.
You can efficiently find the entry closest to the median (or an arbitrary q_2 for that matter) with:
[~,Idx]=min(abs(q_2-y));
As per help min, the value returned as Idx corresponds to the first element with the minimum value in the vector of differences.

Matrix - Vector value matching

In my current project, I need to find values inside of an matrix that match with individual vector values. This is an example of the process; the main program has me using lat and lon values. But I create a 20x20 matrix and then a 20x1 array of randomly placed values.
When i do the for loop, each iteration of the Leroy vector is subtracted from every value in matrix. The first min function should return the smallest value from each column and its correspoding index. The second min function should return the smallest overall value from the first min function. and which index had the smallest value.
My concern is that im not sure which integer inside the matrix returned the smallest value. Is there a way I can use the indexes or something to figure that out?
Matrix = magic(20);
Leroy = randi(20,20,1);
for i = 1:length(Leroy)
[Jenkins, J] = min(min(Leroy(i) - Matrix);
end
As Cris Luego pointed in his comment, your for loop is not required since
Leroy(i) - Matrix
translates to something like
5 - [1 2 3; 4 5 6; 7 8 9]
However, your problem to get the index of the minimum in -Matrix can be solved by using min(-Matrix(:)):
[minimum, minidx] = min(-Matrix(:));
However, you will get the linear index. If you need the index for row and column, use
[colidx,rowidx] = ind2sub(size(Matrix), minidx);
Matrix = magic(20);
Leroy = randi(20,20,1);
for i = 1:length(Leroy)
[Jenkins, J] = min((Leroy(i) - Matrix).^2);
end
Using this will help get a match between two values in two arrays or a match between array values and matrix values

Comparing two arrays of pixel values, and store any matches

I want to compare the pixel values of two images, which I have stored in arrays.
Suppose the arrays are A and B. I want to compare the elements one by one, and if A[l] == B[k], then I want to store the match as a key value-pair in a third array, C, like so: C[l] = k.
Since the arrays are naturally quite large, the solution needs to finish within a reasonable amount of time (minutes) on a Core 2 Duo system.
This seems to work in under a second for 1024*720 matrices:
A = randi(255,737280,1);
B = randi(255,737280,1);
C = zeros(size(A));
[b_vals, b_inds] = unique(B,'first');
for l = 1:numel(b_vals)
C(A == b_vals(l)) = b_inds(l);
end
First we find the unique values of B and the indices of the first occurrences of these values.
[b_vals, b_inds] = unique(B,'first');
We know that there can be no more than 256 unique values in a uint8 array, so we've reduced our loop from 1024*720 iterations to just 256 iterations.
We also know that for each occurrence of a particular value, say 209, in A, those locations in C will all have the same value: the location of the first occurrence of 209 in B, so we can set all of them at once. First we get locations of all of the occurrences of b_vals(l) in A:
A == b_vals(l)
then use that mask as a logical index into C.
C(A == b_vals(l))
All of these values will be equal to the corresponding index in B:
C(A == b_vals(l)) = b_inds(l);
Here is the updated code to consider all of the indices of a value in B (or at least as many as are necessary). If there are more occurrences of a value in A than in B, the indices wrap.
A = randi(255,737280,1);
B = randi(255,737280,1);
C = zeros(size(A));
b_vals = unique(B);
for l = 1:numel(b_vals)
b_inds = find(B==b_vals(l)); %// find the indices of each unique value in B
a_inds = find(A==b_vals(l)); %// find the indices of each unique value in A
%// in case the length of a_inds is greater than the length of b_inds
%// duplicate b_inds until it is larger (or equal)
b_inds = repmat(b_inds,[ceil(numel(a_inds)/numel(b_inds)),1]);
%// truncate b_inds to be the same length as a_inds (if necessary) and
%// put b_inds into the proper places in C
C(a_inds) = b_inds(1:numel(a_inds));
end
I haven't fully tested this code, but from my small samples it seems to work properly and on the full-size case, it only takes about twice as long as the previous code, or less than 2 seconds on my machine.
So, if I understand your question correctly, you want for each value of l=1:length(A) the (first) index k into B so that A(l) == B(k). Then:
C = arrayfun(#(val) find(B==val, 1, 'first'), A)
could give you your solution, as long as you're sure that every element will have a match. The above solution would fail otherwise, complaning that the function returned a non-scalar (because find would return [] if no match is found). You have two options:
Using a cell array to store the result instead of a numeric array. You would need to call arrayfun with 'UniformOutput', false at the end. Then, the values of A without matches in B would be those for which isempty(C{i}) is true.
Providing a default value for an index into A with no matches in B (e.g. 0 or NaN). I'm not sure about this one, but I think that you would need to add 'ErrorHandler', #(~,~) NaN to the arrayfun call. The error handler is a function that gets called when the function passed to arrayfun fails, and may either rethrow the error or compute a substitute value. Thus the #(~,~) NaN. I am not sure that it would work, however, since in this case the error is in arrayfun and not in the passed function, but you can try it.
If you have the images in arrays A & B
idx = A == B;
C = zeros(size(A));
C(idx) = A(idx);

Matlab Assigning Elements to Array in loop

I have this loop which generates a vector "Diff". How do I place the values of Diff in an array that records all the Diff's generated? The problem is that the length of Diff should be a fixed length (36) which is the width of the table "CleanPrice". But because col_set varies in length (according to the number of NaNs in the data it is reading), then Diff also varies in length. What I need it to do is assign the answers generated according to their appropriate column number. i.e. row(i) of diff should contain col(i) where all other rows in Diff should be assigned a "0" or "NaN". Basically I need DiffArray to be a (nTrials x 36) array where each row is the (36 x 1) DiffArray generated. At the moment though, each time the length of col changes, I get the following error:
??? Subscripted assignment dimension mismatch.
Error in ==> NSSmodel
at 41 DiffMatrix(end+1,:)=Diff
This is my code:
DiffArray=[];
StartRow=2935;
EndRow=2940;
nTrials=EndRow-StartRow;
for row=StartRow:EndRow;
col_set=find(~isnan(gcm3.data.CleanPrice(row,1:end)));
col=col_set(:,2:end);
CleanPrices=transpose(gcm3.data.CleanPrice(row,col));
Maturity=gcm3.data.CouponandMaturity(col-1,2);
SettleDate=gcm3.data.CouponandMaturity(row,3);
Settle = repmat(SettleDate,[length(Maturity) 1]);
CleanPrices =transpose(gcm3.data.CleanPrice(row,col));
CouponRate = gcm3.data.CouponandMaturity(col-1,1);
Instruments = [Settle Maturity CleanPrices CouponRate];
PlottingPoints = gcm3.data.CouponandMaturity(1,2):gcm3.data.CouponandMaturity(36,2);
Yield = bndyield(CleanPrices,CouponRate,Settle,Maturity);
SvenssonModel = IRFunctionCurve.fitSvensson('Zero',SettleDate,Instruments)
ParYield=SvenssonModel.getParYields(Maturity);
[PriceActual, AccruedIntActual] = bndprice(Yield, CouponRate, Settle, Maturity);
[PriceNSS, AccruedIntNSS] = bndprice(ParYield, CouponRate, Settle, Maturity);
Diff=PriceActual-PriceNSS
DiffArray(end+1,:)=Diff
end
I looked at num2cell in this post but wasn't sure how to apply it correctly and started getting errors relating to that instead.
Is it correct to say you want to add an 'incomplete' row to DiffArray? If you know exactly where each element should go you could maybe do something like this:
indices = [1:7; 2:8; 3:9; [1 2 3 6 7 8 10]];
Diff = rand(4, 7);
DiffArray = zeros(4, 10) * NaN;
for row = 1:4
DiffArray(row, indices(row, :)) = Diff(row,:);
end
of course in your case you would be calculating Diff and Index (a row vector) inside the loop and not using preassigned arrays. The above is just to illustrate how to use an indexing vector to position a short row in a matrix.

Resources