check if a column is composed of ones - matlab

does it exist a function built-in in matlab that checks if a column is all composed of ones? If it doesn't exist, there are some ways to build a function that work to achieve that porpouse?

all(A==1) should return true if it's composed of only 1s. Note that if you have any floating point precision errors, you should use all( abs(A-1) < eps ).

You can compare all entries of a column to 1 and sum the result
if sum(A(:,1)~=1)==0
% all ones
else
% not all ones
end

If A is a column vector:
A=[1 1 1 1]';
You could check like this:
sum(A==1)==length(A)
ans =
1

Related

removing uniform columns in MATLAB

Say i have a 2D matrix A:
A = [ 1 1 0 0
1 0 0 0
1 1 1 0];
A is not necessarily binary, or even integer (i.e., floats are possible). I want to remove any column that contains uniform valued elements. In the above example, i would get:
1 0
0 0
1 1
To make this fully general, i'd like to allow the user to select the dimension along which rows/columns/slices are removed (i.e., with a DIM option).
Any ideas?
You could try using the min and max functions, which allow you to use the dim argument.
For example
index = min(A,[],1)==max(A,[],1);
A(:,index)=[];
will remove the columns you want. It is straightforward to do the same for rows
index = min(A,[],2)==max(A,[],2);
A(index,:)=[];
One-liner:
B = A(:,range(A)~=0); %//columns
The other one-liner is not that nice, and ugly one-liners should not be written down. :-) But is basically the same solution as S..'s, except is way more expensive (requires stats toolbox).
Please note that "generality" of subscript-based solutions doesn't extend to N-dimensional arrays as easily, because subscripting in ND arrays without checking beforehand the number of dimensions is difficult. Also, for the 1D arrays the notion of "uniformity" is a bit odd along the singleton dimension (the result is always empty).
Besides the neat solution provided by #S.. there is this simple hack also for your example:
for ii = 1:size(A,2)
T(ii) = all(A(:,ii) == sum(A(:,ii))/numel(A(:,ii)));
end
A(:,~T)
ans =
1 0
0 0
1 1
As suggested by #gariepy the right side of the equation can be replaced with mean function.
for ii = 1:size(A,2)
T(ii) = all( A(:,ii) == mean(A(:,ii)) );
end
A(:,~T)
A(:,~all(A == repmat(A(1,:),[size(A,1) 1])))
Inspired by #S.. but only checks if every element of the column equals the first element of the column. Seems like a little less work for the processor than finding the min and the max, and checking for equality.

Create an nx1 vector that can be changed easily by specifying n

