From: drgz on
Hello,

quick question about vectorization of code.

Is there any way to simplify this with some clever functions I most likely don't know about? I'm attempting to model a nonlinear system by a Volterra series, but as I get to the higher nonlinear orders, the nested for-loops gets quite big in my brute-force attempt :)

So hopefully I'm lucky and this can be solved in a more elegant manner. If not, then I can live with that :)

Below I've pasted the part of code for the 9th order part of the model.

for n1 = 0:M(5)-1
xn1 = delay_signal(x,n1);
for n2 = n1:M(5)-1
xn2 = delay_signal(x,n2);
for n3 = n2:M(5)-1
xn3 = delay_signal(x,n3);
for n4 = n3:M(5)-1
xn4 = delay_signal(x,n4);
for n5 = n4:M(5)-1
xn5 = delay_signal(x,n5);
for n6 = 0:M(5)-1
xn6 = delay_signal(x,n6);
for n7 = n6:M(5)-1
xn7 = delay_signal(x,n7);
for n8 = n7:M(5)-1
xn8 = delay_signal(x,n8);
for n9 = n8:M(5)-1
xn9 = delay_signal(x,n9);
x9 = xn1.*xn2.*xn3.*xn4.*xn5.* ...
conj(xn6).*conj(xn7).* ...
conj(xn8).*conj(xn9);
% Check if x9 exist in X9 matrix
if checkExistence(x9,X9)
continue;
else
n = n+1;
X9(:,n) = x9;
end
end
end
end
end
end
end
end
end
end

Here the different variables are:
- x: input "signal"
- M(): max. delay
- n: index for columns in X9 matrix
- X9: matrix holding the different signal products

- checkExistence: short function for checking whether or not the instantaneous vector already exist in the matrix (I assume there might be a built-in function for this as well in MATLAB?)
- delay_signal: just delay the x-vector by the given number of samples

Best regards,

D.
From: Jan Simon on
Dear drgz,

> for n1 = 0:M(5)-1

Do not calculate "M(5) - 1" again and again. Assign it to an extra variable:
M5_1 = M(5) - 1;
for n1 = 0:M5_1
... etc

> for n6 = 0:M(5)-1
Ar you sure this is not:
for n6 = n5:M(5)-1
???

> for n9 = n8:M(5)-1
> xn9 = delay_signal(x,n9);
> x9 = xn1.*xn2.*xn3.*xn4.*xn5.* ...
> conj(xn6).*conj(xn7).* ...
> conj(xn8).*conj(xn9);

Do not calculate CONJ(xn6) etc. again and again and again. Store it after calculating it once in the corresponding loops.
Even xn1.*xn2.*...*conj(xn8) does not change between iterations of the n9 loop - so calculate it before the loop!

> if checkExistence(x9,X9)
> continue;
> else
> n = n+1;
> X9(:,n) = x9;
> end

Omit the unneeded CONTINUE. I hope, that you have preallocated X9? Otherwise the repeated growing is *very* slow in Matlab.
Because checkExistence is called very often, it is worth to post the code you are using. If X9 gets very big, a sorting might be helpful together with a binary search.

In general: Move as much calculations out of the inner loops as possible!

Kind regards, Jan
From: Andy on
Are you only using checkExistence here?:

if ~checkExistence(x9,X9,n)
n = n+1;
X9(:,n) = x9;
end

If so, it might save a lot of time in function-calling overhead to just inline your check:

if ~isequal(xn,Xn(:,1:n))
n = n+1;
X9(:,n) = x9;
end
From: Dragan on
"Andy " <myfakeemailaddress(a)gmail.com> wrote in message <i3pq6p$d7a$1(a)fred.mathworks.com>...
> Are you only using checkExistence here?:
>
> if ~checkExistence(x9,X9,n)
> n = n+1;
> X9(:,n) = x9;
> end
>
> If so, it might save a lot of time in function-calling overhead to just inline your check:
>
> if ~isequal(xn,Xn(:,1:n))
> n = n+1;
> X9(:,n) = x9;
> end

I could try that as well and see how it compares to the suggestion from Jan, thanks for the tip.

Best regards,

D.
From: Jan Simon on
Dear Andy,

> if ~isequal(xn,Xn(:,1:n))

While "xn" is a vector, "Xn(:, 1:n)" is a matrix. So you have to include a loop in addition.
If the matrix gets really large, apply the STRFIND method in one or more further levels.

Kind regards, Jan