Solving equation with for loop is slow

2 visualizzazioni (ultimi 30 giorni)
Jack_111
Jack_111 il 14 Ott 2013
Risposto: guy tau il 23 Feb 2023
I have an equation (5th order Polynomial) and I have to solve it every time for different variables A,B and Coeff as written down. And the coefficient are quite alot (100000) I had no other way than using the for loop to do it but it is incredibely slow. Could anyone please give me a suggestion to make it faster or if there is another way to solve the equation faster.
This is my code:
tCounter = zeros(length(A),1);
for i = 1:length(A)
syms t
Check = (isnan(B(i,1))==1);
if Check ==1
tCounter(i) = NaN;
else
Equation = -(Coeff(21).*((B(i,2) + t*A(i,2)).^5) + (Coeff(20).*((B(i,2) + t*A(i,2)).^4)).*(B(i,1) + t*A(i,1)) + Coeff(19).*((B(i,2) + t*A(i,2)).^4) + (Coeff(18).*((B(i,2) + t*A(i,2)).^3)).*((B(i,1) + t*A(i,1)).^2) + (Coeff(17).*((B(i,2) + t*A(i,2)).^3)).*(B(i,1) + t*A(i,1)) + Coeff(16).*((B(i,2) + t*A(i,2)).^3) + (Coeff(15).*((B(i,2) + t*A(i,2)).^2)).*((B(i,1) + t*A(i,1)).^3) + (Coeff(14).*((B(i,2) + t*A(i,2)).^2)).*((B(i,1) + t*A(i,1)).^2) + (Coeff(13).*((B(i,2) + t*A(i,2)).^2)).*(B(i,1) + t*A(i,1)) + Coeff(12).*((B(i,2) + t*A(i,2)).^2) + (Coeff(11).*((B(i,2) + t*A(i,2)))).*((B(i,1) + t*A(i,1)).^4) + (Coeff(10).*(B(i,2) + t*A(i,2))).*((B(i,1) + t*A(i,1)).^3) + (Coeff(9).*(B(i,2) + t*A(i,2))).*((B(i,1) + t*A(i,1)).^2) + (Coeff(8).*(B(i,2) + t*A(i,2))).*((B(i,1) + t*A(i,1))) + (Coeff(7).*(B(i,2) + t*A(i,2))) + Coeff(6).*((B(i,1) + t*A(i,1)).^5) + Coeff(5).*((B(i,1) + t*A(i,1)).^4) + Coeff(4).*((B(i,1) + t*A(i,1)).^3) + Coeff(3).*((B(i,1) + t*A(i,1)).^2) + Coeff(2).*(B(i,1) + t*A(i,1)) + Coeff(1)) + Thickness - (B(i,3) + t*A(i,3));
t = solve(Equation,t);
t = double (t);
t(imag(t) ~= 0) = [];
t(t<0) = [];
t = min(t);
tCounter(i) = t;
end
end
Many thanks in advance

Risposta accettata

