COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Vectorization of for-loop!

• Follow

```Hello i was trying to vectorize following function,that i used with for-loop. But it doesn`t work.Any suggestions how can i vectorize this code?
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function result=bigfunc(matrix,row,column)
left=matrix([row-1:row+1],column-1);
right=matrix([row-1:row+1],column+1);
middleup=matrix(row-1,column);
middledown=matrix(row+1,column);
neighbors=[left' middleup middledown right'];
if(sum(neighbors(neighbors<=7))>=2 & nnz(neighbors(neighbors<=7))>=2 )
matrix(row,column)=1;
disp('infected');
end
result=matrix;
end
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This is how i called the function with for-loop:
for i=1:5
for j=1:3
bigfunc(u,i,j);

this is how i tried to vectorize it:
u =
1     1     1
1     1     1
1     1     1
1     1     1
1     1     1

i=1:5;
j=1:3;
u=bigfunc(u,1.*i,1.*j)
???Subscript indices must either be real positive integers or logicals. I did not include the entire function,since there are lot of cases when row and column will be out of bounds.However,if you want to to try the function please use the central value of u(3,2) or u(2,2) or u(4,2).
Please respond as soon as possible
```
 0
Reply maks 4/19/2010 3:45:22 AM

```Vectorization is not magical ... in most cases, you need to rewrite a function so that it can accept vectors instead of scalars.

In your case, I suggest the following approach (assuming the size of the matrix is fixed). It is a little involved, but conceptually straightforward.

1) You are always using the same "window" into a matrix, only the center of this window changes. Assume the center of the window is (0,0) and derive the matrix indices for these 8 points, i.e:
left = [-1 -1; 0 -1;  1 -1];
right = [-1 1; 0 1; 1 1];
middleup = [-1 0];
middledown  = [1 0];

2)  Convert the 8 points into linear indices. (This is what SUB2IND does, but in your cases the indices are <= 0, so SUB2IND won't work).  But it is pretty straightforward, see this doc:

3) Now you have a vector of length 8 that defines your window. You can apply this window to a desired location by (a) getting the linear index of that location and (b) centering the window over that location.

4) For vectorizing, you want to apply your window (vector of length 8) to multiple locations at the same time. Assume that you have two locations and:
v1 is the window (vector of linear indices) for location 1
v2 is the window (vector of linear indices) for location 2
Create a new indexing matrix composed of v1 and v2
im = [v1;v2]

5) Use 'im' to index into your matrix
points = matrix(im);
apply your test to each row of points. This can be vectorized as well.

Best,
Gautam

"maks  merlo" <kmaxat@gmail.com> wrote in message <hqgjki\$ett\$1@fred.mathworks.com>...
> Hello i was trying to vectorize following function,that i used with for-loop. But it doesn`t work.Any suggestions how can i vectorize this code?
> ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> function result=bigfunc(matrix,row,column)
> left=matrix([row-1:row+1],column-1);
>    right=matrix([row-1:row+1],column+1);
>     middleup=matrix(row-1,column);
>     middledown=matrix(row+1,column);
> neighbors=[left' middleup middledown right'];
> if(sum(neighbors(neighbors<=7))>=2 & nnz(neighbors(neighbors<=7))>=2 )
>     matrix(row,column)=1;
>     disp('infected');
> end
> result=matrix;
> end
> ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> This is how i called the function with for-loop:
> for i=1:5
> for j=1:3
> bigfunc(u,i,j);
>
>
> this is how i tried to vectorize it:
> u =
>      1     1     1
>      1     1     1
>      1     1     1
>      1     1     1
>      1     1     1
>
> i=1:5;
> j=1:3;
> u=bigfunc(u,1.*i,1.*j)
> ???Subscript indices must either be real positive integers or logicals. I did not include the entire function,since there are lot of cases when row and column will be out of bounds.However,if you want to to try the function please use the central value of u(3,2) or u(2,2) or u(4,2).
```
 0
Reply Gautam 4/19/2010 2:30:20 PM

