Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.

Notice: We are no longer accepting new posts, but the forums will continue to be readable.

Topic: Ask for help: how to let mathematica output Fortran code with fewest
float operations?

Replies: 9   Last Post: Jan 13, 2013 7:27 PM

 Search Thread: Advanced Search

 Messages: [ Previous | Next ]
 Tang Laoya Posts: 27 Registered: 11/21/12
Re: Ask for help: how to let mathematica output Fortran code with
fewest float operations?

Posted: Jan 13, 2013 3:32 AM
 Plain Text Reply

On Sunday, January 13, 2013 2:27:14 PM UTC+8, Tang Laoya wrote:
> Dear all,
>
>
>
> I am new to mathematica and I am trying to let mathematicat output some express to Fortran code. However, it seems that it will output some duplicated expressions so that these expressions would be calculated more than once. Is there any good method to define a rule to let mathematica recognize duplicated expressions and assign them to a new variable and then simplify the Fortran code?
>
>
>
> Thanks,
>
> Tang Laoya
>
>
>
>
>
>
>
>
>
> P.S:
>
>
>
> The following is a test code of mathematica and the solution of x, y and z contains many duplicated expression, for example, (-36*a + 20*a**3 - 216*b)**2.
>
>
>
> sol = Solve[{x^2 + y^2 + z^2 == 1, x + y + z == a , x*y*z == b}, {x,
>
> y, z}];
>
> xx = x /. sol
>
> yy = y /. sol
>
> zz = z /. sol
>
> Print["Writing Fortran Code . . . : / "];
>
> SetDirectory["F:\\tang\\mathtest"];
>
> strm = OpenWrite["test.f90", FormatType -> FotranForm,
>
> PageWidth -> 70];
>
> (* write subroutine of invisopar*)
>
> WriteString[strm, "subroutine test(x,y,z,a,b)\n"];
>
> WriteString[strm, "implicit none\n"];
>
> WriteString[strm, "real*8::x,y,z,a,b\n"];
>
> nroot = Length[xx];
>
> For[ii = 1, ii <= nroot,
>
> WriteString[strm,
>
> "x = " <> ToString[FortranForm[xx[[ii]]]] <> "\n"]; ii++];
>
> For[ii = 1, ii <= nroot,
>
> WriteString[strm,
>
> "y = " <> ToString[FortranForm[yy[[ii]]]] <> "\n"]; ii++];
>
> For[ii = 1, ii <= nroot,
>
> WriteString[strm,
>
> "z = " <> ToString[FortranForm[zz[[ii]]]] <> "\n"]; ii++];
>
> WriteString[strm, "end subroutine\n"];
>
> Close[strm];
>
> Print["Finished Writing Fortran Code . . . : / "];
>
>
>
>
>
> When the test.f90 is outputted, the first solution of x is:
>
> x = a/3. + (-6 + 2*a**2)/(3.*2**0.6666666666666666*(-36*a + 20*a**3 + Sqrt(4*(-6 + 2*a**2)**3 + (-36*a + 20*a**3 - 216*b)**2) - 216*b)**0.3333333333333333) - (-36*a + 20*a**3 + Sqrt(4*(-6 + 2*a**2)**3 + (-36*a + 20*a**3 - 216*b)**2) - 216*b)**0.3333333333333333/(6.*2**0.3333333333333333)
>
>
>
> I would like that the code is as follows:
>
> tmp0 = 216*b
>
> tmp1 = -36*a + 20*a**3
>
> tmp2 = (tmp1 - tmp0 )**2
>
> tmp3 = -6 + 2*a**2
>
> tmp4 = 4*tmp3**3
>
> tmp5 = Sqrt(tmp4 + tmp2 )
>
> tmp6 = tmp1 + tmp5 - tmp0
>
> tmp7 = tmp6**0.3333333333333333
>
> tmp8 = 2**0.6666666666666666
>
>
>
> x = a/3. + tmp3 /(3.*tmp8 *tmp7 ) - tmp7/(6.*tmp8)

BTW: I noticed that maple have the keyword which can implement above simplfication. For example, the following codes can output simplified Fortran code:

with(codegen, fortran)
A := array(1 .. 2, 1 .. 2, symmetric); A[1, 1] := log(x); A[1, 2] := 1-log(x); A[2, 2] := 2-log(x);
print(A);
fortran(A, optimized, mode = double)

But it seems that maple can't solve the equations I put previously.

Could anyone help me to take a look at it?

Thanks,
Tang Laoya

Date Subject Author
1/13/13 Tang Laoya
1/13/13 Tang Laoya
1/13/13 Richard Fateman
1/13/13 Tang Laoya
1/13/13 Nasser Abbasi
1/13/13 Tang Laoya
1/13/13 Axel Vogt
1/13/13 Tang Laoya
1/13/13 Axel Vogt
1/13/13 Tang Laoya

© The Math Forum at NCTM 1994-2018. All Rights Reserved.