Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Colon operands must be all the same type

399 views
Skip to first unread message

Marcus

unread,
Jan 3, 2012, 4:17:08 AM1/3/12
to
Hey guys,

I have the following problem in a Simulink (User defined function) :
The purpose is to search an 256 by 256 array(rand_pt), starting at random coordinates (random_coo_x_double,random_coo_y_double). The program is supposed to stop if it finds an value 1.

***--------------------------------------------------------------------------------------***
***--------------------------------------------------------------------------------------***
***--------------------------------------------------------------------------------------***

random_coo_x_double=randi(128,1,1);

random_coo_y_double=randi(256,1,1);


point_x_temp=1;
point_y_temp=1;
flag=0;
i=1;
j=1;


limit_x=128;
limit_y=256;

while(flag==0) %as long as flag is false
for i=random_coo_x_double:limit_x
for j=random_coo_y_double:limit_y
if (rand_pt(i,j)==1)
point_x_temp=i;
point_y_temp=j;
flag=1; %flag is true
break;
else
%continue searching
end%if
end%for
if flag
break
end%if

end%for
if flag
break
end%if
end%while

***--------------------------------------------------------------------------------------***
***--------------------------------------------------------------------------------------***
***--------------------------------------------------------------------------------------***
In Matlab this is working perfectly. I believe the error message (Colon operands must be all the same type, or mixed with real scalar doubles.) tells me that
"i" and "random_coo_x_double" and "limit_x" should be of the same type.
So far I tried having them all as integers(uint8), which did not work because my array has the size of 256x256. Then I tried uint16 and double which all worked in Matlab but when I copied the code to the Simulink block I got the error above.

I could not find any post that was talking about that problem, so I hope I ll be able to find help here.
Thanks guys
Marcus.

dpb

unread,
Jan 3, 2012, 3:06:48 PM1/3/12
to
On 1/3/2012 3:17 AM, Marcus wrote:
> Hey guys,
> I have the following problem in a Simulink (User defined function) :
> The purpose is to search an 256 by 256 array(rand_pt), starting at
> random coordinates (random_coo_x_double,random_coo_y_double). The
> program is supposed to stop if it finds a value 1.

coo_x=randi(128,1);
coo_y=randi(256,1);

x_temp=1;
y_temp=1;
flag=0;
i=1;
j=1;
limit_x=128;
limit_y=256;
while(flag==0)
for i=coo_x:limit_x
for j=coo_y:limit_y
if (rand_pt(i,j)==1)
x_temp=i;
y_temp=j;
flag=1;
break;
end%if
end%for
if flag, break, end
end%for
if flag, break, end
end%while

> In Matlab this is working perfectly. I believe the error message (Colon
> operands must be all the same type, or mixed with real scalar doubles.)
> tells me that
> "i" and "random_coo_x_double" and "limit_x" should be of the same type.
> So far I tried having them all as integers(uint8), which did not work
> because my array has the size of 256x256. Then I tried uint16 and double
> which all worked in Matlab but when I copied the code to the Simulink
> block I got the error above.

I don't "know nuthink" about Simulink so this is hypothesis...

i and j above will be double (assuming Simulink has same rules as
Matlab). The documentation doesn't say what the default 'classname' is
for randi(), but perhaps it is one of the integer classes; I don't know.

Presuming again you can set breakpoints in Simulink, use the debugger
and do a "whos" on the three variables at the point of the for and see
what they are; that should tell you what is going on.

I rewrote the above function shortening names drastically to aid in
reading the code...

A couple of comments...it would be best practice in Matlab to learn to
_not_ use 'i|j' for variables in loop indices, etc. despite the
propensity for same in other languages. Matlab defines them as the
imaginary i and j and overloading those can cause unexpected
difficulties down the road when you really sometime do want the complex
values.

I'd wonder why use looping here at all, though...why not simply select
the starting point then convert that to a linear index and then use
find() and ind2sub w/ the offset of the starting point?

Something like

ix=randi(128,1);
iy=randi(256,1);

idx_strt = sub2ind(size(x),ix,iy); % the initial offset into array
idx_fnd = find(x(idx_strt:end)==1,1,'first');
if ~isempty(idx_find)
[ix,iy]=ind2sub(size(x),idx_find+idx_strt-1);
else
ix=0; iy=0;
end

You can decide about the return value(s) or whatever, if the resulting
find() does return an empty result.

--

dpb

unread,
Jan 3, 2012, 4:04:39 PM1/3/12
to
On 1/3/2012 2:06 PM, dpb wrote:
...

> I'd wonder why use looping here at all, though...why not simply select
> the starting point then convert that to a linear index and then use
> find() and ind2sub w/ the offset of the starting point?

OK, that's not _quite_ the same as you looping construct; to do that one
must select the square submatrix from that point and work from it.

Actually, that's probably easier to see than the previous solution...

> Something like
>
ix=randi(128,1);
iy=randi(256,1);

[fx,fy] = find(x(ix:end,iy:end)==1,1,'first');
if ~isempty(fx)
ix=ix+fx-1;
iy=iy+fy-1;
else
ix=0; iy=0;
end

Note the above was based on the values being floats; if the array is
logical (or 0|1) then the "==1" in the find() argument can be dispensed
with; default behavior of find() is nonzero values.

--

Phil Goddard

unread,
Jan 3, 2012, 5:26:08 PM1/3/12
to

You haven't explicitly said what type of user defined function you are using, but assuming it's an Embedded MATLAB Block, then the problem is that at compile time the data type of
randsom_coo_x_double
is not known and defaults to mxArray.

(It could be argued that it should default to double, but it doesn't.
When using Embedded MATLAB think in terms of C not MATLAB and predefine all data types.)

In your case you can simple add the 2 lines

random_coo_x_double=0;
random_coo_y_double=0;

before

> random_coo_x_double=randi(128,1,1);
> random_coo_y_double=randi(256,1,1);

Phil.
0 new messages