I want to be able to create a simple nx1 vector in which each row value is a constant (e.g. [2 2 ... 2 2]') and also an nx1 vector in which the values in row 1 and row n are specified (e.g. [1 2 2 ... 2 2 1]'). Also, how would you generate a vector in which you are alternating between two values (e.g. [1 -1 1 -1...]')?
Is there anyway to generate these vectors with out manually typing in each value? I tried to find a way to do so by looking through this Matlab documentation, but couldn't work it out. Thank you!
const=2; %desired constant value
len=5; %length of vector
row1=1; %value of row 1
rown=1; %value of row n
x=const*ones(len,1);
y=[row1; x(1:end-2); rown];
Please, try this code.
const=5; %desired absolute value
Len=10; %length of vector
k=1:Len;
a=(-1).^k;
b=const*a;
If you want same absolute number, this code would be ok.
const1=-3; %first value
const2=5; %second value
N=5; %half length of vector
a=const1*ones(1,N);
b=const2*ones(1,N);
k=zeros(1,2*N);
n=1:N;
k(2*n)=a(n);
k(2*n-1)=b(n);
If you want arbitrary two values, please try this code.

What does it mean to use logical indexing/masking to extract data from a matrix? (MATLAB)

I am new to matlab and I was wondering what it meant to use logical indexing/masking to extract data from a matrix.
I am trying to write a function that accepts a matrix and a user-inputted value to compute and display the total number of values in column 2 of the matrix that match with the user input.
The function itself should have no return value and will be called on later in another loop.
But besides all that hubbub, someone suggested that I use logical indexing/masking in this situation but never told me exactly what it was or how I could use it in my particular situation.
EDIT: since you updated the question, I am updating this answer a little.
Logical indexing is explained really well in this and this. In general, I doubt, if I can do a better job, given available time. However, I would try to connect your problem and logical indexing.
Lets declare an array A which has 2 columns. First column is index (as 1,2,3,...) and second column is its corresponding value, a random number.
A(:,1)=1:10;
A(:,2)=randi(5,[10 1]); //declares a 10x1 array and puts it into second column of A
userInputtedValue=3; //self-explanatory
You want to check what values in second column of A are equal to 3. Imagine as if you are making a query and MATLAB is giving you binary response, YES (1) or NO (0).
q=A(:,2)==3 //the query, what values in second column of A equal 3?
Now, for the indices where answer is YES, you want to extract the numbers in the first column of A. Then do some processing.
values=A(q,2); //only those elements will be extracted: 1. which lie in the
//second column of A AND where q takes value 1.
Now, if you want to count total number of values, just do:
numValues=length(values);
I hope now logical indexing is clear to you. However, do read the Mathworks posts which I have mentioned earlier.
I over simplified the code, and wrote more code than required in order to explain things. It can be achieved in a single-liner:
sum(mat(:,2)==userInputtedValue)
I'll give you an example that may illustrate what logical indexing is about:
array = [1 2 3 0 4 2];
array > 2
ans: [0 0 1 0 1 0]
using logical indexing you could filter elements that fullfil a certain condition
array(array>2) will give: [3 4]
you could also perform alterations to only those elements:
array(array>2) = 100;
array(array<=2) = 0;
will result in "array" equal to
[0 0 100 0 100 0]
Logical indexing means to have a logical / Boolean matrix that is the same size as the matrix that you are considering. You would use this as input into the matrix you're considering, and any locations that are true would be part of the output. Any locations that are false are not part of the output. To perform logical indexing, you would need to use logical / Boolean operators or conditions to facilitate the selection of elements in your matrix.
Let's concentrate on vectors as it's the easiest to deal with. Let's say we had the following vector:
>> A = 1:9
A =
1 2 3 4 5 6 7 8 9
Let's say I wanted to retrieve all values that are 5 or more. The logical condition for this would be A >= 5. We want to retrieve all values in A that are greater than or equal to 5. Therefore, if we did A >= 5, we get a logical vector which tells us which values in A satisfy the above condition:
>> A >= 5
ans =
0 0 0 0 1 1 1 1 1
This certainly tells us where in A the condition is satisfied. The last step would be to use this as input into A:
>> B = A(A >= 5)
B =
5 6 7 8 9
Cool! As you can see, there isn't a need for a for loop to help us select out elements that satisfy a condition. Let's go a step further. What if I want to find all even values of A? This would mean that if we divide by 2, the remainder would be zero, or mod(A,2) == 0. Let's extract out those elements:
>> C = A(mod(A,2) == 0)
C =
2 4 6 8
Nice! So let's go back to your question. Given your matrix A, let's extract out column 2.
>> col = A(:,2)
Now, we want to check to see if any of column #2 is equal to a certain value. Well we can generate a logical indexing array for that. Let's try with the value of 3:
>> ind = col == 3;
Now you'll have a logical vector that tells you which locations are equal to 3. If you want to determine how many are equal to 3, you just have to sum up the values:
>> s = sum(ind);
That's it! s contains how many values were equal to 3. Now, if you wanted to write a function that only displayed how many values were equal to some user defined input and displayed this event, you can do something like this:
function checkVal(A, val)
disp(sum(A(:,2) == val));
end
Quite simply, we extract the second column of A and see how many values are equal to val. This produces a logical array, and we simply sum up how many 1s there are. This would give you the total number of elements that are equal to val.
Troy Haskin pointed you to a very nice link that talks about logical indexing in more detail: http://www.mathworks.com/help/matlab/math/matrix-indexing.html?refresh=true#bq7eg38. Read that for more details on how to master logical indexing.
Good luck!
%% M is your Matrix
M = randi(10,4)
%% Val is the value that you are seeking to find
Val = 6
%% Col is the value of the matrix column that you wish to find it in
Col = 2
%% r is a vector that has zeros in all positions except when the Matrix value equals the user input it equals 1
r = M(:,Col)==Val
%% We can now sum all the non-zero values in r to get the number of matches
n = sum(r)
M =
4 2 2 5
3 6 7 1
4 4 1 6
5 8 7 8
Val =
6
Col =
2
r =
0
1
0
0
n =
1

logical operation within vector range expression in MATLAB

can I have something like
A=1:10;
A(1:2 && 5:6)=0;
meaning I want to zero out specific ranges within my vector index expression in one line
Is that possible?
And what if I wanted to zero out all the rest like
A(~[1:2]) = 0
What's the way of logical NOT within vector indexing?
Thanks
The following should work:
idx = [1:2,5:6];
A(idx) = 0
If you want to zero the complement of the vector of indices:
idx = [1:2,5:6];
A(~ismembc(1:length(A),idx)) = 0
Where ismembc is a faster, lightweight version of ismember that assumes the array is sorted and non-sparse with no NaN elements. (Credit goes to this question.)
Just do A([1:2 5:6]). I.e., just create a vector of the indices you want to zero out.

Matlab Fill previous value if missing value (or zero)

I have a vector containing a time series with different values and some missing values inbetween that are set to zero:
X=[0,0,2,0,5,0,0,0,4,0];
I want to create a new vector where the missing values (zeros) are populated by the previous value if one exist so that I get a new vector looking like:
Z=[0,0,2,2,5,5,5,5,4,4];
I have been browsing through the Matlab help and forums like this to find a neat and suitable function that would solve this for me with a one line solution or similar, but I have failed to do so. I can solve the problem through a few different steps according to below but I am guessing that there must be a better and easier solution available?
Current solution:
X=[0,0,2,0,5,0,0,0,4,0];
ix=logical(X);
Y = X(ix);
ixc=cumsum(ix);
Z=[zeros(1,sum(~logical(ixc))) Y(ixc(logical(ixc)))];
This does the trick, but it seems like an overly complicated solution to a simple problem, so can anyone help me with a better one? Thanks.
Here's a somewhat simpler version using cumsum:
X=[0,0,2,0,5,0,0,0,4,0];
%# find the entries where X is different from zero
id = find(X);
%# If we want to run cumsum on X directly, we'd
%# have the problem that the non-zero entry to the left
%# be added to subsequent non-zero entries. Thus,
%# subtract the non-zero entries from their neighbor
%# to the right
X(id(2:end)) = X(id(2:end)) - X(id(1:end-1));
%# run cumsum to fill in values from the left
Y = cumsum(X)
Y =
0 0 2 2 5 5 5 5 4 4
Here's a little something I wrote up. Does this do the trick?
% INPUT: the array you would like to populate
% OUTPUT: the populated array
function popArray = populate(array)
popArray = array;
% Loops through all the array elements and if it equals zero, replaces it
% with the previous element
%
% Since there is no element before the first to potentially populate it, this
% starts with the second element.
for ii = 2:length(popArray)
if array(ii) == 0;
popArray(ii)= popArray(ii-1);
end
end
disp(popArray);
Let me suggest another vectorized solution (though I like the one by #Jonas better):
X = [0 0 2 0 5 0 0 0 4 0]
id = find(X);
X(id(1):end) = cell2mat( arrayfun(#(a,b)a(ones(1,b)), ...
X(id), [diff(id) numel(X)-id(end)+1], 'UniformOutput',false) )