Replacing specific values in an array based on logic

Viewed 403

I'm trying to replace the values in array1 following this Logic:

  1. If the values are greater than one use just the decimal value.
  2. If it's exactly 1 stay at 1
  3. If 0 stay 0
  4. If neg make positive and follow the logic

The code I used was:

array1=[0.5 1.3 1.0 0.0 -0.2 -2.78]
array1(array1>1)=mod(abs(array1),1)

what I expected to get is array1 = [0.5 0.3 1.0 0.0 0.2 0.78]

But I get an error: =: nonconformant arguments (op1 is 1x1, op2 is 1x5) how can I fix this?

PS: I'm using Octave 5.2 which is similar to Matlab

2 Answers

This causes an Unable to perform assignment-error because left and right side of the assignment differ in size: You need to use the logical indexing on both sides array1>1.

array1=[0.5 1.3 1.0 0.0 -0.2]
% create logical vector for indexing
lg = array1 > 1
% replace elements
array1(lg) = mod( abs(array1(lg)) ,1)

This should work in MATLAB + Octave. You can also split the different operations :

% ensure positiveness
array1 = abs(array1);
% force to one
lg = array1 > 1;
array1(lg) = mod(array(1),1);

this returns array1 = 0.5000 0.3000 1.0000 0 0.20

If you absolutely want to stick to your approach, you can use a little trick: add +1e-10 to the second input of the mod function to let 1 "survive" the operation ;)

array1 = mod( abs(array1) ,1+1e-10)

This trick will yield slightly different results because the modulus is 1.0000000001 and not 1. The error will be higher, the higher the input number. However, from your example-array I would guess that this risk could be OK.

max's answer got me where I needed to get to here's what I used.

array1=[0.5 1.3 1.0 0.0 -0.2 -2.63]

array1=abs(array1) %1) make array positive
lg = array1 > 1 %2) create logical vector for indexing
array1(lg) = mod( abs(array1(lg)) ,1) %3) replace elements
array1 =

   0.50000   1.30000   1.00000   0.00000  -0.20000  -2.63000

array1 =

   0.50000   1.30000   1.00000   0.00000   0.20000   2.63000

lg =

  0  1  0  0  0  1

array1 =

   0.50000   0.30000   1.00000   0.00000   0.20000   0.63000
Related