Matlab min function and 'lt' operator - matlab

I'm using min function to find minimum value in Complex Double array and set return value to slider Min property.
when user change slider value, find values that little than slider value.
but min and lt operator return different result.
for example looks below code.
array=[-5.61160893699794 + 1.29692613840634i , -0.000211300000000000 - 1.85290000000000e-06i; -1.91125106282203 + 1.60401019880518i,-0.768982324325300 + 0.732360902857864i]
vmin=min(min(array));
res=array(array<vmin);
result:
vmin= -2.1130e-04 - 1.8529e-06i
res= -5.6116 + 1.2969i
-1.9113 + 1.6040i
-0.7690 + 0.7324i

According to the MATLAB documentation:
min
When X is complex, the minimum is computed using the magnitude
min(ABS(X)). In the case of equal magnitude elements, then the phase
angle min(ANGLE(X)) is used.
lt
lt compares only the real part of the elements in A.
You can reproduce this behavior:
>> 1 < -2i
ans = 0
>> min([1,-2i])
ans = 1

The expression array < vmin creates the logical array:
>> array < vmin
ans =
1 0
1 1
where the 1s indicate that those elements of array have a real part that is less than the minimum value's real part.
And when you use that logical output as a logical index like array(array<vmin), the output is a column vector of the elements of array that are true. So everything is working as it should.
If array were wrapped in abs, the resulting logical array would be all false:
>> abs(array) < vmin
ans =
0 0
0 0
which may be a more intuitive result.
I don't know if this is important, but I will note that the min function finds the value with the smallest magnitude (in absolute value) for complex entires while lt only tests the real part.

Related

how to compare all vector indexes with a constant value and switch the value of another variable (0 1) based on that

I have a 1x24 vector (a). I should define a command in Matlab which compare all 24 values of a vector (a) with a certain value (mean (b)) and if the vector (a) item is greater than certain value (mean (b)), ''I'' sets 1 and if the vector item is less than certain value ''I'' sets 0. I wrote the below code:
for i=1:length(a)
if a(i) >= mean(b)
I = 1;
else
I = 0;
end
end
But it implements the comparison only for the last index of vector a and sets I=0. How can I fix the command that do the comparison for all indexes of vector a?
In MATLAB, you can use the following syntax to do so:
I = a >= mean(b);
If you want to use your code for doing so, you'll need to initialize I as a vector, and modify its indices as follows:
I = zeros(length(a),1)
for ii=1:length(a)
if a(ii) >= mean(b)
I(ii) = 1;
else
I(ii) = 0;
end
end
You should read about logical indexing in matlab. You don't need for loops for what you are doing. For example, if you have,
rng(5);
a = rand(1,10);
b = 0.5;
then, I = a > b; will return a logical array with zeros and ones, where one indicates the position in the array where the given condition is satisfied,
I =
0 1 0 1 0 1 1 1 0 0
Using these indices, you can modify your original array. For example, if you wish to change all values of a greater than b to be 10, you would simply do,
a(a > b) = 10;
Specifically, if you need indices where the condition is satisfied, you can use, find(a > b), which in this example will give you,
ans =
2 4 6 7 8

Clean MATLAB time series data

I have a Matlab time series data set, which consist of a signal that can only be 1 or 0. How can I get rid of all the values except for the changing ones?
For example:
1
1
1
0
1
0
0
0
should ideally result in
1
0
1
0
while keeping the correct time values as well of course.
Thing is, that I need to find the frequency of the signal. The time should be measured from 0->1 to the next time 0->1 occurs. The smallest time / highest frequency is what I need in the end.
Thanks!
You can use the getsamples method to get a time series which contains a subset of the original samples. Remains to identify the indices where the time series has changed, for this purpose you can use diff and logical indexing:
ts = timeseries([1 1 1 0 1 0 0 0],1:8)
ts.getsamples([true;squeeze(diff(ts.Data)) ~= 0])
A simple and clever call to to diff should be sufficient:
>> A = [1; 1; 1; 0; 1; 0; 0; 0];
>> B = A(diff([-Inf; A]) ~= 0)
B =
1
0
1
0
The code is quite simple. diff finds pairs of differences in an array. Concretely, given an array A, the output is of the following structure:
B = [A(2) - A(1), A(3) - A(2), ..., A(N) - A(N-1)];
N is the total length of the signal. This results in a N-1 length signal. As such, a trick that you can use is to append the array A with -Inf (or some high non-zero value) so that when you find the difference between the first element of this appended array and the actual first element of the true array, you will get some non-zero change. That is registered with diff([-Inf; A]). The next thing you'll want is to check is to see where the differences are non-zero. Whenever there is a non-zero difference, that is a position that you want to keep because there has been a change that occurred. This produces a logical array and so the last step is to use this to index into your array A and thus get the result.
This only extracts out the signal you need however. If you'd like to extract the time in between unique elements, supposing you had some time vector t that was as long as your signal stored in A. You would first record the logical vector in a separate variable, then index into both your time array and the signal array to extract out what you need (original idea from user dfri):
ind = diff([-Inf; A]) ~= 0;
times = t(ind);
B = A(ind);
You can make use of diff and logical to save the results as a logical array, used as a subsequent index filter in your data (say t for time and y for boolean values ))
%// example
t = 0:0.01:0.07;
y = [1,1,1,0,1,0,0,0];
%// find indices to keep
keep = [true logical(diff(y))];
%// truncated data
tTrunc = t(keep)
yTrunc = y(keep)
with the results for the example as follows
tTrunc =
0 0.0300 0.0400 0.0500
yTrunc =
1 0 1 0

