Constrain values in matlab - matlab

If i have a simple array in matlab, say:
a = [0 1 2 3 4 5 6 0 0]
How do i constrain the values in that array (if for example i want the maximum value to be 1, so to get to:
a = [0 1 1 1 1 1 1 0 0]
What would be the simplest, most efficient way to do that?

a(a>1) = 1;
This would do what you're asking... you can follow the same pattern for other constraints.
Edit: commenter is correct, fixed.

a > 0
or
min(a, 1)
(Tested in Octave.)

Try:
arrayfun(#(x) min(1,x),a)
For the max value and substitute max(val,x) for the min.

Related

matlab transform logical index to range

Couldn't find a quick answer for this, it seems super simple but I don't get it. I want do the following transformation (for this example using my imaginary function transform):
a=[0 0 0 1 0 0 0 0];
b=(-1:2); %rule to transform for every true value in [a], -1:2 should be true
transform(a,b) %should output [0 0 1 1 1 1 0 0]
a=[0 0 0 1 0 0 0 0 1 1 0 0 0]; %another example
transform(a,b) %should output [0 0 1 1 1 1 0 1 1 1 1 1 0];
Is there an quick way of doing this transform, maybe using logical operators?
edit: I tried
a(find(a)'+(-1:2))=1 %requires matlab>2016 if I'm not mistaken, otherwise replace + sign with bsxfun(#plus,...)
but I'm looking for a possible function that does this without changing a and without using find (since using find kind of defeats the purpose of using logical matrices/indexing in the first place)
If you have the Image Processing Toolbox you can use imdilate:
nh(max(abs([b(1),b(end)]))+1+b) = true;
result = imdilate(a, nh);
I found an elegant oneliner that should solve your problem:
b=(-1:2)
a(find(a) + b(:)) = 1;
Hope it helps!

force constant value using position of a vector

I have a vector with some positions
position = [2;5;10;12;18];
I would like to create a vector that looks like that
output = [1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0];
It means I take the difference between each value of position and in 'output' I put the number 1 for the first difference number and after 0 for the second difference number and so on..
diff = [3;5;2;6];
So, in output I have 3 ones, then 5 zeros, then 2 ones, then 6 zeros...
Thank you for you help.
You can also use repelem
a = diff(position);
b = mod(1:length(a),2);
repelem(b,a(:)')
How about this?
result = mod(sum(bsxfun(#lt, position(1):position(end)-1, position), 1) + 1, 2);
I'll let you figure out how it works.

Find indices where array changes

I have an array something like this:
[0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 0 0 0 1 1 ... ]
I want to find the indices where 0 changes to 1 and 1 changes to 0. So for the following array:
changes = [5 10 14 17 20]
I know how to use find and a vector predicate expression like find(A > 3) to search for simpler conditions, but this has me stuck. I could write a big loop and do it, but I feel there must be something built-in or otherwise easier to achieve the same thing.
A very simple approach which works with all values as start would be:
changes = find(diff(value))+1;
This will also return the expected result changes = [5 10 14 17 20].
Figured out a solution.
find(circshift(value, [0, 1]) ~= value)
For my application, the array is guaranteed to begin and end with 0s, otherwise it will not work properly.
Dennis K's solution works for your binary data. If you wish to find transitions in general, I recommend Run Length Encoding. I don't think MATLAB has a builtin, but (shameless plug), you can use seqle .

Count the number of the first zero elements

I would line to find the number of the first consecutive zero elements. For example in [0 0 1 -5 3 0] we have two zero consecutive elements that appear first in the vector.
could you please suggest a way without using for loops?
V=[0 0 1 -5 3 0] ;
k=find(V);
Number_of_first_zeros=k(1)-1;
Or,
Number_of_first_zeros=find(V,1,'first')-1;
To solve #The minion comment (if that was the purpose):
Number_of_first_zeros=find(V(find(~V,1,'first'):end),1,'first')-find(~V,1,'first');
Use a logical array to find the zeros and then look at where the zeros and ones are alternating.
V=[1 2 0 0 0 3 5123];
diff(V==0)
ans =
0 1 0 0 -1 0
Create sample data
V=[1 2 0 0 0 3 5123];
Find the zeros. The result will be a logical array where 1 represents the location of the zeros
D=V==0
D =
0 0 1 1 1 0 0
Take the difference of that array. 1 would then represent the start and -1 would represent the end.
T= diff(D)
ans =
0 1 0 0 -1 0
find(T==1) would give you the start and find(T==-1) would give you the end. The first index+1 of T==1 would be the start of the first set of zeros and the first index of T==-1 would be the end of the first set of zeros.
You could find position the first nonzero element using find.
I=find(A, 1);
The number of leading zeros is then I-1.
My solution is quite complex yet it doesn't use the loops and it does the trick. I am pretty sure, that there is a more direct approach.
Just in case no one else posts a working solution here my idea.
x=[1 2 4 0 20 0 10 1 23 45];
x1=find(x==0);
if numel(x1)>1
x2=[x1(2:end), 0];
x3=x2-x1;
y=find(x3~=1);
y(1)
elseif numel(x1)==1
display(1)
else
display('No zero found')
end
x is the dataset. x1 contains the index of all zero elements. x2 contains all those indices except the first one (because matrix dimensions must agree, one zero is added. x3 is the difference between the index and the previous index of zeros in your dataset. Now I find all those differences which are not 1 (do not correspond to sequences of zeros) and the first index (of this data is the required result. The if case is needed in case you have only one or no zero at all.
I'm assuming your question is the following: for the following vector [0 0 1 -5 3 0], I would like to find the index of the first element of a pair of 0 values. Is this correct? Therefore, the desired output for your vector would be '1'?
To extend the other answers to find any such pairs, not just 0 0 (eg. 0 1, 0 2, 3 4 etc), then this might help.
% define the pattern
ptrn = [ 0 0 ];
difference = ptrn(2) - ptrn(1)
V = [0 0 1 -5 3 0 0 2 3 4 0 0 1 0 0 0]
x = diff(V) == difference
indices = find(x)
indices =
1 6 11 14 15

How to assign a value to specific locations of a matrix in MATLAB?

I am not very familiar with Matlab so apologize for this silly question in advance. I would like to assign number 1 to some specific locations of a matrix. I have a row vector and the corresponding column vector. I tried to assign values to these locations several times. However, it didn't work. Here is a smaller size codes example. Assume there is a 4*4 matrix and I would like to assign matrix(1,1), matrix(2,3) and matrix (3,4) to 1. This is what I did.
matrix = zeros(4,4);
row = [1 2 3];
col = [1 3 4];
matrix(row,col)=1;
However, I got answer as
matrix=[ 1 0 1 1
1 0 1 1
1 0 1 1
0 0 0 0]
Can someone point out what I do wrong here? The actual size of the matrix I am going to work on is in thousands so it is why I can not assign those positions one by one manually. Is there any way to use the row vector and column vector I have to assign value 1 ? Thank you very much,
You can use sub2ind to compute the linear indices of the positions you want to assign to and use those for the assignment:
indices = sub2ind(size(matrix), row, col);
matrix(indices) = 1;
matrix(1,1) = 1
matrix(2,3) = 1
matrix(3,4) = 1
A bit of a bump. Unless you are doing quite a few noncontiguous rows or columns, a very useful way is like
matrix(1:3,2:4)=1
It supports element math very easily
this would turn
{0 0 0 0}
{0 0 0 0}
{0 0 0 0}
{0 0 0 0}
into
{0 1 1 1}
{0 1 1 1}
{0 1 1 1}
{0 0 0 0}