I have a long equation written in coffeescript, which turns in a function call when compiled to JavaScript:
CoffeeScript:
#u[idx] = #max(0, currU + t * ((#dU * ((#uu[right] + #uu[left] + #uu[bottom] + #uu[top]) -4 * currU) - d2) + currF * (1.0 - currU)))
JavaScript:
this.max(0, currU + t * ((this.dU * ((this.uu[right] + this.uu[left] + this.uu[bottom] + this.uu[top])(-4 * currU)) - d2) + currF * (1.0 - currU)));
The problem is this part:
((#uu[right] + #uu[left] + #uu[bottom] + #uu[top]) -4 * currU)
which turns into a function call:
((this.uu[right] + this.uu[left] + this.uu[bottom] + this.uu[top])(-4 * currU))
Can someone explain whats going on here.
You want this:
#u[idx] = #max(0, currU + t * ((#dU * ((#uu[right] + #uu[left] + #uu[bottom] + #uu[top]) - 4 * currU) - d2) + currF * (1.0 - currU)))
Which compiles to:
this.u[idx] = this.max(0, currU + t * ((this.dU * ((this.uu[right] + this.uu[left] + this.uu[bottom] + this.uu[top]) - 4 * currU) - d2) + currF * (1.0 - currU)));
The silly little issue is the -4, vs - 4.
Without the space, the compiler assumes the -4 * currU to be an argument to the 'function' , (#uu[right] + #uu[left] + #uu[bottom] + #uu[top]).
Related
I would like to create Matlab codes that automatically convert ODEs to state space matrix. All I need is the A matrix and B matrix.
I have partially finished it and this is what it looks like. After I run this code, I copy and paste the result V that is displayed on the command window into a spreadsheet and manually find the A and B matrices. Does anyone know how I can create a code so it automatically displays the A and B matrices on the command window? I have 14 states, 4 inputs, 4 disturbance inputs by the way.
Thanks.
syms x1(t) x2(t) x3(t) x4(t) x5(t) x6(t) x7(t) x8(t) x9(t) x10(t) x11(t) x12(t) x13(t) x14(t) t;
syms Ms Ir Ip m_1 m_2 m_3 m_4 b_1 b_2 b_3 b_4 ks1 ks2 ks3 ks4 a_dis b_dis Tf Tr ku1 ku2 ku3 ku4 zs1 zs2 zs3 zs4;
syms u1(t) u2(t) u3(t) u4(t) w1(t) w2(t) w3(t) w4(t);
zs1=-Tf*x1-a_dis*x2+x3;
zs2=+Tf*x1-a_dis*x2+x3;
zs3=-Tr*x1+b_dis*x2+x3;
zs4=+Tr*x1+b_dis*x2+x3;
Fd1=b_1*(diff(zs1)-x11);
Fd2=b_2*(diff(zs2)-x12);
Fd3=b_3*(diff(zs3)-x13);
Fd4=b_4*(diff(zs4)-x14);
Fs1=ks1*(zs1-x4);
Fs2=ks2*(zs2-x5);
Fs3=ks3*(zs3-x6);
Fs4=ks4*(zs4-x7);
Fu1= ku1*(x4-w1);
Fu2= ku2*(x5-w2);
Fu3= ku3*(x6-w3);
Fu4= ku4*(x7-w4);
DEq1 = diff(x1)== x8;
DEq2 = diff(x2)== x9;
DEq3 = diff(x3)== x10;
DEq4 = diff(x4)== x11;
DEq5 = diff(x5)== x12;
DEq6 = diff(x6)== x13;
DEq7 = diff(x7)== x14;
DEq8 = Ir*diff(x8)== -Fd1*Tf+Fd2*Tf-Fd3*Tr+Fd4*Tr-Fs1*Tf+Fs2*Tf-Fs3*Tr+Fs4*Tr+u1*Tf-u2*Tf+u3*Tr-u4*Tr;
DEq9 = Ip*diff(x9)== -Fd1*a_dis-Fd2*a_dis+Fd3*b_dis+Fd4*b_dis-Fs1*a_dis-Fs2*a_dis+Fs3*b_dis+Fs4*b_dis+u1*a_dis+u2*a_dis-u3*b_dis-u4*b_dis;
DEq10 = Ms*diff(x10)== -Fd1-Fd2-Fd3-Fd4-Fs1-Fs2-Fs3-Fs4+u1+u2+u3+u4;
DEq11 = m_1*diff(x11)== Fd1+Fs1-Fu1-u1;
DEq12 = m_2*diff(x12)== Fd2+Fs2-Fu2-u2;
DEq13 = m_3*diff(x13)== Fd3+Fs3-Fu3-u3;
DEq14 = m_4*diff(x14)== Fd4+Fs4-Fu4-u4;
[V,S] = odeToVectorField(DEq1,DEq2,DEq3,DEq4,DEq5,DEq6,DEq7,DEq8,DEq9,DEq10,DEq11,DEq12,DEq13,DEq14)
What gets displayed on the command window after running the above code is this.
V =
Y[8]
Y[9]
Y[10]
Y[11]
Y[12]
Y[13]
Y[14]
(Tf*u1(t) - Tf*u2(t) + Tr*u3(t) - Tr*u4(t) + Tf^2*b_1*Y[8] + Tf^2*b_2*Y[8] + Tr^2*b_3*Y[8] + Tr^2*b_4*Y[8] + Tf^2*ks1*Y[1] + Tf^2*ks2*Y[1] + Tr^2*ks3*Y[1] + Tr^2*ks4*Y[1] - Tf*b_1*Y[10] + Tf*b_1*Y[11] + Tf*b_2*Y[10] - Tf*b_2*Y[12] - Tr*b_3*Y[10] + Tr*b_4*Y[10] + Tr*b_3*Y[13] - Tr*b_4*Y[14] - Tf*ks1*Y[3] + Tf*ks1*Y[4] + Tf*ks2*Y[3] - Tf*ks2*Y[5] - Tr*ks3*Y[3] + Tr*ks4*Y[3] + Tr*ks3*Y[6] - Tr*ks4*Y[7] + Tf*a_dis*b_1*Y[9] - Tf*a_dis*b_2*Y[9] - Tr*b_3*b_dis*Y[9] + Tr*b_4*b_dis*Y[9] + Tf*a_dis*ks1*Y[2] - Tf*a_dis*ks2*Y[2] - Tr*b_dis*ks3*Y[2] + Tr*b_dis*ks4*Y[2])/Ir
(a_dis*u1(t) + a_dis*u2(t) - b_dis*u3(t) - b_dis*u4(t) + a_dis^2*b_1*Y[9] + a_dis^2*b_2*Y[9] + b_3*b_dis^2*Y[9] + b_4*b_dis^2*Y[9] + a_dis^2*ks1*Y[2] + a_dis^2*ks2*Y[2] + b_dis^2*ks3*Y[2] + b_dis^2*ks4*Y[2] - a_dis*b_1*Y[10] + a_dis*b_1*Y[11] - a_dis*b_2*Y[10] + a_dis*b_2*Y[12] + b_3*b_dis*Y[10] + b_4*b_dis*Y[10] - b_3*b_dis*Y[13] - b_4*b_dis*Y[14] - a_dis*ks1*Y[3] + a_dis*ks1*Y[4] - a_dis*ks2*Y[3] + a_dis*ks2*Y[5] + b_dis*ks3*Y[3] + b_dis*ks4*Y[3] - b_dis*ks3*Y[6] - b_dis*ks4*Y[7] + Tf*a_dis*b_1*Y[8] - Tf*a_dis*b_2*Y[8] - Tr*b_3*b_dis*Y[8] + Tr*b_4*b_dis*Y[8] + Tf*a_dis*ks1*Y[1] - Tf*a_dis*ks2*Y[1] - Tr*b_dis*ks3*Y[1] + Tr*b_dis*ks4*Y[1])/Ip
(u1(t) + u2(t) + u3(t) + u4(t) - b_1*Y[10] + b_1*Y[11] - b_2*Y[10] - b_3*Y[10] + b_2*Y[12] - b_4*Y[10] + b_3*Y[13] + b_4*Y[14] - ks1*Y[3] + ks1*Y[4] - ks2*Y[3] - ks3*Y[3] + ks2*Y[5] - ks4*Y[3] + ks3*Y[6] + ks4*Y[7] + Tf*b_1*Y[8] - Tf*b_2*Y[8] + Tr*b_3*Y[8] - Tr*b_4*Y[8] + Tf*ks1*Y[1] - Tf*ks2*Y[1] + Tr*ks3*Y[1] - Tr*ks4*Y[1] + a_dis*b_1*Y[9] + a_dis*b_2*Y[9] - b_3*b_dis*Y[9] - b_4*b_dis*Y[9] + a_dis*ks1*Y[2] + a_dis*ks2*Y[2] - b_dis*ks3*Y[2] - b_dis*ks4*Y[2])/Ms
-(u1(t) - b_1*Y[10] + b_1*Y[11] - ks1*Y[3] + ks1*Y[4] + ku1*Y[4] - ku1*w1(t) + Tf*b_1*Y[8] + Tf*ks1*Y[1] + a_dis*b_1*Y[9] + a_dis*ks1*Y[2])/m_1
-(u2(t) - b_2*Y[10] + b_2*Y[12] - ks2*Y[3] + ks2*Y[5] + ku2*Y[5] - ku2*w2(t) - Tf*b_2*Y[8] - Tf*ks2*Y[1] + a_dis*b_2*Y[9] + a_dis*ks2*Y[2])/m_2
-(u3(t) - b_3*Y[10] + b_3*Y[13] - ks3*Y[3] + ks3*Y[6] + ku3*Y[6] - ku3*w3(t) + Tr*b_3*Y[8] + Tr*ks3*Y[1] - b_3*b_dis*Y[9] - b_dis*ks3*Y[2])/m_3
(b_4*Y[10] - u4(t) - b_4*Y[14] + ks4*Y[3] - ks4*Y[7] - ku4*Y[7] + ku4*w4(t) + Tr*b_4*Y[8] + Tr*ks4*Y[1] + b_4*b_dis*Y[9] + b_dis*ks4*Y[2])/m_4
Using Matlab's subs function is the less ugly way I have found to do it. You'll get a 14x14 sym matrix:
A = repmat(V,1,14);
for j=1:14
y = double((1:14)==j);
A(:,j) = subs(A(:,j), 'Y[1]', y(1));
A(:,j) = subs(A(:,j), 'Y[2]', y(2));
A(:,j) = subs(A(:,j), 'Y[3]', y(3));
A(:,j) = subs(A(:,j), 'Y[4]', y(4));
A(:,j) = subs(A(:,j), 'Y[5]', y(5));
A(:,j) = subs(A(:,j), 'Y[6]', y(6));
A(:,j) = subs(A(:,j), 'Y[7]', y(7));
A(:,j) = subs(A(:,j), 'Y[8]', y(8));
A(:,j) = subs(A(:,j), 'Y[9]', y(9));
A(:,j) = subs(A(:,j), 'Y[10]', y(10));
A(:,j) = subs(A(:,j), 'Y[11]', y(11));
A(:,j) = subs(A(:,j), 'Y[12]', y(12));
A(:,j) = subs(A(:,j), 'Y[13]', y(13));
A(:,j) = subs(A(:,j), 'Y[14]', y(14));
end
You can get rid of all the lines by using eval function:
A = repmat(V,1,14);
for j=1:14
y = double((1:14)==j);
for k=1:14
A(:,j) = eval(sprintf('subs(A(:,j), ''Y[%d]'', y(%d));',k,k));
end
end
In the column j, we are replacing Y[i] by 1 if i==j else 0.
Test:
>> size(A)
ans =
14 14
>> A(:,10)
ans =
0
0
1
0
0
0
0
-(Tf*b_1 - Tf*b_2 + Tr*b_3 - Tr*b_4 - Tf*u1(t) + Tf*u2(t) - Tr*u3(t) + Tr*u4(t))/Ir
-(a_dis*b_1 + a_dis*b_2 - b_3*b_dis - b_4*b_dis - a_dis*u1(t) - a_dis*u2(t) + b_dis*u3(t) + b_dis*u4(t))/Ip
-(b_1 + b_2 + b_3 + b_4 - u1(t) - u2(t) - u3(t) - u4(t))/Ms
(b_1 - u1(t) + ku1*w1(t))/m_1
(b_2 - u2(t) + ku2*w2(t))/m_2
(b_3 - u3(t) + ku3*w3(t))/m_3
(b_4 - u4(t) + ku4*w4(t))/m_4
I want to solve this equation in MATLAB. I know via numerical solver that some of the roots are imaginary and others real. Using solve, MATLAB spits out a list of conditions under which the solution is valid.
I just want MATLAB to solve this with an analytical solution (not numerically, I can do this in Mathematica). Is there a better solution, or any other package that I can use?
syms f2 ep1 ep2 a1 a2 fp1 fp2 h e1 m1 mp R f r t1 f1
eqn = (((ep2*fp1 - ep1*fp2)*mp*(e1*m1*(ep2*f2*fp1*(fp2 - a2*mp) +...
ep1*fp2*(-(f1*fp2) + a2*f2*mp))*(h + R) + a2*f2*(-(ep2*f*f2*fp1*R)+...
ep1*f*f1*fp2*R - ...
ep1*ep2*(f1 - f2)*mp*r*(h + R)))* (a1*ep1*ep2*f1*(f1 - f2)...
*mp*(ep2*f*f2*fp1*R - ep1*f*f1*fp2*R + ep1*ep2*(f1 - f2)*mp*r*(h + R)) +...
e1*(ep2^2*f*f2^2*fp1^2*R*t1 + ...
ep1^2*f1*fp2*(f*f1*fp2*R*t1 - ep2*(f1 - f2)*mp*(h + R)*(-(fp1*m1) + ...
a1*m1*mp + r*t1)) + ...
ep1*ep2*fp1*(-2*f*f1*f2*fp2*R*t1 + ep2*(f1 - f2)*mp*(h + R)*(-(f2*fp1*m1)+...
a1*f1*m1*mp + f2*r*t1)))))/...
(e1*ep1*ep2*(ep2*f2*fp1 - ep1*f1*fp2)^2*(h + R)^2*(ep1*ep2*(f1 - f2)*...
(-(a2*f2*fp1) + a1*f1*fp2)*mp + e1*(ep2*f2*fp1*(fp2 - a2*mp) + ...
ep1*fp2*(-(f1*fp2) + a2*f2*mp))*t1))) * (-1) == 0;
solve(eqn,fp1)
The solutions I get are:
(a2*f2*(R*ep1*f*f1*fp2 - ep1*ep2*mp*r*(R + h)*(f1 - f2)) - e1*ep1*fp2*m1*(R + h)*(f1*fp2 - a2*f2*mp))/(R*a2*ep2*f*f2^2 - e1*ep2*m1*(R + h)*(fp2 - a2*mp)*f2)
(ep1*fp2)/ep2
(ep1*f1*mp*(R^2*a1^2*e1^2*ep2^2*f1^2*m1^2*mp^2 + 2*R^2*a1^2*e1*ep2^2*f*f1^2*f2*m1*mp + R^2*a1^2*ep2^2*f^2*f1^2*f2^2 + 2*R^2*a1*e1^2*ep1*ep2*f1^2*fp2*m1^2*mp - 4*R^2*a1*e1^2*ep1*ep2*f1*f2*fp2*m1^2*mp + 2*R^2*a1*e1^2*ep2^2*f1*f2*m1*mp*r*t1 - 4*R^2*a1*e1^2*ep2*f*f1*f2*fp2*m1*t1 + 4*R^2*a1*e1*ep1*ep2^2*f1^2*f2*m1*mp*r - 4*R^2*a1*e1*ep1*ep2^2*f1*f2^2*m1*mp*r - 2*R^2*a1*e1*ep1*ep2*f*f1^2*f2*fp2*m1 - 2*R^2*a1*e1*ep2^2*f*f1*f2^2*r*t1 + R^2*e1^2*ep1^2*f1^2*fp2^2*m1^2 - 2*R^2*e1^2*ep1*ep2*f1*f2*fp2*m1*r*t1 + R^2*e1^2*ep2^2*f2^2*r^2*t1^2 + 2*R*a1^2*e1^2*ep2^2*f1^2*h*m1^2*mp^2 + 2*R*a1^2*e1*ep2^2*f*f1^2*f2*h*m1*mp + 4*R*a1*e1^2*ep1*ep2*f1^2*fp2*h*m1^2*mp - 8*R*a1*e1^2*ep1*ep2*f1*f2*fp2*h*m1^2*mp + 4*R*a1*e1^2*ep2^2*f1*f2*h*m1*mp*r*t1 - 4*R*a1*e1^2*ep2*f*f1*f2*fp2*h*m1*t1 + 8*R*a1*e1*ep1*ep2^2*f1^2*f2*h*m1*mp*r - 8*R*a1*e1*ep1*ep2^2*f1*f2^2*h*m1*mp*r - 2*R*a1*e1*ep1*ep2*f*f1^2*f2*fp2*h*m1 - 2*R*a1*e1*ep2^2*f*f1*f2^2*h*r*t1 + 2*R*e1^2*ep1^2*f1^2*fp2^2*h*m1^2 - 4*R*e1^2*ep1*ep2*f1*f2*fp2*h*m1*r*t1 +\\\r\n 2*R*e1^2*ep2^2*f2^2*h*r^2*t1^2 + a1^2*e1^2*ep2^2*f1^2*h^2*m1^2*mp^2 + 2*a1*e1^2*ep1*ep2*f1^2*fp2*h^2*m1^2*mp - 4*a1*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1^2*mp + 2*a1*e1^2*ep2^2*f1*f2*h^2*m1*mp*r*t1 + 4*a1*e1*ep1*ep2^2*f1^2*f2*h^2*m1*mp*r - 4*a1*e1*ep1*ep2^2*f1*f2^2*h^2*m1*mp*r + e1^2*ep1^2*f1^2*fp2^2*h^2*m1^2 - 2*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1*r*t1 + e1^2*ep2^2*f2^2*h^2*r^2*t1^2)^(1/2) - ep1*f2*mp*(R^2*a1^2*e1^2*ep2^2*f1^2*m1^2*mp^2 + 2*R^2*a1^2*e1*ep2^2*f*f1^2*f2*m1*mp + R^2*a1^2*ep2^2*f^2*f1^2*f2^2 + 2*R^2*a1*e1^2*ep1*ep2*f1^2*fp2*m1^2*mp - 4*R^2*a1*e1^2*ep1*ep2*f1*f2*fp2*m1^2*mp + 2*R^2*a1*e1^2*ep2^2*f1*f2*m1*mp*r*t1 - 4*R^2*a1*e1^2*ep2*f*f1*f2*fp2*m1*t1 + 4*R^2*a1*e1*ep1*ep2^2*f1^2*f2*m1*mp*r - 4*R^2*a1*e1*ep1*ep2^2*f1*f2^2*m1*mp*r - 2*R^2*a1*e1*ep1*ep2*f*f1^2*f2*fp2*m1 - 2*R^2*a1*e1*ep2^2*f*f1*f2^2*r*t1 + R^2*e1^2*ep1^2*f1^2*fp2^2*m1^2 - 2*R^2*e1^2*ep1*ep2*f1*f2*fp2*m1*r*t1 + R^2*e1^2*ep2^2*f2^2*r^2*t1^2 + 2*R*a1^2*e1^2*ep2^2*f1^2*h*m1^2*mp^2 + 2*R*a1^2*e1*ep2^2*f*f1^2*f2*h*m1*mp + 4*R*a\\\r\n1*e1^2*ep1*ep2*f1^2*fp2*h*m1^2*mp - 8*R*a1*e1^2*ep1*ep2*f1*f2*fp2*h*m1^2*mp + 4*R*a1*e1^2*ep2^2*f1*f2*h*m1*mp*r*t1 - 4*R*a1*e1^2*ep2*f*f1*f2*fp2*h*m1*t1 + 8*R*a1*e1*ep1*ep2^2*f1^2*f2*h*m1*mp*r - 8*R*a1*e1*ep1*ep2^2*f1*f2^2*h*m1*mp*r - 2*R*a1*e1*ep1*ep2*f*f1^2*f2*fp2*h*m1 - 2*R*a1*e1*ep2^2*f*f1*f2^2*h*r*t1 + 2*R*e1^2*ep1^2*f1^2*fp2^2*h*m1^2 - 4*R*e1^2*ep1*ep2*f1*f2*fp2*h*m1*r*t1 + 2*R*e1^2*ep2^2*f2^2*h*r^2*t1^2 + a1^2*e1^2*ep2^2*f1^2*h^2*m1^2*mp^2 + 2*a1*e1^2*ep1*ep2*f1^2*fp2*h^2*m1^2*mp - 4*a1*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1^2*mp + 2*a1*e1^2*ep2^2*f1*f2*h^2*m1*mp*r*t1 + 4*a1*e1*ep1*ep2^2*f1^2*f2*h^2*m1*mp*r - 4*a1*e1*ep1*ep2^2*f1*f2^2*h^2*m1*mp*r + e1^2*ep1^2*f1^2*fp2^2*h^2*m1^2 - 2*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1*r*t1 + e1^2*ep2^2*f2^2*h^2*r^2*t1^2)^(1/2) - R*e1*ep1^2*f1^2*fp2*m1*mp - e1*ep1^2*f1^2*fp2*h*m1*mp + e1*ep1*ep2*f2^2*h*mp*r*t1 - R*a1*e1*ep1*ep2*f1^2*m1*mp^2 - a1*e1*ep1*ep2*f1^2*h*m1*mp^2 + 2*R*e1*ep1*f*f1*f2*fp2*t1 + R*a1*ep1*ep2*f*f1*f2^2*mp - R*a1*ep1*ep2*f*f1^2*f2*mp + R*e1\\\r\n*ep1^2*f1*f2*fp2*m1*mp + R*e1*ep1*ep2*f2^2*mp*r*t1 + e1*ep1^2*f1*f2*fp2*h*m1*mp - R*e1*ep1*ep2*f1*f2*mp*r*t1 - e1*ep1*ep2*f1*f2*h*mp*r*t1 + R*a1*e1*ep1*ep2*f1*f2*m1*mp^2 + a1*e1*ep1*ep2*f1*f2*h*m1*mp^2)/(2*e1*ep2*f2*(R*f*f2*t1 - R*ep1*f1*m1*mp + R*ep1*f2*m1*mp - ep1*f1*h*m1*mp + ep1*f2*h*m1*mp))
(ep1*f2*mp*(R^2*a1^2*e1^2*ep2^2*f1^2*m1^2*mp^2 + 2*R^2*a1^2*e1*ep2^2*f*f1^2*f2*m1*mp + R^2*a1^2*ep2^2*f^2*f1^2*f2^2 + 2*R^2*a1*e1^2*ep1*ep2*f1^2*fp2*m1^2*mp - 4*R^2*a1*e1^2*ep1*ep2*f1*f2*fp2*m1^2*mp + 2*R^2*a1*e1^2*ep2^2*f1*f2*m1*mp*r*t1 - 4*R^2*a1*e1^2*ep2*f*f1*f2*fp2*m1*t1 + 4*R^2*a1*e1*ep1*ep2^2*f1^2*f2*m1*mp*r - 4*R^2*a1*e1*ep1*ep2^2*f1*f2^2*m1*mp*r - 2*R^2*a1*e1*ep1*ep2*f*f1^2*f2*fp2*m1 - 2*R^2*a1*e1*ep2^2*f*f1*f2^2*r*t1 + R^2*e1^2*ep1^2*f1^2*fp2^2*m1^2 - 2*R^2*e1^2*ep1*ep2*f1*f2*fp2*m1*r*t1 + R^2*e1^2*ep2^2*f2^2*r^2*t1^2 + 2*R*a1^2*e1^2*ep2^2*f1^2*h*m1^2*mp^2 + 2*R*a1^2*e1*ep2^2*f*f1^2*f2*h*m1*mp + 4*R*a1*e1^2*ep1*ep2*f1^2*fp2*h*m1^2*mp - 8*R*a1*e1^2*ep1*ep2*f1*f2*fp2*h*m1^2*mp + 4*R*a1*e1^2*ep2^2*f1*f2*h*m1*mp*r*t1 - 4*R*a1*e1^2*ep2*f*f1*f2*fp2*h*m1*t1 + 8*R*a1*e1*ep1*ep2^2*f1^2*f2*h*m1*mp*r - 8*R*a1*e1*ep1*ep2^2*f1*f2^2*h*m1*mp*r - 2*R*a1*e1*ep1*ep2*f*f1^2*f2*fp2*h*m1 - 2*R*a1*e1*ep2^2*f*f1*f2^2*h*r*t1 + 2*R*e1^2*ep1^2*f1^2*fp2^2*h*m1^2 - 4*R*e1^2*ep1*ep2*f1*f2*fp2*h*m1*r*t1 +\\\r\n 2*R*e1^2*ep2^2*f2^2*h*r^2*t1^2 + a1^2*e1^2*ep2^2*f1^2*h^2*m1^2*mp^2 + 2*a1*e1^2*ep1*ep2*f1^2*fp2*h^2*m1^2*mp - 4*a1*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1^2*mp + 2*a1*e1^2*ep2^2*f1*f2*h^2*m1*mp*r*t1 + 4*a1*e1*ep1*ep2^2*f1^2*f2*h^2*m1*mp*r - 4*a1*e1*ep1*ep2^2*f1*f2^2*h^2*m1*mp*r + e1^2*ep1^2*f1^2*fp2^2*h^2*m1^2 - 2*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1*r*t1 + e1^2*ep2^2*f2^2*h^2*r^2*t1^2)^(1/2) - ep1*f1*mp*(R^2*a1^2*e1^2*ep2^2*f1^2*m1^2*mp^2 + 2*R^2*a1^2*e1*ep2^2*f*f1^2*f2*m1*mp + R^2*a1^2*ep2^2*f^2*f1^2*f2^2 + 2*R^2*a1*e1^2*ep1*ep2*f1^2*fp2*m1^2*mp - 4*R^2*a1*e1^2*ep1*ep2*f1*f2*fp2*m1^2*mp + 2*R^2*a1*e1^2*ep2^2*f1*f2*m1*mp*r*t1 - 4*R^2*a1*e1^2*ep2*f*f1*f2*fp2*m1*t1 + 4*R^2*a1*e1*ep1*ep2^2*f1^2*f2*m1*mp*r - 4*R^2*a1*e1*ep1*ep2^2*f1*f2^2*m1*mp*r - 2*R^2*a1*e1*ep1*ep2*f*f1^2*f2*fp2*m1 - 2*R^2*a1*e1*ep2^2*f*f1*f2^2*r*t1 + R^2*e1^2*ep1^2*f1^2*fp2^2*m1^2 - 2*R^2*e1^2*ep1*ep2*f1*f2*fp2*m1*r*t1 + R^2*e1^2*ep2^2*f2^2*r^2*t1^2 + 2*R*a1^2*e1^2*ep2^2*f1^2*h*m1^2*mp^2 + 2*R*a1^2*e1*ep2^2*f*f1^2*f2*h*m1*mp + 4*R*a\\\r\n1*e1^2*ep1*ep2*f1^2*fp2*h*m1^2*mp - 8*R*a1*e1^2*ep1*ep2*f1*f2*fp2*h*m1^2*mp + 4*R*a1*e1^2*ep2^2*f1*f2*h*m1*mp*r*t1 - 4*R*a1*e1^2*ep2*f*f1*f2*fp2*h*m1*t1 + 8*R*a1*e1*ep1*ep2^2*f1^2*f2*h*m1*mp*r - 8*R*a1*e1*ep1*ep2^2*f1*f2^2*h*m1*mp*r - 2*R*a1*e1*ep1*ep2*f*f1^2*f2*fp2*h*m1 - 2*R*a1*e1*ep2^2*f*f1*f2^2*h*r*t1 + 2*R*e1^2*ep1^2*f1^2*fp2^2*h*m1^2 - 4*R*e1^2*ep1*ep2*f1*f2*fp2*h*m1*r*t1 + 2*R*e1^2*ep2^2*f2^2*h*r^2*t1^2 + a1^2*e1^2*ep2^2*f1^2*h^2*m1^2*mp^2 + 2*a1*e1^2*ep1*ep2*f1^2*fp2*h^2*m1^2*mp - 4*a1*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1^2*mp + 2*a1*e1^2*ep2^2*f1*f2*h^2*m1*mp*r*t1 + 4*a1*e1*ep1*ep2^2*f1^2*f2*h^2*m1*mp*r - 4*a1*e1*ep1*ep2^2*f1*f2^2*h^2*m1*mp*r + e1^2*ep1^2*f1^2*fp2^2*h^2*m1^2 - 2*e1^2*ep1*ep2*f1*f2*fp2*h^2*m1*r*t1 + e1^2*ep2^2*f2^2*h^2*r^2*t1^2)^(1/2) - R*e1*ep1^2*f1^2*fp2*m1*mp - e1*ep1^2*f1^2*fp2*h*m1*mp + e1*ep1*ep2*f2^2*h*mp*r*t1 - R*a1*e1*ep1*ep2*f1^2*m1*mp^2 - a1*e1*ep1*ep2*f1^2*h*m1*mp^2 + 2*R*e1*ep1*f*f1*f2*fp2*t1 + R*a1*ep1*ep2*f*f1*f2^2*mp - R*a1*ep1*ep2*f*f1^2*f2*mp + R*e1\\\r\n*ep1^2*f1*f2*fp2*m1*mp + R*e1*ep1*ep2*f2^2*mp*r*t1 + e1*ep1^2*f1*f2*fp2*h*m1*mp - R*e1*ep1*ep2*f1*f2*mp*r*t1 - e1*ep1*ep2*f1*f2*h*mp*r*t1 + R*a1*e1*ep1*ep2*f1*f2*m1*mp^2 + a1*e1*ep1*ep2*f1*f2*h*m1*mp^2)/(2*e1*ep2*f2*(R*f*f2*t1 - R*ep1*f1*m1*mp + R*ep1*f2*m1*mp - ep1*f1*h*m1*mp + ep1*f2*h*m1*mp))
There is a stored procedure defined, which takes some parameters,it runs a loop inside it. The issue is that whenever I am executing this query, this single process/function takes 100% CPU usage and approx 2 mins to get executed,I have increased the number of cores but it still takes 100% CPU usage. I am thinking that maybe it is creating temporary tables and Postgresql is unable to autovaccum.
I have tried several configurations, but to no avail.
create
or replace
function some_function(offers numeric[],
list character varying[],
startdate date,
enddate date) returns table
(prod character varying,
offer numeric,
dates date,
baseline double precision,
promoincremental double precision,
couponincremental double precision,
affinityquantity double precision,
affinitymargin double precision,
affinityrevenue double precision,
cannibalisationquantity double precision,
cannibalisationrevenue double precision,
cannibalisationmargin double precision
) language plpgsql as $function$ declare a numeric[] := offers;
i numeric;
begin
foreach i in array a loop return QUERY select
models.prod,
i as offer,
date(models.transdate_dt) as dates,
greatest(0,(sum(models.unitretailprice) * sum(coefficients.unit_retail_price)) + (sum(models.flag::int) * sum(coefficients.flag::int)) + (sum(models.mc_baseline) * sum(coefficients.mc_baseline)) + (sum(models.mc_day_avg) * sum(coefficients.mc_day_avg)) + (sum(models.mc_day_normal) * sum(coefficients.mc_day_normal)) + (sum(models.mc_week_avg) * sum(coefficients.mc_week_avg)) + (sum(models.mc_week_normal) * sum(coefficients.mc_week_normal)) + (sum(models.sku_day_avg) * sum(coefficients.sku_day_avg)) + (sum(models.sku_month_avg) * sum(coefficients.sku_month_avg)) + (sum(models.sku_month_normal)* sum(coefficients.sku_month_normal)) + (sum(models.sku_moving_avg) * sum(coefficients.sku_moving_avg)) + (sum(models.sku_week_avg) * sum(coefficients.sku_week_avg)) + (sum(models.sku_week_normal)* sum(coefficients.sku_week_normal))) as baseline,
greatest(0, ((0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a)))) as promoIncremental,
greatest(0, (sum(models.basket_dollar_off) * sum(coefficients.basket_dollar_off)) + (sum(models.basket_per_off) * sum(coefficients.basket_per_off)) + (sum(models.category_dollar_off) * sum(coefficients.category_dollar_off)) + (sum(models.category_per_off) * sum(coefficients.category_per_off)) + (sum(models.disc_per) * sum(coefficients.disc_per))) as couponIncremnetal,
greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a))) * sum(affinity.pull) * sum(affinity.confidence) as affinityquantity,
greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a))) * sum(affinity.margin_lift) * sum(affinity.confidence) as affinitymargin,
greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a))) * sum(affinity.revenue_lift) * sum(affinity.confidence) as affinityrevenue,
greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a)))/(NULLIF( greatest(0,(sum(models.unitretailprice) * sum(coefficients.unit_retail_price)) + (sum(models.flag::int) * sum(coefficients.flag::int)) + (sum(models.mc_baseline) * sum(coefficients.mc_baseline)) + (sum(models.mc_day_avg) * sum(coefficients.mc_day_avg)) + (sum(models.mc_day_normal) * sum(coefficients.mc_day_normal)) + (sum(models.mc_week_avg) * sum(coefficients.mc_week_avg)) + (sum(models.mc_week_normal) * sum(coefficients.mc_week_normal)) + (sum(models.sku_day_avg) * sum(coefficients.sku_day_avg)) + (sum(models.sku_month_avg) * sum(coefficients.sku_month_avg)) + (sum(models.sku_month_normal)* sum(coefficients.sku_month_normal)) + (sum(models.sku_moving_avg) * sum(coefficients.sku_moving_avg)) + (sum(models.sku_week_avg) * sum(coefficients.sku_week_avg)) + (sum(models.sku_week_normal)* sum(coefficients.sku_week_normal))) + greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a))) + greatest(0, (sum(models.basket_dollar_off) * sum(coefficients.basket_dollar_off)) + (sum(models.basket_per_off) * sum(coefficients.basket_per_off)) + (sum(models.category_dollar_off) * sum(coefficients.category_dollar_off)) + (sum(models.category_per_off) * sum(coefficients.category_per_off)) + (sum(models.disc_per) * sum(coefficients.disc_per))), 0)) * sum(cannibalisation.effect) * (sum(products.price) - (sum(products.price) - i )) as cannibalisationquantity,
((sum(products.price) - i) * sum(models.disc_per) - (sum(products.price) - i) ) * ( greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a)))/(NULLIF( greatest(0,(sum(models.unitretailprice) * sum(coefficients.unit_retail_price)) + (sum(models.flag::int) * sum(coefficients.flag::int)) + (sum(models.mc_baseline) * sum(coefficients.mc_baseline)) + (sum(models.mc_day_avg) * sum(coefficients.mc_day_avg)) + (sum(models.mc_day_normal) * sum(coefficients.mc_day_normal)) + (sum(models.mc_week_avg) * sum(coefficients.mc_week_avg)) + (sum(models.mc_week_normal) * sum(coefficients.mc_week_normal)) + (sum(models.sku_day_avg) * sum(coefficients.sku_day_avg)) + (sum(models.sku_month_avg) * sum(coefficients.sku_month_avg)) + (sum(models.sku_month_normal)* sum(coefficients.sku_month_normal)) + (sum(models.sku_moving_avg) * sum(coefficients.sku_moving_avg)) + (sum(models.sku_week_avg) * sum(coefficients.sku_week_avg)) + (sum(models.sku_week_normal)* sum(coefficients.sku_week_normal))) + greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a))) + greatest(0, (sum(models.basket_dollar_off) * sum(coefficients.basket_dollar_off)) + (sum(models.basket_per_off) * sum(coefficients.basket_per_off)) + (sum(models.category_dollar_off) * sum(coefficients.category_dollar_off)) + (sum(models.category_per_off) * sum(coefficients.category_per_off)) + (sum(models.disc_per) * sum(coefficients.disc_per))), 0)) * sum(cannibalisation.effect) * (sum(products.price) - (sum(products.price) - i ) )) as cannibalisationrevenue,
(((sum(products.price) - i) * sum(models.disc_per) - (sum(products.price) - i) ) - sum(products.cost)) * ( greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a)))/(NULLIF(greatest(0,(sum(models.unitretailprice) * sum(coefficients.unit_retail_price)) + (sum(models.flag::int) * sum(coefficients.flag::int)) + (sum(models.mc_baseline) * sum(coefficients.mc_baseline)) + (sum(models.mc_day_avg) * sum(coefficients.mc_day_avg)) + (sum(models.mc_day_normal) * sum(coefficients.mc_day_normal)) + (sum(models.mc_week_avg) * sum(coefficients.mc_week_avg)) + (sum(models.mc_week_normal) * sum(coefficients.mc_week_normal)) + (sum(models.sku_day_avg) * sum(coefficients.sku_day_avg)) + (sum(models.sku_month_avg) * sum(coefficients.sku_month_avg)) + (sum(models.sku_month_normal)* sum(coefficients.sku_month_normal)) + (sum(models.sku_moving_avg) * sum(coefficients.sku_moving_avg)) + (sum(models.sku_week_avg) * sum(coefficients.sku_week_avg)) + (sum(models.sku_week_normal)* sum(coefficients.sku_week_normal))) + greatest(0, (0 * sum(coefficients.f)) + (0 * sum(coefficients.p)) + (i * sum(coefficients.a))) + greatest(0, (sum(models.basket_dollar_off) * sum(coefficients.basket_dollar_off)) + (sum(models.basket_per_off) * sum(coefficients.basket_per_off)) + (sum(models.category_dollar_off) * sum(coefficients.category_dollar_off)) + (sum(models.category_per_off) * sum(coefficients.category_per_off)) + (sum(models.disc_per) * sum(coefficients.disc_per))), 0)) * sum(cannibalisation.effect) * (sum(products.price) - (sum(products.price) - i ) )) as cannibalisationmargin
from
models
join coefficients on
models.prod = coefficients.prod
and models.si_type = coefficients.si_type
and models.model_type = coefficients.model_type
left join products on
products.unique_id1 = models.prod
left join affinity on
affinity.prod = models.prod
left join cannibalisation on
cannibalisation.prod = models.prod
where
coefficients.prod = any(skusList)
and models.transdate_dt >= startDate
and models.transdate_dt <= endDate
group by
models.prod,
dates,
offer ;
end loop;
end;
$function$ ;
Here I call the function with these parameters:::::
select
*
from
some_function(array[1.5,
2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5 ],
'{12841276, 11873916,07915473, 01504273,10405843,11231446,12224242,11249380,08604365, 11248952, 11230018,10447621,11229820,10406916,09578733,11280161, 01503697, 11923554, 10406460,11295219,01458421,09053893,11224409, 06755789, 11317377, 11275047,12231817,11309507,10447522,10406296, 10406338, 01460658, 12272811,11318870,11248838,10406130,11248812, 11223682, 11276748, 10447605, 11232451, 10405827,10447670,08177743, 10405231, 02326791, 12224226,12231650,11929197,01504380 }',
'2018-01-02'::date,
'2018-01-06'::date );
I expected it to take around 30% CPU usage at a max because it is performing some calculations but it is taking down 100% CPU usage, Can anyone kindly help in this regard?
I am trying to implement a 2D DFT using a combination of 1D DFT in Matlab. When comparing my results against Matlab's inbuilt function (fft2) I realized that I have the following issues:
The sign of the imaginary part is being inverted. i.e + changed to - and vice versa.
The rows are being ordered in descending order except for the first one.
This image shows the comparison between the two results. The red numbers on the side are there to indicate the reordering issue.
My code is as follows:
x = imread('img.png');
x = double(x);
x = x(1:12,1:5)
% FFT
Xw = complex(zeros(size(x)));
for row = 1:size(x,1)
Xw(row,:) = fft(x(row,:));
end
for col = 1:size(x,2)
Xw(:,col) = fft(Xw(:,col)');
end
Could someone kindly indicate where my problem is please? Thanks
The ' operator is for the complex transpose, which means that the matrix is transposed and the conjugate of the values is taken. This means that the signs of the complex values are reversed. You don't notice this with real numbers because technically, the imaginary component is zero.
You want to use .' instead to preserve the sign of the imaginary component as performing the intermediate FFT per row will result in complex values. Using just ' will change the imaginary components of the intermediate results, which will give you the wrong results:
for col = 1:size(x,2)
Xw(:,col) = fft(Xw(:,col).');
end
BTW, as a minor note, there is no need to transpose the intermediate columns of your result at all. If you provide a single vector, fft will operate along the first non-singleton dimension, and so using a transpose is superfluous. It would actually help if you didn't transpose your result at all:
for col = 1:size(x,2)
Xw(:,col) = fft(Xw(:,col));
end
Here's an example. I've generated a random 10 x 10 matrix:
rng(123);
x = rand(10);
Using your code with correcting the transpose (and without the indexing at the beginning), we get:
>> Xw
Xw =
Columns 1 through 5
50.1429 + 0.0000i -0.4266 - 0.2624i 0.8803 + 0.9311i -0.0526 + 1.7067i 0.7187 + 0.7161i
0.5066 - 2.4421i 2.7551 - 1.7421i -1.9994 + 0.6052i 0.2891 + 3.4182i 0.5300 + 2.4417i
0.1956 + 0.1790i 4.1461 + 1.9648i -1.3781 - 1.0303i -0.6872 - 1.0103i -1.2184 - 0.5783i
-0.3645 - 1.6193i -1.8470 - 1.3445i 4.1555 + 0.7432i 2.3707 + 3.8265i -1.9526 + 1.9464i
-3.1136 - 0.3704i 2.4132 - 1.0795i -0.2255 + 1.3062i 0.8436 - 0.5157i -0.3493 - 0.9994i
-1.5962 + 0.0000i -0.3780 - 1.4055i 1.6242 - 0.4842i 0.4457 + 0.4718i -0.1794 - 2.0014i
-3.1136 + 0.3704i 0.0134 + 0.1267i 1.0630 + 1.4563i -0.8864 - 0.3174i -0.5720 + 1.3041i
-0.3645 + 1.6193i 0.7028 + 0.2797i 0.1064 + 2.0705i 2.1644 + 0.1685i 0.3095 + 0.7426i
0.1956 - 0.1790i 2.3511 + 2.1440i 0.7301 - 0.8264i -1.1974 - 0.3794i -2.4981 + 1.2363i
0.5066 + 2.4421i -3.5897 + 0.7444i 1.2191 - 3.6386i -2.9659 - 1.6626i -2.0339 + 0.0880i
Columns 6 through 10
2.0373 + 0.0000i 0.7187 - 0.7161i -0.0526 - 1.7067i 0.8803 - 0.9311i -0.4266 + 0.2624i
-1.8782 - 0.9047i -2.0339 - 0.0880i -2.9659 + 1.6626i 1.2191 + 3.6386i -3.5897 - 0.7444i
2.3752 + 1.8811i -2.4981 - 1.2363i -1.1974 + 0.3794i 0.7301 + 0.8264i 2.3511 - 2.1440i
4.5213 + 0.9237i 0.3095 - 0.7426i 2.1644 - 0.1685i 0.1064 - 2.0705i 0.7028 - 0.2797i
-1.2259 + 2.1690i -0.5720 - 1.3041i -0.8864 + 0.3174i 1.0630 - 1.4563i 0.0134 - 0.1267i
6.2411 + 0.0000i -0.1794 + 2.0014i 0.4457 - 0.4718i 1.6242 + 0.4842i -0.3780 + 1.4055i
-1.2259 - 2.1690i -0.3493 + 0.9994i 0.8436 + 0.5157i -0.2255 - 1.3062i 2.4132 + 1.0795i
4.5213 - 0.9237i -1.9526 - 1.9464i 2.3707 - 3.8265i 4.1555 - 0.7432i -1.8470 + 1.3445i
2.3752 - 1.8811i -1.2184 + 0.5783i -0.6872 + 1.0103i -1.3781 + 1.0303i 4.1461 - 1.9648i
-1.8782 + 0.9047i 0.5300 - 2.4417i 0.2891 - 3.4182i -1.9994 - 0.6052i 2.7551 + 1.7421i
I've also verified that this works without transposing. You'll get the same thing as if you were to perform .'. Now, using fft2, we get:
>> Xw2 = fft2(x)
Xw2 =
Columns 1 through 5
50.1429 + 0.0000i -0.4266 - 0.2624i 0.8803 + 0.9311i -0.0526 + 1.7067i 0.7187 + 0.7161i
0.5066 - 2.4421i 2.7551 - 1.7421i -1.9994 + 0.6052i 0.2891 + 3.4182i 0.5300 + 2.4417i
0.1956 + 0.1790i 4.1461 + 1.9648i -1.3781 - 1.0303i -0.6872 - 1.0103i -1.2184 - 0.5783i
-0.3645 - 1.6193i -1.8470 - 1.3445i 4.1555 + 0.7432i 2.3707 + 3.8265i -1.9526 + 1.9464i
-3.1136 - 0.3704i 2.4132 - 1.0795i -0.2255 + 1.3062i 0.8436 - 0.5157i -0.3493 - 0.9994i
-1.5962 + 0.0000i -0.3780 - 1.4055i 1.6242 - 0.4842i 0.4457 + 0.4718i -0.1794 - 2.0014i
-3.1136 + 0.3704i 0.0134 + 0.1267i 1.0630 + 1.4563i -0.8864 - 0.3174i -0.5720 + 1.3041i
-0.3645 + 1.6193i 0.7028 + 0.2797i 0.1064 + 2.0705i 2.1644 + 0.1685i 0.3095 + 0.7426i
0.1956 - 0.1790i 2.3511 + 2.1440i 0.7301 - 0.8264i -1.1974 - 0.3794i -2.4981 + 1.2363i
0.5066 + 2.4421i -3.5897 + 0.7444i 1.2191 - 3.6386i -2.9659 - 1.6626i -2.0339 + 0.0880i
Columns 6 through 10
2.0373 + 0.0000i 0.7187 - 0.7161i -0.0526 - 1.7067i 0.8803 - 0.9311i -0.4266 + 0.2624i
-1.8782 - 0.9047i -2.0339 - 0.0880i -2.9659 + 1.6626i 1.2191 + 3.6386i -3.5897 - 0.7444i
2.3752 + 1.8811i -2.4981 - 1.2363i -1.1974 + 0.3794i 0.7301 + 0.8264i 2.3511 - 2.1440i
4.5213 + 0.9237i 0.3095 - 0.7426i 2.1644 - 0.1685i 0.1064 - 2.0705i 0.7028 - 0.2797i
-1.2259 + 2.1690i -0.5720 - 1.3041i -0.8864 + 0.3174i 1.0630 - 1.4563i 0.0134 - 0.1267i
6.2411 + 0.0000i -0.1794 + 2.0014i 0.4457 - 0.4718i 1.6242 + 0.4842i -0.3780 + 1.4055i
-1.2259 - 2.1690i -0.3493 + 0.9994i 0.8436 + 0.5157i -0.2255 - 1.3062i 2.4132 + 1.0795i
4.5213 - 0.9237i -1.9526 - 1.9464i 2.3707 - 3.8265i 4.1555 - 0.7432i -1.8470 + 1.3445i
2.3752 - 1.8811i -1.2184 + 0.5783i -0.6872 + 1.0103i -1.3781 + 1.0303i 4.1461 - 1.9648i
-1.8782 + 0.9047i 0.5300 - 2.4417i 0.2891 - 3.4182i -1.9994 - 0.6052i 2.7551 + 1.7421i
We can show these two are equal by ensuring that all of the element-wise differences between the two matrices is less than a small threshold... say 1e-10:
>> all(abs(Xw(:)-Xw2(:)) <= 1e-10)
ans =
1
Take away message
Never use ' for the transpose.... ever. Luis Mendo is a strong advocate of this very fact.
I have already asked the same question in the Matlab user community.
I have the following symbolic expression:
(3*s11)/2 + (3*s12)/2 + (3*s13)/2 + (3*s14)/2 + (3*s15)/2 + (s11*s12)/2 + (s11*s13)/2 + (s11*s14)/2 + (s12*s13)/2 + (s11*s15)/2 + (s12*s14)/2 + (s12*s15)/2 + (s13*s14)/2 + (s13*s15)/2 + (s14*s15)/2 + s11^2/4 + s12^2/4 + s13^2/4 + s14^2/4 + s15^2/4 + 9/4
It is stored as a symbolic expression variable. I would like to enforce the rule sij^2 = 1 i.e. the variables can be either -1 or +1. If I enforce the rule in the expression mentioned above, the expression will be as follows.
(3*s11)/2 + (3*s12)/2 + (3*s13)/2 + (3*s14)/2 + (3*s15)/2 + (s11*s12)/2 + (s11*s13)/2 + (s11*s14)/2 + (s12*s13)/2 + (s11*s15)/2 + (s12*s14)/2 + (s12*s15)/2 + (s13*s14)/2 + (s13*s15)/2 + (s14*s15)/2 + 1/4 + 1/4 + 1/4 + 1/4 + 1/4 + 9/4
How can I do this in Matlab?
Set assumptions e.g. assume(s14^2==1), then use simplify.