MATLAB: changes in vector elements - matlab

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..

Related

Find column-count inbetween integers row-wise in matrix (matlab)

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

How do I reshape a non-quadratic matrix?

I have a column vector A with dimensions (35064x1) that I want to reshape into a matrix with 720 lines and as many columns as it needs.
In MATLAB, it'd be something like this:
B = reshape(A,720,[])
in which B is my new matrix.
However, if I divide 35604 by 720, there'll be a remainder.
Ideally, MATLAB would go about filling every column with 720 values until the last column, which wouldn't have 720 values; rather, 504 values (48x720+504 = 35064).
Is there any function, as reshape, that would perform this task?
Since I am not good at coding, I'd resort to built-in functions first before going into programming.
reshape preserves the number of elements but you achieve the same in two steps
b=zeros(720*ceil(35604/720),1); b(1:35604)=a;
reshape(b,720,[])
A = rand(35064,1);
NoCols = 720;
tmp = mod(numel(A),NoCols ); % get the remainder
tmp2 = NoCols -tmp;
B = reshape([A; nan(tmp2,1)],720,[]); % reshape the extended column
This first gets the remainder after division, and then subtract that from the number of columns to find the amount of missing values. Then create an array with nan (or zeros, whichever suits your purpose best) to pad the original and then reshape. One liner:
A = rand(35064,1);
NoCols = 720;
B = reshape([A; nan(NoCols-mod(numel(A),NoCols);,1)],720,[]);
karakfa got the right idea, but some error in his code.
Fixing the errors and slightly simplifying it, you end up with:
B=nan(720,ceil(numel(a)/720));
B(1:numel(A))=A;
Create a matrix where A fits in and assingn the elemnent of A to the first numel(A) elements of the matrix.
An alternative implementation which is probably a bit faster but manipulates your variable b
%pads zeros at the end
A(720*ceil(numel(A)/720))=0;
%reshape
B=reshape(A,720,[]);

deleting a column in hansl

I have a very simple question. I want to delete a column from a matrix in a loop.
In Matlab I use the following:
for a certain i,
X(:,i)=[]
which deletes the column an reshapes the matrix.
I want to know the equivalent in Hansl (Gretl) program, please.
Thanks!
Sorry it's probably too late for you now, but I just saw your question and maybe it's useful for others.
In hansl (gretl's scripting and matrix language) I could think of several possibilities:
First, if you happen to know the number of columns and the value of i, the solution could use a hard-wired index vector (for i==2 and cols(X)==5 here):
X = X[, {1, 3,4,5}]
Secondly, since the first solution is probably too restrictive, you could concatenate the left and right parts of the matrix, as in:
X = X[, 1: i-1] ~ X[, i+1 :cols(X)]
But the problem here is that i must not index the first or last column, or the indexing will produce an error.
So my final suggestion that should work universally is:
X = selifc( X, ones(1, i-1) ~ 0 ~ ones(1, cols(X) - i) )
The selifc() function discards the column for which the second vector argument has a 0 entry. This also works for i==1 or i==cols(X).
A shorter variation of this final solution might be:
X = selifc(X, seq(1, cols(X)) .!= i)
which does an element-wise not-equal-to-i comparison (.!=) of the column indices constructed with the seq() function. But it's probably not as readable as the previous way.
good luck!

Recognise that numbers in a row of a matrix are all the same number

I have a matrix of 0s, 1s, 2s and 3s.If all the elements in the same row are the same then I want it to display the text 'flush'. For example, I have the matrix
[0,1,0,2,3;
0,0,0,0,0;
3,2,1,3,1;
2,2,2,2,2];
How would I program Matlab to recognise the 2nd and 4th row all have the same number?
A = [0,1,0,2,3; 0,0,0,0,0; 3,2,1,3,1; 2,2,2,2,2]
As it was said before if you only have positive numbers you can use the variance.
n_flush = var(A, [], 2) == 0
However, this will fail for negative numbers for example a row like [-2 -1 1 2].
What I would do is to compare the first column with the rest and flag the rows where all the elements are equal.
n_flush = all(bsxfun(#eq, A(:,1), A(:,2:end)),2)
Now, if you want to display flush every time the rows are equal you can do
for ind = find(n_flush)
fprintf('flush row %i\n', ind)
end
If you need to have the whole thing in a one-liner (which is what many Matlab-geeks try to do), then maybe this here will suit your needs
cellfun(#(x) char((x==0)*sprintf('flush')), num2cell(var(A')'), 'UniformOutput', false)
Edit: nice idea GameOfThrows
Yet another solution by explicitly subtracting the first column from each column via duplicating the first column to other columns of a matching-sized matrix.
identical_rows = ~any(A - kron(ones(1,size(A,2)),A(:,1)),2)

Operation on specific part of a vector in MATLAB

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