7
$\begingroup$

I am trying to output most efficient Fortran code by mathematica 9.0 with the method Simon provided: How can I get Mathematica to produce better Fortran code?

The expressions is as follows:

v = Det[{{1, 1, 1, 1}, {x1, x2, x3, x4}, {y1, y2, y3, y4}, {z1, z2, 
     z3, z4}}]/6;
b1 = -Det[{{1, 1, 1}, {y2, y3, y4}, {z2, z3, z4}}];
c1 = Det[{{1, 1, 1}, {x2, x3, x4}, {z2, z3, z4}}];
d1 = -Det[{{1, 1, 1}, {x2, x3, x4}, {y2, y3, y4}}];
b2 = Det[{{1, 1, 1}, {y1, y3, y4}, {z1, z3, z4}}];
c2 = -Det[{{1, 1, 1}, {x1, x3, x4}, {z1, z3, z4}}];
d2 = Det[{{1, 1, 1}, {x1, x3, x4}, {y1, y3, y4}}];
b3 = -Det[{{1, 1, 1}, {y1, y2, y4}, {z1, z2, z4}}];
c3 = Det[{{1, 1, 1}, {x1, x2, x4}, {z1, z2, z4}}];
d3 = -Det[{{1, 1, 1}, {x1, x2, x4}, {y1, y2, y4}}];
b4 = Det[{{1, 1, 1}, {y1, y2, y3}, {z1, z2, z3}}];
c4 = -Det[{{1, 1, 1}, {x1, x2, x3}, {z1, z2, z3}}];
d4 = Det[{{1, 1, 1}, {x1, x2, x3}, {y1, y2, y3}}];
bcdv = {b1, c1, d1, b2, c2, d2, b3, c3, d3, b4, c4, d4, v};

The code to produce Fortran code is as follows:

out = Experimental`OptimizeExpression[FullSimplify[bcdv], 
    "OptimizationSymbol" -> tmp] /. 
   HoldPattern[
     Experimental`OptimizedExpression[
      Block[{tempVars__}, 
       CompoundExpression[defs : Set[_, _] ..., expr_]]]] :> 
    Block[{Set = 
       ToString[#1] <> " = " <> ToString[FortranForm[#2]] &}, 
     List[defs, expr]];
out2 = out // Flatten // ExportString[#, "Table"] &

However, it produced the following code (with the number of production operations be 69):

tmp9 = -z3
tmp6 = -z4
tmp3 = -z2
tmp15 = tmp6 + z3
tmp33 = -z1
tmp10 = tmp9 + z4
tmp26 = -y3
tmp23 = -y4
tmp39 = tmp6 + z1
tmp17 = tmp3 + z4
tmp7 = tmp6 + z2
tmp34 = tmp33 + z4
tmp47 = -y1
tmp20 = -y2
tmp56 = tmp3 + z1
tmp13 = tmp9 + z2
tmp37 = tmp33 + z3
tmp51 = tmp33 + z2
tmp30 = tmp9 + z1
tmp4 = tmp3 + z3
tmp53 = tmp39*y2
tmp10*y2 + tmp7*y3 + tmp4*y4
tmp15*x2 + tmp17*x3 + tmp13*x4
x3*(tmp23 + y2) + x4*(tmp20 + y3) + x2*(tmp26 + y4)
tmp15*y1 + tmp34*y3 + tmp30*y4
tmp10*x1 + tmp39*x3 + tmp37*x4
x4*(tmp26 + y1) + x1*(tmp23 + y3) + x3*(tmp47 + y4)
tmp53 + tmp17*y1 + tmp51*y4
tmp7*x1 + tmp34*x2 + tmp56*x4
x2*(tmp23 + y1) + x4*(tmp47 + y2) + x1*(tmp20 + y4)
tmp13*y1 + tmp37*y2 + tmp56*y3
tmp4*x1 + tmp30*x2 + tmp51*x3
x3*(tmp20 + y1) + x1*(tmp26 + y2) + x2*(tmp47 + y3)
(-(x2*y3*z1) + x2*y4*z1 + x1*y3*z2 - x1*y4*z2 + x2*y1*z3 - x1*y2*z3 + \
x1*y4*z3 - x2*y4*z3 + x4*(-(y2*z1) + y3*z1 + y1*z2 - y3*z2 - y1*z3 + \
y2*z3) + (-(x2*y1) + x1*y2 - x1*y3 + x2*y3)*z4 + x3*(tmp53 - y4*z1 - \
y1*z2 + y4*z2 + y1*z4))/6

The ideal code is as follows, with the number of production operations be 29:

x1=x(2)-x(1)
y1=y(2)-y(1)
z1=z(2)-z(1)
x2=x(3)-x(2)
y2=y(3)-y(2)
z2=z(3)-z(2)
x3=x(4)-x(3)
y3=y(4)-y(3)
z3=z(4)-z(3)
x4=x(1)-x(4)
y4=y(1)-y(4)
z4=z(1)-z(4)
B1=Y3*Z2-Y2*Z3
B2=Y3*Z4-Y4*Z3
B3=Y1*Z4-Y4*Z1
B4=Y1*Z2-Y2*Z1
C1=X2*Z3-X3*Z2
C2=X4*Z3-X3*Z4
C3=X4*Z1-X1*Z4
C4=X2*Z1-X1*Z2
D1=X3*Y2-X2*Y3
D2=X3*Y4-X4*Y3
D3=X1*Y4-X4*Y1
D4=X1*Y2-X2*Y1
V=(x(1)*b1+x(2)*b2+x(3)*b3+x(4)*b4)/6.0d0

Is there any better way to produce high efficient Fortran code?

Thanks, Tang Laoya

$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.