Walter Roberson
Walter Roberson il 14 Ott 2013
solve() generically outside of the loop and then subs() or matlabFunction() to get code executed for each loop instance.
t = roots( [Coeff(6)*A(i, 1)^5+Coeff(11)*A(i, 1)^4*A(i, 2)+Coeff(15)*A(i, 1)^3*A(i, 2)^2+Coeff(18)*A(i, 1)^2*A(i, 2)^3+Coeff(20)*A(i, 1)*A(i, 2)^4+Coeff(21)*A(i, 2)^5,
(5*Coeff(6)*B(i, 1)+Coeff(11)*B(i, 2)+Coeff(5))*A(i, 1)^4+(2*(2*Coeff(11)*B(i, 1)+Coeff(15)*B(i, 2)+(1/2)*Coeff(10)))*A(i, 1)^3*A(i, 2)+(3*Coeff(15)*B(i, 1)+3*Coeff(18)*B(i, 2)+Coeff(14))*A(i, 1)^2*A(i, 2)^2+(2*Coeff(18)*B(i, 1)+4*Coeff(20)*B(i, 2)+Coeff(17))*A(i, 1)*A(i, 2)^3+(Coeff(20)*B(i, 1)+5*Coeff(21)*B(i, 2)+Coeff(19))*A(i, 2)^4,
(10*Coeff(6)*B(i, 1)^2+Coeff(15)*B(i, 2)^2+(4*Coeff(11)*B(i, 2)+4*Coeff(5))*B(i, 1)+Coeff(10)*B(i, 2)+Coeff(4))*A(i, 1)^3+(3*(2*Coeff(11)*B(i, 1)^2+Coeff(18)*B(i, 2)^2+(2*Coeff(15)*B(i, 2)+Coeff(10))*B(i, 1)+(2/3)*Coeff(14)*B(i, 2)+(1/3)*Coeff(9)))*A(i, 1)^2*A(i, 2)+(3*Coeff(15)*B(i, 1)^2+6*Coeff(20)*B(i, 2)^2+(6*Coeff(18)*B(i, 2)+2*Coeff(14))*B(i, 1)+3*Coeff(17)*B(i, 2)+Coeff(13))*A(i, 1)*A(i, 2)^2+(Coeff(18)*B(i, 1)^2+10*Coeff(21)*B(i, 2)^2+(4*Coeff(20)*B(i, 2)+Coeff(17))*B(i, 1)+4*Coeff(19)*B(i, 2)+Coeff(16))*A(i, 2)^3,
(10*Coeff(6)*B(i, 1)^3+Coeff(18)*B(i, 2)^3+(6*Coeff(11)*B(i, 2)+6*Coeff(5))*B(i, 1)^2+Coeff(14)*B(i, 2)^2+(3*Coeff(15)*B(i, 2)^2+3*Coeff(10)*B(i, 2)+3*Coeff(4))*B(i, 1)+Coeff(9)*B(i, 2)+Coeff(3))*A(i, 1)^2+(4*Coeff(11)*B(i, 1)^3+4*Coeff(20)*B(i, 2)^3+(6*Coeff(15)*B(i, 2)+3*Coeff(10))*B(i, 1)^2+3*Coeff(17)*B(i, 2)^2+(6*Coeff(18)*B(i, 2)^2+4*Coeff(14)*B(i, 2)+2*Coeff(9))*B(i, 1)+2*Coeff(13)*B(i, 2)+Coeff(8))*A(i, 1)*A(i, 2)+(Coeff(15)*B(i, 1)^3+10*Coeff(21)*B(i, 2)^3+(3*Coeff(18)*B(i, 2)+Coeff(14))*B(i, 1)^2+6*Coeff(19)*B(i, 2)^2+(6*Coeff(20)*B(i, 2)^2+3*Coeff(17)*B(i, 2)+Coeff(13))*B(i, 1)+3*Coeff(16)*B(i, 2)+Coeff(12))*A(i, 2)^2,
(5*Coeff(6)*A(i, 1)+Coeff(11)*A(i, 2))*B(i, 1)^4+(Coeff(20)*A(i, 1)+5*Coeff(21)*A(i, 2))*B(i, 2)^4+(4*Coeff(5)*A(i, 1)+Coeff(10)*A(i, 2)+(4*Coeff(11)*A(i, 1)+2*Coeff(15)*A(i, 2))*B(i, 2))*B(i, 1)^3+(Coeff(17)*A(i, 1)+4*Coeff(19)*A(i, 2))*B(i, 2)^3+((3*Coeff(15)*A(i, 1)+3*Coeff(18)*A(i, 2))*B(i, 2)^2+3*Coeff(4)*A(i, 1)+Coeff(9)*A(i, 2)+(3*Coeff(10)*A(i, 1)+2*Coeff(14)*A(i, 2))*B(i, 2))*B(i, 1)^2+(Coeff(13)*A(i, 1)+3*Coeff(16)*A(i, 2))*B(i, 2)^2+Coeff(2)*A(i, 1)+Coeff(7)*A(i, 2)+A(i, 3)+((2*Coeff(18)*A(i, 1)+4*Coeff(20)*A(i, 2))*B(i, 2)^3+(2*Coeff(14)*A(i, 1)+3*Coeff(17)*A(i, 2))*B(i, 2)^2+2*Coeff(3)*A(i, 1)+Coeff(8)*A(i, 2)+(2*Coeff(9)*A(i, 1)+2*Coeff(13)*A(i, 2))*B(i, 2))*B(i, 1)+(Coeff(8)*A(i, 1)+2*Coeff(12)*A(i, 2))*B(i, 2),
Coeff(6)*B(i, 1)^5+Coeff(21)*B(i, 2)^5+(Coeff(11)*B(i, 2)+Coeff(5))*B(i, 1)^4+Coeff(19)*B(i, 2)^4+(Coeff(15)*B(i, 2)^2+Coeff(10)*B(i, 2)+Coeff(4))*B(i, 1)^3+Coeff(16)*B(i, 2)^3+(Coeff(18)*B(i, 2)^3+Coeff(14)*B(i, 2)^2+Coeff(9)*B(i, 2)+Coeff(3))*B(i, 1)^2+Coeff(12)*B(i, 2)^2-Thickness+(Coeff(20)*B(i, 2)^4+Coeff(17)*B(i, 2)^3+Coeff(13)*B(i, 2)^2+Coeff(8)*B(i, 2)+Coeff(2))*B(i, 1)+Coeff(7)*B(i, 2)+B(i, 3)+Coeff(1) ] );
and then do the filtering like you had before.
  4 Commenti
