I am new to MATLAB and I have a question which I think should have an easy solution.However, I am stuck now.
My program produces a vector as a result which contains positive and negative values.
I wish to find a solution that I could assign only positive values of the vector to a new vector and replace the negative values with 0. Of course the size of the vectors should be the same.
The vector size is 1*345600
Pbat(t) ...... (has both negative and positive numbers)
Pbat1(t) ...... (should have the same size as Pbat(t) while changing negative values to 0)
Thanks in advance,
Hamed
Easy, using logical indexing...
initial_vector = rand(1,345600);
new_vector = initial_vector;
new_vector(initial_vector<0)=0;
Just use max(..., 0):
initial_vector = randn(1,345600); %// example data
new_vector = max(initial_vector, 0); %// set negative values to 0
Related
I have a complex matrix of size 3x2x372 complex double. I would like to work with only one specific of these three dimensions. Therefore, I used the following code to make the table easier to read:
new_output = abs(output);
In fact, the new matrix is of size 3x2x372 double. I guess it makes the further computation simpler. So I obtain the following output:
I would now like to create a matrix that only refers to the highlighted values. So it should ideally be of size 2x372 double.
Make a for-loop and assign the last row to a new matrix.
mat = zeroes(372, 2)
for k = 1:372
a = val(:, :, k)
mat(k, :) = a(1, :)
end
Edit: above gives you a 372x2 matrix. Use below to get a 2x372 matrix
mat = zeroes(2, 372)
And
mat(:, k) = a(1,:).'
in the loop
Actually, you need the last row from each "slice", so you can get it by:
new_output=data(size(data,1),:,:);
But that will give you the same dimensions as the original matrix, with 3D. To directly get it as 2D matrix, use squeeze:
new_output=squeeze(data(size(data,1),:,:));
I have a stupid problem, I can't find the answer to ^^.
I have a 100x10000 double matrix containing integers from 1 to 4 and want to find row-wise the column-count between every single integer
My first idea was to use:
storage_ones = cell(100,1);
for n = 1:100;
[row col] = find(matrix(n,:)==1);
storage_ones{n,1} = col;
end
And then substract them in another loop. But with find I get following Answer:
Empty matrix: 1-by-0
Does anybody have an idea how I can solve this problem?
Thanks in advance!!
Your issue is potentially due to one of two things:
Since you're using a double datatype, it is possible that you're encountering floating point errors where the values aren't going to be 1 exactly. If this is the case consider not checking for exact equality and instead check if it is very close to 1 using a small epsilon (here I used 1e-12).
[row, col] = find(abs(matrix(n,:) - 1) < 1e-12);
If you really have an integer datatype, consider using uint8 to store your data rather than double and then you can perform exact comparisons.
matrix = uint8(matrix);
% Then for your comparison
find(matrix(n,:) == 1)
You may just not have any 1's in that column. If find can't find any matches, it returns an empty array.
find([1 2 3] == 4)
% Empty matrix: 1-by-0
I have a some vectors of different large sizes and their value is between 0 and 1. I want to save those indices of elements which there would be any changes in decimal. For an small example, let's assume
V=[0.02,0.1,0.4,0.0054,0.05];
Now the ouptput for this should be as
i={2,4,5}
Would you please let me know how it can be done?
As suggested by #Luis Mendo (including his suggestion with removing ~= 0), here the comment as answer. You can use the logarithm function to determine your number of decimals for you.
i = find(diff(floor(log10(V))))+1
Be sure to use floor to have integer values you can compare to 0.
count = arrayfun(#(x) regexp(num2str(x),'\.','split'),V, 'UniformOutput', false)
dp = cell2mat(arrayfun(#(x) length(x{2}),count, 'UniformOutput', false))
find(diff(dp))+1
I did it this way. First I split the numbers and next i find the length of the second term and lastly, I find whether the length is different from its previous..
Let's say I have a cell array raweeg each cell of which is a matrix with time points in the first column and some markers in the second. I want to create a vector to store the time points, when the marker is not equal to -1. I found a non-elegant (and not working) way to create a vector of zeros of size 1x1 and then to append the following values in a loop.
P.S.: There are exactly 96 non-"-1" values and corresponding time points.
startpoints = zeros(1,1);
for i = length(raweeg{1,1}(:,1))
if raweeg{1,1}(i,2) ~= -1
startpoints(end+1,1) = raweeg{1,1}(i,1);
end
end
Thank you
Vectorize it like this, for a given cell of raweeg:
startpoints = raweeg{1,1}(raweeg{1,1}(:,2) ~= -1, 1);
This is called logical indexing.
Just be sure your markers are not generated with floating point computations, or the comparisons will likely fail often.
P.S. The problem in your code is the for loop statement, which should be:
for i = 1:length(raweeg{1,1}(:,1))
Or better, for i = 1:size(raweeg{1,1},1).
With out the "1:" part, it just has a single iteration, the last row.
I've got a huge array of values, all or which are much smaller than 1, so using a round up/down function is useless. Is there anyway I can use/make the 'find' function on these non-integer values?
e.g.
ind=find(x,9.5201e-007)
FWIW all the values are in acceding sequential order in the array.
Much appreciated!
The syntax you're using isn't correct.
find(X,k)
returns k non-zero values, which is why k must be an integer. You want
find(x==9.5021e-007);
%# ______________<-- logical index: ones where condition is true, else zeros
%# the single-argument of find returns all non-zero elements, which happens
%# at the locations of your value of interest.
Note that this needs to be an exact representation of the floating point number, otherwise it will fail. If you need tolerance, try the following example:
tol = 1e-9; %# or some other value
val = 9.5021e-007;
find(abs(x-val)<tol);
When I want to find real numbers in some range of tolerance, I usually round them all to that level of toleranace and then do my finding, sorting, whatever.
If x is my real numbers, I do something like
xr = 0.01 * round(x/0.01);
then xr are all multiples of .01, i.e., rounded to the nearest .01. I can then do
t = find(xr=9.22)
and then x(t) will be every value of x between 9.2144444444449 and 9.225.
It sounds from your comments what you want is
`[b,m,n] = unique(x,'first');
then b will be a sorted version of the elements in x with no repeats, and
x = b(n);
So if there are 4 '1's in n, it means the value b(1) shows up in x 4 times, and its locations in x are at find(n==1).