```"Gautam Vallabha" <gautam.vallabha.nospam@mathworks.com> wrote in message <hqhpds\$epa\$1@fred.mathworks.com>...
>
> Vectorization is not magical ... in most cases, you need to rewrite a function so that it can accept vectors instead of scalars.
>
> In your case, I suggest the following approach (assuming the size of the matrix is fixed). It is a little involved, but conceptually straightforward.
>
> 1) You are always using the same "window" into a matrix, only the center of this window changes. Assume the center of the window is (0,0) and derive the matrix indices for these 8 points, i.e:
>    left = [-1 -1; 0 -1;  1 -1];
>    right = [-1 1; 0 1; 1 1];
>    middleup = [-1 0];
>    middledown  = [1 0];
>
> 2)  Convert the 8 points into linear indices. (This is what SUB2IND does, but in your cases the indices are <= 0, so SUB2IND won't work).  But it is pretty straightforward, see this doc:
>
> 3) Now you have a vector of length 8 that defines your window. You can apply this window to a desired location by (a) getting the linear index of that location and (b) centering the window over that location.
>
> 4) For vectorizing, you want to apply your window (vector of length 8) to multiple locations at the same time. Assume that you have two locations and:
>   v1 is the window (vector of linear indices) for location 1
>   v2 is the window (vector of linear indices) for location 2
> Create a new indexing matrix composed of v1 and v2
>   im = [v1;v2]
>
> 5) Use 'im' to index into your matrix
>     points = matrix(im);
> apply your test to each row of points. This can be vectorized as well.
>
> Best,
> Gautam
Thank you SO MUCH. If it`s not difficult, could you please show me example to vectorize through entire matrix?
```
 0
Reply Maks 4/19/2010 5:30:23 PM

```Maks,

Judging from your variable names it looks like you are trying to model the behaviour of a pathogen, and the bulk of your computation is spent checking whether a particular cells neighbors are infected. This probably calls for the use of the conv2 function.

If you supply another example, giving the starting matrix and the expected result, someone will likely post a working code.

Darren
```
 0
Reply Darren 4/20/2010 5:05:04 AM

```"Maks Merlo" <kmaxat@gmail.com> wrote in message <hqi3vf\$pmj\$1@fred.mathworks.com>...
> "Gautam Vallabha" <gautam.vallabha.nospam@mathworks.com> wrote in message <hqhpds\$epa\$1@fred.mathworks.com>...
> >
> > Vectorization is not magical ... in most cases, you need to rewrite a function so that it can accept vectors instead of scalars.
> >
> > In your case, I suggest the following approach (assuming the size of the matrix is fixed). It is a little involved, but conceptually straightforward.
> >
> > 1) You are always using the same "window" into a matrix, only the center of this window changes. Assume the center of the window is (0,0) and derive the matrix indices for these 8 points, i.e:
> >    left = [-1 -1; 0 -1;  1 -1];
> >    right = [-1 1; 0 1; 1 1];
> >    middleup = [-1 0];
> >    middledown  = [1 0];
> >
> > 2)  Convert the 8 points into linear indices. (This is what SUB2IND does, but in your cases the indices are <= 0, so SUB2IND won't work).  But it is pretty straightforward, see this doc:
> >
> > 3) Now you have a vector of length 8 that defines your window. You can apply this window to a desired location by (a) getting the linear index of that location and (b) centering the window over that location.
> >
> > 4) For vectorizing, you want to apply your window (vector of length 8) to multiple locations at the same time. Assume that you have two locations and:
> >   v1 is the window (vector of linear indices) for location 1
> >   v2 is the window (vector of linear indices) for location 2
> > Create a new indexing matrix composed of v1 and v2
> >   im = [v1;v2]
> >
> > 5) Use 'im' to index into your matrix
> >     points = matrix(im);
> > apply your test to each row of points. This can be vectorized as well.
> >
> > Best,
> > Gautam
> Thank you SO MUCH. If it`s not difficult, could you please show me example to vectorize through entire matrix?

As someone noted on this thread, CONV2 may be appropriate in this case, and you want to look into it. But for completeness, I'll walk through a matrix vectorization example.

1) Assume that we have a matrix with 10 rows and 30 columns:
matrix = rand(10,30);
and we want extract a window of elements around an arbitrary center (row,column) and analyze that window. And we want to vectorize this, so that we can specify multiple centers and have all their windows be analyzed at the same time.

2) For concreteness, assume our window consists of elements to the left, right, above and below the arbitrary center (row,column).
left = [row col-1]; right = [row col+1];
above = [row-1 col]; below = [row+1 col];

3) Convert the relative row & columns to linear indices. MATLAB matrices are laid out in memory in a column-major fashion (column 1, then column 2, etc.). So left, right, above, below correspond to RELATIVE linear indices -10, +10, -1, +1.
relativeLinearIndices = [-10 +10 -1 +1];

3) Say the matrix location of interest (the center of the window) is row 2, column 5. Get the linear index of that location:
linearIndexOfCenter = sub2ind(size(matrix), 2, 5); % size(matrix) is [10 30]
% linearIndexOfCenter = 42

4) Shift your window to the location of interest
shiftedIndices = relativeLinearIndices  + linearIndexOfCenter;
% shiftedIndices =   [32    52    41    43]

5) Extract the window from your matrix, and manipulate as needed
data = matrix(shiftedIndices) % returns the four elements of the window
numPositive = sum(data > 0.5); % do some analysis

6) We want to vectorize steps 3-5. Say we have two locations of interest: (2,5) and (3,7). Get the linear indices of these centers:
linearIndicesOfCenters = sub2ind(size(matrix), [2 3], [5 7])
% linearIndicesOfCenters = [42 63]

Shift the window for each center
shiftedIndices = [relativeLinearIndices + linearIndicesOfCenters(1);
relativeLinearIndices + linearIndicesOfCenters(2)];
% Fast way of doing the above step
shiftedIndices = bsxfun(@plus, relativeLinearIndices, linearIndicesOfCenters');

Extract the matrix elements for each window
data = matrix(shiftedIndices); % each row is the data for one window
numPositive = sum(data > 0.5, 2); % do vectorized analysis of each row

Caution: Make sure your window always falls within the matrix. In the above example, if we had used the window center of (1,1) or (10,1), we would get an error when we tried to extract the data from the matrix. Either:
* pad your matrix so that this doesn't happen, OR,
* check shiftedIndices for values <1 or >numel(matrix) and handle them in some way.

Cheers,
Gautam
```
 0