Walter Roberson
Walter Roberson il 14 Ott 2013
I solve()'d in Maple. You could do the equivalent using
syms A B i t
Equation = -(Coeff(21).*((B(i,2) + t*A(i,2)).^5) + (Coeff(20).*((B(i,2) + t*A(i,2)).^4)).*(B(i,1) + t*A(i,1)) + Coeff(19).*((B(i,2) + t*A(i,2)).^4) + (Coeff(18).*((B(i,2) + t*A(i,2)).^3)).*((B(i,1) + t*A(i,1)).^2) + (Coeff(17).*((B(i,2) + t*A(i,2)).^3)).*(B(i,1) + t*A(i,1)) + Coeff(16).*((B(i,2) + t*A(i,2)).^3) + (Coeff(15).*((B(i,2) + t*A(i,2)).^2)).*((B(i,1) + t*A(i,1)).^3) + (Coeff(14).*((B(i,2) + t*A(i,2)).^2)).*((B(i,1) + t*A(i,1)).^2) + (Coeff(13).*((B(i,2) + t*A(i,2)).^2)).*(B(i,1) + t*A(i,1)) + Coeff(12).*((B(i,2) + t*A(i,2)).^2) + (Coeff(11).*((B(i,2) + t*A(i,2)))).*((B(i,1) + t*A(i,1)).^4) + (Coeff(10).*(B(i,2) + t*A(i,2))).*((B(i,1) + t*A(i,1)).^3) + (Coeff(9).*(B(i,2) + t*A(i,2))).*((B(i,1) + t*A(i,1)).^2) + (Coeff(8).*(B(i,2) + t*A(i,2))).*((B(i,1) + t*A(i,1))) + (Coeff(7).*(B(i,2) + t*A(i,2))) + Coeff(6).*((B(i,1) + t*A(i,1)).^5) + Coeff(5).*((B(i,1) + t*A(i,1)).^4) + Coeff(4).*((B(i,1) + t*A(i,1)).^3) + Coeff(3).*((B(i,1) + t*A(i,1)).^2) + Coeff(2).*(B(i,1) + t*A(i,1)) + Coeff(1)) + Thickness - (B(i,3) + t*A(i,3));
tsym = solve(simplify(Equation), t);
tfun = matlabFunction(tsym, 'vars', {'A', 'B', 'i'});
then
for i = 1:length(realA)
if isnan(B(i,1))
tCounter(i) = NaN;
else
t = tfun(realA, realB, i);
t(imag(t) ~= 0) = [];
t(t<0) = [];
t = min(t);
tCounter(i) = t;
end
end
The "for" loop is still there, but the solve() has been done only once, and then each iteration of the loop the anonymous function equivalent of the solution is used, passing in appropriate parameters.
Jack_111
Jack_111 il 14 Ott 2013
It was more than perfect
Big thanks

Accedi per commentare.

Più risposte (1)

guy tau
guy tau il 23 Feb 2023
Hi @Wlater, a very late replay, buy unfortentaly, i'm currently dealing with a simialr issue, and hopfully you can assisit me as well.
I have large table of data (~30000 rows), in which I use the solver function on some of the varibles from the table to predect and compare to a known sampled varible.
I tried your suggested code, wrtiren as:
syms a.var1 a.var2 a.var3 a.var4 i X
Equation = ((a.var1(i) -c1*(X)^4)- (c2*a.var2(i)*(6.105.*exp((c3*X)./(x+c4)) -a.var3(i))) - (c5*(x-a.var4(i)))) = 0;
tsym = solve(simplify(Equation), X);
tfun = matlabFunction(tsym, 'vars', {'a.var1', 'a.var2', 'a.var3', 'a.var4','i'});
for i = 1:height(a)
t(i) = tfun(a.var1,a.var2,a.var3,a.var4, i);
end
where
c1,c2,c3,c4 and c5 are constants
and a.var1 to a.var 4 are the varibiles from the table
Unfortunately I got the follwing error back
Error using sym/subsindex
Invalid indexing or function definition. Indexing must follow MATLAB indexing. Function arguments must be symbolic variables, and function body must be sym expression.
Error in indexing (line 1075)
R_tilde = builtin('subsref',L_tilde,Idx);
Related documentation
I assume the problem is realted to the index table, but i'm struggling the find the solution
If other solution pop's to your mind that will be great as well.
currently, letting the loop run by just using solver is just to slow...

Tag

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by