1
$\begingroup$

I have X, Y and Z variables in matrix form, each of size n x 1. Eg.:

X = [-38.0400, -38.6700, -38.9300, -39.4500...]

Whenever I run the code below:

% find center of X
minx = find(X==min(min(X)));
maxx = find(X==max(max(X)));
centx = (minx + maxx) / 2;
xy = Y(centx);
xz = Z(centx);
centx = [centx xy xz];

I'll get the initial answer as, for example:

centx = 6.6034e+04

but then an error will be displayed:

Subscript indices must either be real positive integers or logicals.
Error in max_point(line 5)
xy = Y(centx);

My questions are

  • Is the answer given in scientific notation (exponential form) because of the trailing zeros in my original entries?
  • How can I avoid getting the answer in scientific notation (exponential form) (because I think that is the cause for the error)?

Thanks in advance

$\endgroup$
1
3
$\begingroup$

The problem is here,

centx = (minx + maxx) / 2;

You are using a floating point number as the index of an array. The error is simply saying that an index must be an integer.

You want to know which index is the center of the x range? You will need to do that in a different way. How about this,

% find center of X
minx = find(X==min(min(X)));
maxx = find(X==max(max(X)));
centx = uint32(round((minx + maxx) / 2)); % notice I used the round function here and the cast to make it an integer!
xy = Y(centx);
xz = Z(centx);
centx = [centx xy xz];

This uses the round function, http://www.mathworks.com/help/matlab/ref/round.html

The round function automatically use the most appropriate integer rounding function to get you to the closest value, which I think it what you want in this case. You still need to cast to an integer as pointed out below.

Internally the round function is applying ceil if the fractional part is $>=\frac{1}{2}$, or the floor function when the fractional part $<\frac{1}{2}$.

The exponential answer is just because that is the way MATLAB prints floats.

$\endgroup$
7
  • $\begingroup$ so, there's no way avoiding it? sorry that might heard like a stupid question, but i'm totally a beginner. $\endgroup$ – user3991 Jun 26 '13 at 7:59
  • $\begingroup$ There are ways, probably use this function to convert the float to the nearest integer, mathworks.com/help/matlab/ref/round.html $\endgroup$ – boyfarrell Jun 26 '13 at 8:35
  • $\begingroup$ ok i see your point there. then how about the Error in max_point(line 5) xy = Y(centx);? would you mind to have a look? $\endgroup$ – user3991 Jun 27 '13 at 4:48
  • $\begingroup$ Both errors come from the same cause, try the code in my answer see it that works. $\endgroup$ – boyfarrell Jun 27 '13 at 5:23
  • $\begingroup$ round returns a double not an integer (and this is true also for C), see its prototype: double round( double arg ); The main reason for type casting is not to have to call round/ceil/floor before every use of the variables as indexes in an array. If you do not cast, variables remain double. There are of course also good reasons not to cast, like efficiency. (On a number of architectures integer arithmetic is very slow, if compared to floating point arithmetic.) $\endgroup$ – Stefano M Jun 27 '13 at 6:49
1
$\begingroup$

centx = (minx + maxx) / 2; will result in non-integer array index as @boyfarrell pointed out. You could use function ceil or floor to get the nearest integer index if that is what you are looking for.

$\endgroup$
0
$\begingroup$

In matlab by default everything is a matrix of double precision floating point numbers. If you like to do index arithmetic using integer variables you can perform an explicit type cast using the conversion functions listed in http://www.mathworks.it/it/help/matlab/numeric-types.html. E.g.

minx = uint32(find(X==min(min(X))));

(here I'm using 32 bit unsigned integers, under the assumption that you do not need 64 bit pointers.)

Note that

>> a = 3/2
a =
    1.5000
>> b = uint32(3)/2 
b =
           2
>> whos
  Name      Size            Bytes  Class     Attributes

  a         1x1                 8  double              
  b         1x1                 4  uint32              

Alternatively you can do index arithmetic in double and then use the ceil and floor function to round the floating point number, as suggested in other answers. (Please note that ceil and floor return a double, they do not cast to an integer type.)

$\endgroup$
2
  • $\begingroup$ I've tried another function of format short g, which give me non-exponential answer, just like I wanted. (Eg: centx = 6.6034e+04 become centx = 66034). I've come to realized that another error is found. Error xy = Y(centx); I edited my question with addition of this error. $\endgroup$ – user3991 Jun 27 '13 at 3:28
  • $\begingroup$ @Jueru format will only affect how a value is printed, not its data type. All error seems to be linked to improper data type or value... Type cast or round. $\endgroup$ – Stefano M Jun 27 '13 at 6:54

Your Answer

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