Reply Classroom 4/23/2010 3:02:04 PM

```On Apr 23, 7:02=A0pm, "Classroom Resources Team" <nos...@mathworks.com>
wrote:
> "Maks Merlo" <kma...@gmail.com> wrote in message <hqi3vf\$pm...@fred.mathw=
orks.com>...
> > "Gautam Vallabha" <gautam.vallabha.nos...@mathworks.com> wrote in messa=
ge <hqhpds\$ep...@fred.mathworks.com>...
>
> > > Vectorization is not magical ... in most cases, you need to rewrite a=
function so that it can accept vectors instead of scalars.
>
> > > In your case, I suggest the following approach (assuming the size of =
the matrix is fixed). It is a little involved, but conceptually straightfor=
ward.
>
> > > 1) You are always using the same "window" into a matrix, only the cen=
ter of this window changes. Assume the center of the window is (0,0) and de=
rive the matrix indices for these 8 points, i.e:
> > > =A0 =A0left =3D [-1 -1; 0 -1; =A01 -1];
> > > =A0 =A0right =3D [-1 1; 0 1; 1 1];
> > > =A0 =A0middleup =3D [-1 0];
> > > =A0 =A0middledown =A0=3D [1 0];
>
> > > 2) =A0Convert the 8 points into linear indices. (This is what SUB2IND=
does, but in your cases the indices are <=3D 0, so SUB2IND won't work). =
=A0But it is pretty straightforward, see this doc:
> > > =A0http://www.mathworks.com/company/newsletters/digest/sept01/matrix.=
html
>
> > > 3) Now you have a vector of length 8 that defines your window. You ca=
n apply this window to a desired location by (a) getting the linear index o=
f that location and (b) centering the window over that location.
>
> > > 4) For vectorizing, you want to apply your window (vector of length 8=
) to multiple locations at the same time. Assume that you have two location=
s and:
> > > =A0 v1 is the window (vector of linear indices) for location 1
> > > =A0 v2 is the window (vector of linear indices) for location 2
> > > Create a new indexing matrix composed of v1 and v2
> > > =A0 im =3D [v1;v2]
>
> > > 5) Use 'im' to index into your matrix
> > > =A0 =A0 points =3D matrix(im);
> > > apply your test to each row of points. This can be vectorized as well=
..
>
> > > Best,
> > > Gautam
> > Thank you SO MUCH. If it`s not difficult, could you please show me exam=
ple to vectorize through entire matrix?
>
> As someone noted on this thread, CONV2 may be appropriate in this case, a=
nd you want to look into it. But for completeness, I'll walk through a matr=
ix vectorization example.
>
> 1) Assume that we have a matrix with 10 rows and 30 columns:
> =A0 =A0 =A0matrix =3D rand(10,30);
> and we want extract a window of elements around an arbitrary center (row,=
column) and analyze that window. And we want to vectorize this, so that we =
can specify multiple centers and have all their windows be analyzed at the =
same time.
>
> 2) For concreteness, assume our window consists of elements to the left, =
right, above and below the arbitrary center (row,column).
> =A0 =A0left =3D [row col-1]; right =3D [row col+1];
> =A0 above =3D [row-1 col]; below =3D [row+1 col];
>
> 3) Convert the relative row & columns to linear indices. MATLAB matrices =
are laid out in memory in a column-major fashion (column 1, then column 2, =
etc.). So left, right, above, below correspond to RELATIVE linear indices -=
10, +10, -1, +1.
> =A0 relativeLinearIndices =3D [-10 +10 -1 +1];
>
> 3) Say the matrix location of interest (the center of the window) is row =
2, column 5. Get the linear index of that location:
> =A0 =A0linearIndexOfCenter =3D sub2ind(size(matrix), 2, 5); % size(matrix=
) is [10 30]
> =A0 =A0% linearIndexOfCenter =3D 42
>
> 4) Shift your window to the location of interest
> =A0 =A0 shiftedIndices =3D relativeLinearIndices =A0+ linearIndexOfCenter=
;
> =A0 % shiftedIndices =3D =A0 [32 =A0 =A052 =A0 =A041 =A0 =A043]
>
> 5) Extract the window from your matrix, and manipulate as needed
> =A0 =A0data =3D matrix(shiftedIndices) % returns the four elements of the=
window
> =A0 =A0numPositive =3D sum(data > 0.5); % do some analysis
>
> 6) We want to vectorize steps 3-5. Say we have two locations of interest:=
(2,5) and (3,7). Get the linear indices of these centers:
> =A0 linearIndicesOfCenters =3D sub2ind(size(matrix), [2 3], [5 7])
> =A0 % linearIndicesOfCenters =3D [42 63]
>
> Shift the window for each center
> =A0 =A0shiftedIndices =3D [relativeLinearIndices + linearIndicesOfCenters=
(1);
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0relativeLinearIndi=
ces + linearIndicesOfCenters(2)];
> =A0 =A0% Fast way of doing the above step
> =A0 shiftedIndices =3D bsxfun(@plus, relativeLinearIndices, linearIndices=
OfCenters');
>
> Extract the matrix elements for each window
> =A0 =A0data =3D matrix(shiftedIndices); % each row is the data for one wi=
ndow
> =A0 =A0numPositive =3D sum(data > 0.5, 2); % do vectorized analysis of ea=
ch row
>
> Caution: Make sure your window always falls within the matrix. In the abo=
ve example, if we had used the window center of (1,1) or (10,1), we would g=
et an error when we tried to extract the data from the matrix. Either:
> * pad your matrix so that this doesn't happen, OR,
> * check shiftedIndices for values <1 or >numel(matrix) and handle them in=
some way.
>
> Cheers,
> Gautam- Hide quoted text -
>
> - Show quoted text -

hello idont have any guide for simbiology because in my country we
could not use mathwork site i will apriciate if you send me anything
that can guide me to learn simbiology . I coudnt do some part of my
thesis without this guide .I owe you one i be pleased to do it for you
one day
```
 0
Reply moji 6/2/2010 10:13:56 AM

```moji <mojtabarezazadeh121@gmail.com> wrote in message <35734a6d-f46d-4f85-b5e6-17565e8a0c61@40g2000vbr.googlegroups.com>...
> hello idont have any guide for simbiology because in my country we
> could not use mathwork site i will apriciate if you send me anything
> that can guide me to learn simbiology . I coudnt do some part of my
> thesis without this guide .I owe you one i be pleased to do it for you
> one day

Hi,

If you have access to SimBiology, you should also have access to the documentation. Take a look at the accompanying Getting Started Guide.

-Arthur
```
 0
Reply Arthur 6/3/2010 8:19:05 PM

6 Replies
236 Views

(page loaded in 0.33 seconds)

5/25/2013 5:24:36 PM