using Matlab, how to find the maximum value over a certain range?

i want to know the coding to find the maximum value, over a certain range.
i already coded like below.
f=f'
ac_yyyy_f=ac_yyyy_f'
[row,col] = ind2sub(size(ac_yyyy_f),find(ac_yyyy_f==max(ac_yyyy_f)))
but the problem is, sometimes the maximum value of Y axis choosen by my code is not what i want.
the X axis has the range of 0 to 100000 and i want the maximum between 20000 to 100000. the problem is sometimes the max value show up at the range of 0 to 20000.
How can i figure this out?
Use the max() function:
%let R be your range of values
R = [2 1 7 4];
[value, index] = max(R);
In the above example, value will be 7 and index will be 3
For more info: http://fr.mathworks.com/help/matlab/ref/max.html
I'm using a vector of random integers to stand in for your function output.
a = floor(rand(1,100000)*100);
[val, idx] = max(a(20000:100000));
You want to use the max function here to find the maximum value rather than find.
Now, the other part of the task is getting the max value from a certain part of your matrix. You can pass just a subset of a vector or matrix to a function by indexing it with a range of values. Note that idx gives you the position of val within a(20000:100000). If you need the position within a, you need to use idx+19999.
Also, you should take a look at the matrix indexing reference—there are many different and fun ways to index a matrix—because indexing is one of the most important features of matlab.
Here's the reference for the max function:
http://www.mathworks.com/help/matlab/ref/max.html
And the reference for indexing:
http://www.mathworks.com/help/matlab/math/matrix-indexing.html
You can use the max function with a subset of your array. It will return the maximum value, as well as the index where it is located. Be sure to correct the index it returns you based on your desired range. Like this:
%//create an array of 100,000 values to play with.
f=floor(rand(100000,1).*100);
%//find the max between f(20000) and f(100000)
[myMax, I] = max( f(20000:100000) );
%//correct the index based on where we started looking
%//for the max. Subtract 1 because it's MATLAB!
myIndex = I+20000-1;
This results in:
>> myMax
myMax =
99
>> myIndex
myIndex =
20045
>> f(myIndex)
ans =
99

Compare a value to a vector of values and return the match in Matlab

Can any one tell me how to return a matched value to a comparison between a value and a column vector in MATLAB. So lets say the value to be compared is 200 and I got a column vector:
a = [21; 32; 433; 54; 42;]
I want to find which element in the vector a returns the match for the comparison 200 <= a
If I do: x = any(200 <= a) the value of x will be 0 or 1 based on if the condition satisfy. But if I want to know which value in vector 'a' satisfied the condition how can I find that out? In this case element 3 and value is 433
The other answers are good, but find is unnecessary. Whenever possible, use logical indexing instead. Seeing 200 <= a is a bit strange for me. I like seeing the variable on the left side, so this is the same as saying a >= 200. In any case, you can do this:
vals = a(200 <= a);
200 <= a would return a logical vector where 1 denotes that the element satisfies the condition you're looking for and 0 would mean that the condition isn't satisfied. If we displayed 200 <= a, this is what we get:
>> 200 <= a
ans =
0
0
1
0
0
This means that only the third element satisfies your criteria. If we used this logical vector and indexed into a, we would return only those elements that satisfied your condition from a. As such, we would get:
vals =
433
Use find as follows:
positions = find(200<=a); %// all positions satisfying condition
values = a(positions); %// values at those positions
You can use find to get a vector of indices that satisfy the condition.
The following command returns the value at the index found to meet the criteria.
a(find(a >= 200))
ans =
433
Likewise, a <= 200:
a(find(a <= 200))
ans =
21
32
54
42
As #David points out in the comments, you don't need to use the find command, but it works just the same.

Stability (Numerical analysis)

I'm trying to find the max machine number x that satisfies the following equation: x+a=a, where a is a given integer. (I'm not allowed to use eps.)
Here's my code (which is not really working):
function [] = Largest_x()
a=2184;
x=0.0000000001
while (x+a)~=a
x=2*x;
end
fprintf('The biggest value of x in order that x+a=a \n (where a is equal to %g) is : %g \n',a,x);
end
Any help would be much appreciated.
The answer is eps(a)/2.
eps is the difference to the next floating point number, so if you add half or less than that to a float, it won't change. For example:
100+eps(100)/2==100
ans =
1
%# divide by less than two
100+eps(100)/1.9==100
ans =
0
%# what is that number x?
eps(100)/2
ans =
7.1054e-15
If you don't want to rely on eps, you can calculate the number as
2^(-53+floor(log2(a)))
You're small algorithm is certainly not correct. The only conditions where A = X + A are when X is equal to 0. By default matlab data types are doubles with 64 bits.
Lets pretend that matlab were instead using 8 bit integers. The only way to satisfy the equation A = X + A is for X to have the binary representation of [0 0 0 0 0 0 0 0]. So any number between 1 and 0 would work as decimal points are truncated from integers. So again if you were using integers A = A + X would resolve to true if you were to set the value of X to any value between [0,1). However this value is meaningless because X would not take on this value but rather it would take on the value of 0.
It sounds like you are trying to find the resolution of matlab data types. See this: http://www.mathworks.com/help/matlab/matlab_prog/floating-point-numbers.html
The correct answer is that, provided by Jonas: 0.5 * eps(a)
Here is an alternative for the empirical and approximate solution:
>> a = 2184;
>> e = 2 .^ (-100 : 100); % logarithmic scale
>> idx = find(a + e == a, 1, 'last')
idx =
59
>> e(idx)
ans =
2.2737e-013