1
\$\begingroup\$

Below are two examples of arrays (with a special ordering with odd numbers on one side, and even number on the other side) I have, with some given len:

9  7  5  3  1  2  4  6  8

11  9  7  5  3  1  2  4  6  8  10

For some value z, I want to find the column the value is in. MATLAB code I wrote:

if z == 1
   column = ceil(len/2);   
elseif logical(mod(z,2))
   column = ceil(len/2) - (z-1)/2;
else
   column = ceil(len/2) + z/2;
end

Does this above locate the correct column?

\$\endgroup\$
  • \$\begingroup\$ What's the context — why do you want to do this? Is len always odd? If not, can you provide an example of what an even-length array would look like? \$\endgroup\$ – 200_success Oct 18 '16 at 6:18
  • \$\begingroup\$ @200_success♦ yes it is always odd. \$\endgroup\$ – Elessarr Oct 18 '16 at 6:25
3
\$\begingroup\$

I suspect that the better solution is to compute the column index directly, without the if-else conditions. You can do this by using integer division, and modulo. Consider the following computation breakdown:

% declare an int32 value 2
itwo = int32(2)
% compute the position of the column with the value 1
onecol = idivide(len + 1, itwo)
% compute how far away the desired value is from the 1 column
distance = idivide(z, itwo)
% compute the direction of the desired value from the 1 column (-1 is left (odd numbers), +1 is right (even numbers))
direction = 1 - 2 * mod(z, itwo) 

You can string this together as a 1-liner:

column = idivide(len + 1, itwo) + idivide(z, itwo) * (1 - 2 * mod(z, itwo))

You can also put it in a function should you choose. I have put together this example here:

https://goo.gl/Oenp85 (and updated for int32 conversion here: https://goo.gl/NgJJhN

Note that it has been a long time since I played with MATLAB.

indexOfVal = @(mat, val) idivide(numel(mat) + 1, int32(2)) + idivide(val, int32(2)) * (1 - 2 * mod(val, int32(2)));

x = [9 7 5 3 1 2 4 6 8];

result1 = indexOfVal(x, 9)
result2 = indexOfVal(x, 7)
result3 = indexOfVal(x, 5)
result4 = indexOfVal(x, 3)
result5 = indexOfVal(x, 1)
result6 = indexOfVal(x, 2)
result7 = indexOfVal(x, 4)
result8 = indexOfVal(x, 6)
result9 = indexOfVal(x, 8)

Produces:

result1 =  1                                                                                                                                                                                                                
result2 =  2                                                                                                                                                                                                                
result3 =  3                                                                                                                                                                                                                
result4 =  4                                                                                                                                                                                                                
result5 =  5                                                                                                                                                                                                                
result6 =  6                                                                                                                                                                                                                
result7 =  7                                                                                                                                                                                                                
result8 =  8                                                                                                                                                                                                                
result9 =  9                        
\$\endgroup\$
  • 1
    \$\begingroup\$ @StewieGriffin I have applied the changes I think you want, and added a second running example in a link. Hopefully that encompasses the changes you suggest. Feel free to edit in any other incompatibility fixes with matlab. \$\endgroup\$ – rolfl Nov 17 '16 at 15:26
  • \$\begingroup\$ Looks good.. :) \$\endgroup\$ – Stewie Griffin Nov 17 '16 at 19:08
0
\$\begingroup\$

Obviously, the if z == 1 special case can be eliminated. When z is 1, then the logical(mod(z,2)) case applies, and the - (z-1)/2 term is 0.

\$\endgroup\$
  • \$\begingroup\$ oh thats true. But will it cause error if i include it? \$\endgroup\$ – Elessarr Oct 18 '16 at 6:31
  • \$\begingroup\$ if i remove it, i have to remove it from a lot of files i created. \$\endgroup\$ – Elessarr Oct 18 '16 at 6:32
  • \$\begingroup\$ so just want to make sure. if logical(mod(z,2)) column = ceil(len/2) - (z-1)/2; else column = ceil(len/2) + z/2; end works correctly? \$\endgroup\$ – Elessarr Oct 18 '16 at 6:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.