diff options
author | Barry Wardell <barry.wardell@gmail.com> | 2011-11-28 17:23:07 +0000 |
---|---|---|
committer | Barry Wardell <barry.wardell@gmail.com> | 2011-11-28 17:23:07 +0000 |
commit | 864f17e74aa7cd6dbb81c677b7746ba7245c6cab (patch) | |
tree | 3e474384ab589f623377b8a8471868ca7097658a | |
parent | de580d703993b2a402634fd0b34a883edc3266bc (diff) |
Remove old, unused files.
-rw-r--r-- | Tools/External/Format.m | 1737 | ||||
-rw-r--r-- | Tools/External/SetTensor.m | 723 | ||||
-rw-r--r-- | Tools/External/SetTensor.tex | 843 |
3 files changed, 0 insertions, 3303 deletions
diff --git a/Tools/External/Format.m b/Tools/External/Format.m deleted file mode 100644 index 46a1c3f..0000000 --- a/Tools/External/Format.m +++ /dev/null @@ -1,1737 +0,0 @@ -(* :Title: Extensions to the built-in Format rules and more... *) - -(* :Author: Mark Sofroniou *) - -(* :Summary: - This package extends Mathematica's built-in format rules. - Assignments to expressions and lists are now possible. - The package adds definitions Assign, CAssign and FortranAssign - and MapleAssign. Many shortcomings of the built-in formatting code - have also been addressed, such as the limit on continuation lines - in FORTRAN77 and assignments to Expressions. - Code optimization is possible via the auxiliary package Optimize.m - and the option AssignOptimize. - The functions are primarily intended for use with the Splice command. - When using Splice, the option FormatType->OutputForm should be - specified. - Interactive output within a Mathematica session is also possible - (see also the AssignToFile option). - All expressions are written as Strings. This enable more precise - formatting of expressions, removing the need for text editing. - Any Mathematica print form (e.g. TeXForm) can be specified as an - argument of the Assign command. *) - -(* :Context: Format` *) - -(* :Package Version: 1.5 *) - -(* :Copyright: Copyright 1992-4, Mark Sofroniou. - Permission is hereby granted to modify and/or make copies of - this file for any purpose other than direct profit, or as part - of a commercial product, provided this copyright notice is left - intact. Sale, other than for the cost of media, is prohibited. - - Permission is hereby granted to reproduce part or all of - this file, provided that the source is acknowledged. *) - -(* :History: - December 1994 - Modifications to MapleAssign. - - August 1994 - Version 1.5. Removed option AssignExp. - Added array and sequence formatting for temporaries. - Better handling of Arrays in C. - - April 1994 - Version 1.4. Removed options AssignComplexRules, - AssignLevel, AssignMinSize, AssignRecursive. Renamed AssignNProtect - as AssignToArray. Improved linebreaking and option/argument - testing and scoping. Improved MapleAssign functionality. - - September 1993 - Version 1.3. Added option AssignOptimize - and modified evaluation process accordingly. 1.3.1 minor - modifications to FORTRAN numbering and optimization. - - August 1993 - Version 1.2. New MapleAssign accepts standard - Mathematica input and returns analogous maple code. Options - AssignIndex and AssignZero added. - - June 1993 - Version 1.1. Changed evaluation process. - Removed support for log10 function and changed representation - of rational powers in CAssign and FortranAssign. - - April 1993 - added lists of assignments. - - October 1992 - automatic breaking of long FORTRAN expressions - and Maple format added. - - Original Version by Mark Sofroniou, July, 1992. - - Those who have contributed suggestions (historical order): - Dave Withoff, Rolf Mertig, Emily Martin, Troels Petersen, - Alain Kessi, Richard Fateman, Christophe Pichon. *) - -(* :Keywords: - Assign, CAssign, CForm, InputForm, FortranAssign, FortranForm, - OutputForm, TeXForm. *) - -(* :Source: - Mark Sofroniou, Ph.D. Thesis, Loughborough University, Loughborough, - Leicestershire LE11 3TU, England. *) - -(* :Mathematica Version: 2.1 *) - -(* :Limitations: - This package has been developed to address limitations and problems - encountered when using Mathematica's format rules. Commands are - encapsulated to avoid interference with Mathematica's built-in - definitions. Necessary rules are therefore added and removed upon - each execution. - Recursive code breaking may be slow for large FORTRAN - expressions especially if too strict a tolerance is specified. - This is a particular weakness of FortranForm. - Suggestions for improvements and enhancements are welcome. *) - -BeginPackage["Format`","Utilities`FilterOptions`"] - -Assign::usage = "Assign[lhs,rhs,outputformat,options]\n -Assign converts the assignment of lhs to rhs into specified -outputformat strings (such as TeXForm). If assignments to -expressions are not required, the lhs argument may be omitted.\n -When used with Splice, the option FormatType->OutputForm -should be specified." - -CAssign::usage = "CAssign[lhs,rhs,options]\n -CAssign converts the assignment of lhs to rhs into C compatible -strings. Options enable control over the conversion process, such as -the precision of real numbers. If assignments to expressions -are not required, the lhs argument may be omitted.\n When used -with Splice, the option FormatType->OutputForm should be specified." - -FortranAssign::usage = "FortranAssign[lhs,rhs,options]\n -FortranAssign converts the assignment of lhs to rhs into -FORTRAN compatible strings. Options enable control over the conversion -process. Expressions are broken up and continuation characters are -added by default. The precision of real numbers in expressions may -be specified together with single or double precision exponents. -Generic FORTRAN functions are used since compilers can infer the -function type from the precision of the argument. If assignments -to expressions are not required, the lhs argument may be omitted.\n -When used with Splice, the option FormatType->OutputForm should be -specified." - -MapleAssign::usage = "MapleAssign[lhs,rhs,options]\n -converts Mathematica expressions into Maple expressions and assignments. -MapleAssign converts the assignment of lhs to rhs into strings -suitable as input to Maple. If assignments to expressions are not -required, the lhs argument may be omitted.\n When used with Splice, -the option FormatType->OutputForm should be specified." - -(* Options: *) - -AssignBreak::usage = "AssignBreak specifies how long lines of -code should be broken up. AssignBreak may evaluate to a List of -{linewidth,string} or False. One of the string characters is -assumed to be \\n." - -AssignCase::usage = "AssignCase specifies whether case conversion -of characters should be performed. AssignCase may evaluate to -Default, LowerCase or UpperCase." - -AssignEnd::usage = "AssignEnd is a string appended to expressions. -It can be used to add C-style statement delimiters (AssignEnd->\";\") -or separate multiple expressions (AssignEnd->\"\\n\")." - -AssignFortranNumbers::usage= "AssignFortranNumbers specifies whether -real numbers should be formatted in standard single or double precision -FORTRAN notation (e.g. 7.2d0, 10.3e1). Its value may be True or False -(uses default exponentiation)." - -AssignFunction::usage = "The message AssignFunction::undef is generated -whenever a non ANSI C or FORTRAN function is encountered for the first time. -The message may be suppressed using Off." - -AssignHyperbolic::usage = "AssignHyperbolic is an option of -CAssign and FortranAssign specifying whether to transform -reciprocal and inverse hyperbolic functions (these are not -supported by some compilers). Unique principal values are -assumed by writing in terms of hyperbolic functions and/or -log and sqrt. E.g. atanh(x) = log((1+x)/(1-x))/2. -AssignHyperbolic may evaluate to True or False." - -AssignIndent::usage = "AssignIndent specifies a string to prepend -to an expression." - -AssignIndex::usage = "AssignIndex specifies the starting index of an -assignment array. Its value may be any positive integer or zero." - -AssignLabel::usage = "AssignLabel specifies a string or positive integer -to attach to the first in a list of expressions. Less than 6 characters -or digits must be involved." - -AssignMaxSize::usage = "AssignMaxSize specifies an upper bound for the -maximum number of bytes of a single expression. In FORTRAN77, there is -compiler dependent limit on the allowable number of continuation lines -an expression may occupy (typically 19). Some editors such as vi in UNIX -impose limitations on the permissible length of a single line. -AssignMaxSize specifies a limit on the number of bytes using ByteCount. -This is an approximate heuristic which is roughly proportional to the -number of characters in an expression. The setting AssignMaxSize->Infinity -ensures that no expressions are broken up. AssignMaxSize -may evaluate to a positive integer (>= 200) or Infinity. See also the option -AssignTemporary." - -AssignOptimize::usage = "AssignOptimize is an option of CAssign and -FortranAssign specifying whether to generate an optimized computational -sequence. This option requires the auxiliary package Optimize.m. -The degreee of optimization performed can be set as options to the -function Optimize. AssignOptimize may evaluate to True or False." - -AssignPrecision::usage = "AssignPrecision specifies the precision -of real numbers in expressions. Its value may be any positive integer -or infinity." - -AssignRange::usage = "AssignRange is an option of CAssign and FortranAssign. -AssignRange is used to check the range of real and integer numbers in an -expression. Numbers are checked against IEEE standards for single and double -precision according to the setting of AssignPrecision. AssignRange may evaluate -to True or False." - -AssignReplace::usage = "AssignReplace specifies a list of String -replacement rules. AssignReplace can be used to compact expressions -by AssignReplace->{\" \"->\"\"}." - -AssignTemporary::usage = "AssignTemporary specifies the name and format -of the temporary assignment variable used. Temporary variables are introduced -in order to break up large expressions when specified bounds are exceeded. -For example, specifying {t,Sequence} introduces the variables t1, t2,... etc. -User definitions for a symbol may interfere with the assigment process. -AssignTemporary may evaluate to an empty list or a pair {var,form} where var -is a symbol or a string and form is either Array or Sequence." - -AssignTemporaryIndex::usage = "AssignTemporaryIndex stores the maximum number -of temporary variables introduced during each assignment. This is useful for -array dimensioning." - -AssignToArray::usage= "AssignToArray is used to convert -Mathematica arrays and functions into arrays in C and FORTRAN. -Arguments are protected from N and maintained in exact form. -AssignToArray may evaluate to any list of symbols." - -AssignToFile::usage = "AssignToFile specifies the name of an output -file to write results. Any previous contents of the file will be -overwritten. AssignToFile may evaluate to any string. See also the -Mathematica function Splice." - -AssignTrig::usage = "AssignTrig is an option of CAssign and -FortranAssign specifying whether to transform reciprocal and -inverse trigonometric functions (these are not supported by -some compilers). Unique principal values in terms of trigonometric -functions are assumed. E.g. cot(x) = tan(1/x). -AssignTrig may evaluate to True or False." - -AssignZero::usage = "AssignZero specifies whether zero-valued -elements in an array should be assigned or removed. This is -useful when assigning large arrays in ANSI C (default values -are zero). AssignZero may evaluate to True or False." - - -(* Set general error message for arguments. *) - -Assign::args = "The `1` did not evaluate to `2`." -CAssign::args = "The `1` did not evaluate to `2`." -FortranAssign::args = "The `1` did not evaluate to `2`." -MapleAssign::args = "The `1` did not evaluate to `2`." - -AssignFunction::undef = "Expression contains the function -`1` which is not part of the ANSI `2` standard." - -AssignOptimize::fail = "Unable to optimize expression - check -default options for Optimize. Continuing with unoptimized -expression." - -(* Symbols used to format real numbers in FORTRAN. *) - -d::usage="d is the exponent used to format double precision -numbers in FortranAssign."; -e::usage="e is the exponent used to format single precision -numbers in FortranAssign."; - -(* Symbols used to format CAssign, FortranAssign and MapleAssign functions. *) - -abs::usage="The symbol abs is used to format Abs in CAssign, FortranAssign -and MapleAssign."; -acos::usage="The symbol acos is used to format ArcCos in CAssign and -FortranAssign."; -aimag::usage="The symbol aimag is used in the test for ANSI compatible -functions in FortranAssign."; -aint::usage="The symbol aint is used in the test for ANSI compatible -functions in FortranAssign."; -alog::usage="The symbol alog is used in the test for ANSI compatible -functions in FortranAssign."; -alog10::usage="The symbol alog10 is used in the test for ANSI compatible -functions in FortranAssign."; -amax0::usage="The symbol amax0 is used in the test for ANSI compatible -functions in FortranAssign."; -amax1::usage="The symbol amax1 is used in the test for ANSI compatible -functions in FortranAssign."; -amin0::usage="The symbol amin0 is used in the test for ANSI compatible -functions in FortranAssign."; -amin1::usage="The symbol amin1 is used in the test for ANSI compatible -functions in FortranAssign."; -amod::usage="The symbol amod is used in the test for ANSI compatible -functions in FortranAssign."; -and::usage="The symbol and is used to format And in MapleAssign."; -anint::usage="The symbol anint is used in the test for ANSI compatible -functions in FortranAssign."; -arccos::usage="The symbol arccos is used to format ArcCos in MapleAssign."; -acosh::usage="The symbol acosh is used to format ArcCosh in CAssign and -FortranAssign. If the compiler does not support an acosh function, -then the option AssignHyperbolic may be used."; -Ai::usage="The symbol Ai is used to format AiryAi in MapleAssign."; -arccosh::usage="The symbol arccosh is used to format ArcCosh in MapleAssign."; -arccot::usage="The symbol arccot is used to format ArcCot in MapleAssign."; -arccoth::usage="The symbol arccoth is used to format ArcCoth in MapleAssign."; -arccsc::usage="The symbol arccsc is used to format ArcCsc in MapleAssign."; -arccsch::usage="The symbol arccsch is used to format ArcCsch in MapleAssign."; -arcsec::usage="The symbol arcsec is used to format ArcSec in MapleAssign."; -arcsech::usage="The symbol arcsech is used to format ArcSech in MapleAssign."; -asin::usage="The symbol asin is used to format ArcSin in CAssign and -FortranAssign."; -arcsin::usage="The symbol arcsin is used to format ArcSin in MapleAssign."; -asinh::usage="The symbol asinh is used to format ArcSinh in CAssign and -FortranAssign. If the compiler does not support an asinh function, -then the option AssignHyperbolic may be used."; -arcsinh::usage="The symbol arcsinh is used to format ArcSinh in MapleAssign."; -atan::usage="The symbol atan is used to format ArcTan in CAssign and -FortranAssign. If the compiler does not support an atanh function, -then the option AssignHyperbolic may be used."; -arctan::usage="The symbol arctan is used to format ArcTan in MapleAssign."; -atan2::usage="The symbol atan2 is used in the test for ANSI compatible -functions in CAssign and FortranAssign."; -atanh::usage="The symbol atanh is used to format ArcTanh in CAssign and -FortranAssign."; -arctanh::usage="The symbol arctanh is used to format ArcTanh in MapleAssign."; -bernoulli::usage="The symbol bernoulli is used to format BernoulliB in -MapleAssign."; -Bi::usage="The symbol Bi is used to format AiryBi in MapleAssign."; -binomial::usage="The symbol binomial is used to format Binomial in -MapleAssign."; -cabs::usage="The symbol cabs is used in the test for ANSI compatible -functions in FortranAssign."; -ccos::usage="The symbol ccos is used in the test for ANSI compatible -functions in FortranAssign."; -ceil::usage="The symbol ceil is used to format Round in CAssign."; -cexp::usage="The symbol cexp is used in the test for ANSI compatible -functions in FortranAssign."; -char::usage="The symbol char is used in the test for ANSI compatible functions -in FortranAssign."; -Ci::usage="The symbol Ci is used to format CosIntegral in MapleAssign."; -clog::usage="The symbol clog is used in the test for ANSI compatible -functions in FortranAssign."; -cmplx::usage="The symbol cmplx is used in the test for ANSI compatible -functions in FortranAssign."; -collect::usage="The symbol collect is used to format Collect in MapleAssign."; -conjg::usage="The symbol cmplx is used to format Conjugate in FortranAssign."; -cos::usage="The symbol cos is used to format Cos in CAssign, FortranAssign -and MapleAssign."; -cosh::usage="The symbol cosh is used to format Cosh in CAssign, FortranAssign -and MapleAssign."; -cot::usage="The symbol cot is used to format Cot in MapleAssign."; -coth::usage="The symbol coth is used to format Coth in MapleAssign."; -csc::usage="The symbol csc is used to format Csc in MapleAssign."; -csch::usage="The symbol csch is used to format Csch in MapleAssign."; -csin::usage="The symbol csin is used in the test for ANSI compatible -functions in FortranAssign."; -csqrt::usage="The symbol csqrt is used in the test for ANSI compatible -functions in FortranAssign."; -dabs::usage="The symbol dabs is used in the test for ANSI compatible -functions in FortranAssign."; -dacos::usage="The symbol dacos is used in the test for ANSI compatible -functions in FortranAssign."; -dasin::usage="The symbol dasin is used in the test for ANSI compatible -functions in FortranAssign."; -datan::usage="The symbol datan is used in the test for ANSI compatible -functions in FortranAssign."; -datan2::usage="The symbol datan is used in the test for ANSI compatible -functions in FortranAssign."; -dble::usage="The symbol dble is used in the test for ANSI compatible functions -in FortranAssign."; -dcos::usage="The symbol dcos is used in the test for ANSI compatible -functions in FortranAssign."; -dcosh::usage="The symbol dcosh is used in the test for ANSI compatible -functions in FortranAssign."; -ddim::usage="The symbol ddim is used in the test for ANSI compatible -functions in FortranAssign."; -denom::usage="The symbol denom is used to format Denominator in MapleAssign."; -dexp::usage="The symbol dexp is used in the test for ANSI compatible -functions in FortranAssign."; -diff::usage="The symbol diff is used to format D in MapleAssign."; -dilog::usage="The symbol dilog is used to format PolyLog in MapleAssign."; -dim::usage="The symbol dim is used in the test for ANSI compatible functions in -FortranAssign."; -dint::usage="The symbol dint is used in the test for ANSI compatible -functions in FortranAssign."; -div::usage="The symbol div is used in the test for ANSI compatible functions in -CAssign."; -dlog::usage="The symbol dlog is used in the test for ANSI compatible -functions in FortranAssign."; -dlog10::usage="The symbol dlog10 is used in the test for ANSI compatible -functions in FortranAssign."; -dmax1::usage="The symbol dmax1 is used in the test for ANSI compatible -functions in FortranAssign."; -dmin1::usage="The symbol dmin1 is used in the test for ANSI compatible -functions in FortranAssign."; -dmod::usage="The symbol dmod is used in the test for ANSI compatible -functions in FortranAssign."; -dnint::usage="The symbol dnint is used in the test for ANSI compatible -functions in FortranAssign."; -dprod::usage="The symbol dprod is used in the test for ANSI compatible -functions in FortranAssign."; -dsign::usage="The symbol dsign is used in the test for ANSI compatible -functions in FortranAssign."; -dsin::usage="The symbol dsin is used in the test for ANSI compatible -functions in FortranAssign."; -dsinh::usage="The symbol dsinh is used in the test for ANSI compatible -functions in FortranAssign."; -dsqrt::usage="The symbol dsqrt is used in the test for ANSI compatible -functions in FortranAssign."; -dtan::usage="The symbol dtan is used in the test for ANSI compatible -functions in FortranAssign."; -dtanh::usage="The symbol dtanh is used in the test for ANSI compatible -functions in FortranAssign."; -Ei::usage="The symbol Ei is used to format ExpIntegral in MapleAssign."; -erf::usage="The symbol erf is used to format Erf in MapleAssign."; -erfc::usage="The symbol erfc is used to format Erfc in MapleAssign."; -euler::usage="The symbol euler is used to format EulerE in MapleAssign."; -evalf::usage="The symbol evalf is used to format N in MapleAssign."; -exp::usage="The symbol exp is used to format Exp in CAssign, FortranAssign -and MapleAssign."; -expand::usage="The symbol expand is used to format Expand in MapleAssign."; -fabs::usage="The symbol fabs is used in the test for ANSI compatible functions -in CAssign."; -factor::usage="The symbol factor is used to format Factor in MapleAssign."; -false::usage="The symbol false is used to format False in MapleAssign."; -float::usage="The symbol float is used in the test for ANSI compatible -functions in FortranAssign."; -floor::usage="The symbol floor is used to format Floor in CAssign."; -fmod::usage="The symbol fmod is used in the test for ANSI compatible functions -in CAssign."; -frexp::usage="The symbol frexp is used in the test for ANSI compatible -functions in CAssign."; -fsolve::usage="The symbol fsolve is used to format NSolve in MapleAssign."; -GAMMA::usage="The symbol GAMMA is used to format Gamma in MapleAssign."; -iabs::usage="The symbol iabs is used in the test for ANSI compatible -functions in FortranAssign."; -ichar::usage="The symbol ichar is used in the test for ANSI compatible -functions in FortranAssign."; -idim::usage="The symbol idim is used in the test for ANSI compatible -functions in FortranAssign."; -idint::usage="The symbol idint is used in the test for ANSI compatible -functions in FortranAssign."; -idnint::usage="The symbol idnint is used in the test for ANSI compatible -functions in FortranAssign."; -ifix::usage="The symbol ifix is used in the test for ANSI compatible -functions in FortranAssign."; -index::usage="The symbol index is used in the test for ANSI compatible -functions in FortranAssign."; -infinity::usage="The symbol infinity is used to format ComplexInfinity, -and Infinity in MapleAssign."; -int::usage="The symbol int is used to format Floor in FortranAssign and -Integrate and NIntegrate in MapleAssign."; -isign::usage="The symbol isign is used in the test for ANSI compatible -functions in FortranAssign."; -labs::usage="The symbol labs is used in the test for ANSI compatible -functions in CAssign."; -ldexp::usage="The symbol ldexp is used in the test for ANSI compatible -functions in CAssign."; -ldiv::usage="The symbol ldiv is used in the test for ANSI compatible -functions in CAssign."; -len::usage="The symbol len is used in the test for ANSI compatible -functions in FortranAssign."; -lge::usage="The symbol lge is used in the test for ANSI compatible -functions in FortranAssign."; -lgt::usage="The symbol lgt is used in the test for ANSI compatible -functions in FortranAssign."; -lle::usage="The symbol lle is used in the test for ANSI compatible -functions in FortranAssign."; -llt::usage="The symbol llt is used in the test for ANSI compatible -functions in FortranAssign."; -lnGAMMA::usage="The symbol lnGAMMA is used to format LogGamma in MapleAssign."; -log::usage="The symbol log is used to format Log in CAssign, FortranAssign -and MapleAssign."; -log10::usage="The symbol log10 is used in the test for ANSI compatible -functions in CAssign and FortranAssign."; -map::usage="The symbol map is used to format Map in MapleAssign."; -max::usage="The symbol max is used to format Max in FortranAssign and -MapleAssign."; -max0::usage="The symbol max0 is used in the test for ANSI compatible -functions in FortranAssign."; -max1::usage="The symbol max1 is used in the test for ANSI compatible -functions in FortranAssign."; -min::usage="The symbol min is used to format Min in FortranAssign and -MapleAssign."; -min0::usage="The symbol min0 is used in the test for ANSI compatible -functions in FortranAssign."; -min1::usage="The symbol min1 is used in the test for ANSI compatible -functions in FortranAssign."; -mod::usage="The symbol mod is used to format Mod in CAssign, FortranAssign -and MapleAssign."; -mtaylor::usage="The symbol mtaylor is used to format Series in MapleAssign."; -modf::usage="The symbol modf is used in the test for ANSI compatible -functions in CAssign."; -nint::usage="The symbol nint is used to format Round in FortranAssign."; -nops::usage="The symbol nops is used to format Length in MapleAssign."; -normal::usage="The symbol normal is used to format Together in MapleAssign."; -not::usage="The symbol not is used to format Not in MapleAssign."; -NULL::usage="The symbol NULL is used to format Null in MapleAssign."; -num::usage="The symbol num is used to format Numerator in MapleAssign."; -op::usage="The symbol op is used to format Part in MapleAssign. op(0,expr) -is analogous to Head[expr]"; -or::usage="The symbol or is used to format Or in MapleAssign."; -pow::usage="The symbol pow is used to format Power in CAssign."; -product::usage="The symbol product is used to format Product in MapleAssign."; -Psi::usage="The symbol Psi is used to format PolyGamma in MapleAssign."; -rand::usage="The symbol rand is used to format Random in CAssign."; -real::usage="The symbol real is used to format Re in FortranAssign."; -RootOf::usage="The symbol RootOf is used to format Roots in MapleAssign."; -round::usage="The symbol round is used to format Round in MapleAssign."; -sec::usage="The symbol sec is used to format Sec in MapleAssign."; -sech::usage="The symbol sech is used to format Sech in MapleAssign."; -series::usage="The symbol series is used to format Series in MapleAssign."; -Si::usage="The symbol Si is used to format SinIntegral in MapleAssign."; -sign::usage="The symbol sign is used to format Sign in MapleAssign and -in the test for ANSI compatible functions in FortranAssign."; -simplify::usage="The symbol simplify is used to format Simplify in -MapleAssign."; -sin::usage="The symbol sin is used to format Sin in CAssign, FortranAssign -and MapleAssign."; -sinh::usage="The symbol sinh is used to format Sinh in CAssign, FortranAssign -and MapleAssign."; -sngl::usage="The symbol sngl is used in the test for ANSI compatible -functions in FortranAssign."; -solve::usage="The symbol solve is used to format Solve in MapleAssign."; -sqrt::usage="The symbol sqrt is used to format Sqrt in CAssign, FortranAssign -and MapleAssign."; -srand::usage="The symbol srand is used in the test for ANSI compatible -functions in CAssign and FortranAssign."; -subs::usage="The symbol subs is used to format ReplaceAll in MapleAssign."; -sum::usage="The symbol sum is used to format Sum in MapleAssign."; -tan::usage="The symbol tan is used to format Tan in CAssign, FortranAssign -and MapleAssign."; -tanh::usage="The symbol tanh is used to format Tanh in CAssign, FortranAssign -and MapleAssign."; -true::usage="The symbol true is used to format True in MapleAssign."; -trig::usage="The symbol trig is used to format the option Trig->True -(used in Simplify and related functions) in MapleAssign."; - -(* Symbols used to format ASCII strings. Default already exists - in the global context. *) - -LowerCase::usage="LowerCase is used to format ASCII strings via -the option AssignCase."; -UpperCase::usage="UpperCase is used to format ASCII strings via -the option AssignCase."; - -Unprotect[d,e,abs,acos,acosh,Ai,aimag,aint,alog,alog10,amax0,amax1,amin0,amin1, -amod,and,anint,arccos,arccosh,arccot,arccoth,arccsc,arccsch,arcsec,arcsech,arcsin, -arcsinh,arctan,arctanh,asin,asinh,atan,atan2,atanh,bernoulli,Bi,binomial,cabs, -ccos,ceil,cexp,char,Ci,clog,cmplx,collect,conjg,cos,cosh,cot,coth,csc,csch,csin, -csqrt,dabs,dacos,dasin,datan,datan2,dble,dcos,dcosh,ddim,denom,dexp,dilog,dim, -dint,dlog,dlog10,dmax1,dmin1,dmod,dnint,dprod,dsign,dsin,dsinh,dsqrt,dtan,dtanh, -Ei,erf,erfc,euler,evalf,exp,expand,factor,factorial,false,float,fsolve,GAMMA,iabs, -ichar,idim,idint,idnint,ifix,index,infinity,int,isign,len,lge,lgt,lle,llt,log,log10,lnGAMMA, -map,max,max0,max1,min,min0,min1,mod,mtaylor,nint,not,NULL,num,op,or,pow,Psi,real,RootOf, -round,sec,sech,series,Si,sign,sin,sinh,sngl,solve,sqrt,subs,tan,tanh,true, -LowerCase,UpperCase,Assign,AssignBreak,AssignCase,AssignEnd,AssignFortranNumbers, -AssignIndent,AssignHyperbolic,AssignLabel,AssignMaxSize,AssignPrecision, -AssignRange,AssignReplace,AssignTemporary,AssignToArray,AssignToFile,AssignTrig, -CAssign,FortranAssign,MapleAssign]; - - -Begin["`Private`"] - -errmsgs = { - {"argument lhs","a (flat) list of the same length as rhs"}, - {"option AssignBreak","False or a List of a positive integer and a string"}, - {"option AssignCase","Default, LowerCase, or UpperCase"}, - {"option AssignEnd","a string"}, - {"option AssignFortranNumbers","True or False"}, - {"option AssignHyperbolic","True or False"}, - {"option AssignIndent","a string or a positive integer"}, - {"option AssignIndex","a positive integer or zero"}, - {"option AssignLabel","a string or positive integer"}, - {"option AssignMaxSize","a positive integer (>= 200) or infinity"}, - {"option AssignOptimize","True or False"}, - {"option AssignPrecision","a positive integer or infinity"}, - {"option AssignRange","True or False"}, - {"option AssignReplace","a (possibly empty) list of string replacement rules"}, - {"option AssignTemporary","a list of the form {_Symbol|_String,Sequence|Array}"}, - {"option AssignToArray","a (possibly empty) list of symbols"}, - {"option AssignToFile","a string"}, - {"option AssignTrig","True or False"}, - {"option AssignZero","True or False"}}; - -(* Function to check the data types of options with error messages. *) - -OptionTest[expr_,var_,assignfn_,opts___?OptionQ]:= - Module[{defaults=Options[assignfn],optlist,types,linbrk,acase, - aend,fnumsQ,hypQ,indent,index,albl,amxsz,optQ, - prec,rangeQ,arep,tvar,atoarry,atofile,trigQ,zeroQ}, - - optlist = - {linbrk,acase,aend,fnumsQ,hypQ,indent,index,albl,amxsz,optQ, - prec,rangeQ,arep,tvar,atoarry,atofile,trigQ,zeroQ} = - Map[First,defaults] /. {opts} /. defaults; - - types = { -If[VectorQ[var], - MatchQ[expr,_List]&&Length[var]===Length[expr], - If[ListQ[var],False,True] -], -MatchQ[linbrk,False|{_Integer?Positive,_String}], -MatchQ[acase,Default|LowerCase|UpperCase], -StringQ[aend], -MatchQ[fnumsQ,True|False], -MatchQ[hypQ,True|False], -StringQ[indent], -MatchQ[index,_Integer?Positive|0], -MatchQ[albl,_Integer?(0<#<100000&)|_String?(StringLength[#]<6&)], -MatchQ[amxsz,_Integer?(#>=200&)|Infinity], -MatchQ[optQ,True|False], -MatchQ[prec,_Integer?Positive|Infinity], -MatchQ[rangeQ,True|False], -MatchQ[arep,{}|{(_String->_String)...}], -MatchQ[tvar,{}|{_Symbol|_String,Sequence|Array}], -MatchQ[atoarry,{___Symbol}], -StringQ[atofile], -MatchQ[trigQ,True|False], -MatchQ[zeroQ,True|False] }; - -(* Add optimization variable to list of arrays and avoid duplicates. *) - -If[optQ&&MatchQ[#,{_Symbol,Array}], - optlist[[-4]] = Union[ Join[ atoarry, {First[#]} ] ] -]& @ (Optimize`OptimizeVariable /. {opts} /. Options[Optimize`Optimize]); - - Check[ - MapThread[ - If[#1,#1,Message[assignfn::args,Apply[Sequence,#2]]]&, - {types,errmsgs} - ]; optlist, (* Return list of option values. *) - $Failed, (* Option of wrong type. *) - assignfn::args (* Check only for these messages. *) - ] - ]; (* End of OptionTest. *) - - - -(* C assignment format. *) - -SetAttributes[CAssign,HoldFirst]; - -Options[CAssign]:= { -AssignBreak->{Options[$Output,PageWidth][[1,2]]-2,"\\\n"}, -AssignCase->Default, AssignEnd->";", AssignFortranNumbers->False, AssignHyperbolic->False, -AssignIndent->"", AssignIndex->0, AssignLabel->"", AssignMaxSize->Infinity, -AssignOptimize->False, AssignPrecision->$MachinePrecision-1, -AssignRange->False, AssignReplace->{" "->""}, AssignTemporary->{"t",Array}, -AssignToArray->{}, AssignToFile->"", AssignTrig->True, AssignZero->True}; - -CAssign[lhs_:"",expr_?(!OptionQ[#]&),opts___?OptionQ]:= - Module[{optvals}, - optvals /; - And[ - (optvals = OptionTest[expr,GetShape[lhs],CAssign,FilterOptions[CAssign,opts]])=!=$Failed, - optvals = CMain[lhs,expr,optvals,{FilterOptions[Optimize`Optimize,opts]}]; - True - ] - ]; - - -(* Perform assignments and code translation. Output resulting list as a - column and avoid string delimiters "". *) - -SetAttributes[CMain,HoldFirst]; - -CMain[lhs_,expr_,{linbrk_,acase_,aend_,fnumsQ_,hypQ_,indent_,index_,albl_, -amxsz_,optQ_,prec_,rangeQ_,arep_,tvar_,atoarry_,atofile_,trigQ_,zeroQ_},optopts_]:= -Block[{$RecursionLimit=Infinity}, - Block[atoarry, - - AssignTemporaryIndex = 0; - -(* Format C Arrays. *) - - Map[ (Format[#[i__],CForm]:=HoldForm[Part[#,i]])&, atoarry ]; - - ColumnForm[ - Flatten[ - CommonAssign[ - Makelhs[lhs,CForm], - RangeTest[ - CDefs[ - MyN[expr,prec,atoarry,CMain], - trigQ,hypQ,optQ,prec,atoarry,optopts], - prec,CForm,rangeQ], - CForm, - " = ",acase,aend,tvar,atofile,zeroQ, - indent,index,albl,linbrk,amxsz,arep - ] - ] - ] //OutputForm - ] -]; (* End of CMain.*) - - - -(* Define rules for C translation. *) - -(* C expression head replacement. *) - -SetAttributes[ApplyCDefs,Listable]; - -ApplyCDefs[expr_]:= CRH[Map[CRH,expr,-2]]; - -Literal[CRH[ArcTan[x_,y_]]]:= atan2[y,x]; - -(* Nest logical operators. *) - -Literal[CRH[Equal[x_,y_,z__]]]:= Apply[CD[And], Map[CD[Equal][x,#]&,{y,z}] ]; -Literal[CRH[e:Unequal[x_,y_,z__]]]:= - Apply[CD[And], - Flatten[ Table[Map[CD[Unequal][e[[i]],#]&,Drop[{x,y,z},i]],{i,Length[e]-1}] ] - ]; -Literal[CRH[(h:Greater|GreaterEqual|Less|LessEqual)[x_,y__,z_]]]:= - Apply[CD[And],MapThread[CD[h],{{x,y},{y,z}}]]; -Literal[CRH[Inequality[x_,op_,y_,z__]]]:= CD[And][CD[op][x,y],CRH[Inequality[y,z]]]; -Literal[CRH[Inequality[x_,op_,y_]]]:= CD[op][x,y]; - -(* Recover minus sign. *) - -Literal[CRH[Times[-1.,x__]]]:= CD[Times][-1,x]; - -(* Replace heads in remaining expressions. *) - -Literal[CRH[expr_]]:= Operate[CD,expr]; - -(* Legal C functions. *) - -cfuns = {abs,acos,AddTo,asin,atan,atan2,ceil,cos,cosh,Decrement, - div,DivideBy,exp,fabs,floor,fmod,frexp,Increment,labs,ldexp,ldiv, - log,log10,mod,modf,pow,Power,PreIncrement,PreDecrement,rand,srand, - sin,sinh,sqrt,SubtractFrom,tan,tanh,TimesBy}; - -ANSIC[funct_]:= - If[MemberQ[cfuns,funct], - funct, - Message[AssignFunction::undef,funct,"C"]; funct - ]; - -(* Add C definitions. *) - -SetAttributes[CDefs,{HoldAll}]; - -CDefs[expr_,trigQ_,hypQ_,optQ_,prec_,atoarry_,{optopts___}]:= - Block[{Csc,Cot,Sec,ArcCsc,ArcCot,ArcSec,Csch,Coth,Sech, - ArcCsch,ArcCoth,ArcSech,acosh,asinh,atanh,CD,pow}, - With[{one=N[1,prec],two=N[2,prec]}, - Module[{optexpr}, - -(* Handled correctly by CForm. *) - - CD[Times]=Times; CD[Plus]=Plus; CD[Equal]=Equal; CD[Unequal]=Unequal; - CD[Greater]=Greater; CD[Less]=Less; CD[GreaterEqual]=GreaterEqual; - CD[LessEqual]=LessEqual; CD[Or]=Or; CD[And]=And; CD[Not]=Not; - -(* Needs additional rules. *) - - CD[Power]=Power; - CD[IfThen]=IfThen; - -(* Numeric. *) - - CD[Abs]=abs; CD[Conjugate]=conjg; CD[Floor]=floor; CD[Max]=max; - CD[Min]=min; CD[Mod]=mod; CD[Random]=rand; CD[Round]=ceil; - CD[Sign]=sign; CD[Sqrt]=sqrt; - -(* Trigonometric related. *) - - CD[ArcCos]=acos; CD[ArcCosh]=acosh; CD[ArcSin]=asin; - CD[ArcSinh]=asinh; CD[ArcTan]=atan; CD[ArcTanh]=atanh; - CD[Cos]=cos; CD[Cosh]=cosh; CD[Sin]=sin; CD[Sinh]=sinh; - CD[Tan]=tan; CD[Tanh]=tanh; CD[Log]=log; CD[exp]=exp; - -(* Numbers. *) - - CD[Complex]=Complex; CD[Rational]=Rational; - -(* Arrays. *) - - Map[ (CD[#]=#)&, atoarry]; - -(* Legal C function? Only check head once. *) - - CD[x_]:= CD[x]=ANSIC[x]; - -(* Add format rules. *) - - If[trigQ, - Csc[x_]:= Evaluate[one/CD[Sin][x]]; - Cot[x_]:= Evaluate[one/CD[Tan][x]]; - Sec[x_]:= Evaluate[one/CD[Cos][x]]; - ArcCsc[x_]:= Evaluate[CD[ArcSin][one/x]]; - ArcCot[x_]:= Evaluate[CD[ArcTan][one/x]]; - ArcSec[x_]:= Evaluate[CD[ArcCos][one/x]]; - ]; - - If[hypQ, - Csch[x_]:= Evaluate[one/CD[Sinh][x]]; - Coth[x_]:= Evaluate[one/CD[Tanh][x]]; - Sech[x_]:= Evaluate[one/CD[Cosh][x]]; - ArcCsch[x_]:= Evaluate[CD[ArcSinh][one/x]]; - ArcCoth[x_]:= Evaluate[CD[ArcTanh][one/x]]; - ArcSech[x_]:= Evaluate[CD[ArcCosh][one/x]]; - CD[ArcCosh][x_]:= Evaluate[CD[Log][x+CD[Sqrt][x^2-one]]]; - CD[ArcSinh][x_]:= Evaluate[CD[Log][x+CD[Sqrt][x^2+one]]]; - CD[ArcTanh][x_]:= Evaluate[CD[Log][(one+x)/(one-x)]/two]; - CD[ArcTanh][(x_:one)/y_]:= Evaluate[CD[Log][(y+x)/(y-x)]/two]; - ]; - -(* Apply formatting rules and optimize. *) - - optexpr = If[optQ, AssignOpt[#,optopts], # ]& @ ApplyCDefs[expr]; - -(* Add remaining formatting rules. These are applied here to avoid - any conflict with code optimization. *) - - Block[{Power}, - -(* Rational powers. *) - - Power[x_,Rational[1,2]]:= Evaluate[CD[Sqrt][x]]; - Power[x_,Rational[-1,2]]:= Evaluate[one/CD[Sqrt][x]]; - - Power[a_,Rational[b_,c_]]:= - With[{nb=N[b,prec],nc=N[c,prec]}, pow[a,HoldForm[nb/nc]] ]; - -(* Remaining powers. *) - - Power[a_,b_?(NumberQ[#]&&#!=-1&)]:= pow[a,N[b,prec]]; - Power[a_,b_?(#=!=-1&)]:= pow[a,b]; - - optexpr - - ] - ] - ] - ]; (* End of CDefs. *) - - - -(* Define FORTRAN assignment format. *) - -SetAttributes[FortranAssign,HoldFirst]; - -Options[FortranAssign]:= { -AssignBreak->{If[#>72,72,#]&[-1+Options[$Output,PageWidth][[1,2]]], - "\n & "}, AssignCase->Default, AssignEnd->"", -AssignFortranNumbers->True, AssignHyperbolic->False, -AssignIndent->" ", AssignIndex->1, AssignLabel->"", -AssignMaxSize->5000, AssignOptimize->False, -AssignPrecision->$MachinePrecision-1, AssignRange->False, -AssignReplace->{" "->""}, AssignTemporary->{"t",Sequence}, AssignToArray->{}, -AssignToFile->"", AssignTrig->True, AssignZero->True}; - - -FortranAssign[lhs_:"",expr_?(!OptionQ[#]&),opts___?OptionQ]:= - Module[{optvals}, - optvals /; - And[ - (optvals = OptionTest[expr,GetShape[lhs],FortranAssign, - FilterOptions[FortranAssign,opts]])=!=$Failed, - optvals = FMain[lhs,expr,optvals,{FilterOptions[Optimize`Optimize,opts]}]; - True - ] - ]; - - -SetAttributes[FMain,HoldFirst]; - -FMain[lhs_,expr_,{linbrk_,acase_,aend_,fnumsQ_,hypQ_,indent_,index_,albl_, -amxsz_,optQ_,prec_,rangeQ_,arep_,tvar_,atoarry_,atofile_,trigQ_,zeroQ_},optopts_]:= - Block[{d,e,$RecursionLimit=Infinity}, - Module[{newexpr,expsymb,AvoidRule=False}, - - AssignTemporaryIndex = 0; - -(* Attach rule for formatting real numbers with FortranForm. *) - - If[fnumsQ, - Unprotect[Real]; - Format[expsymb,FortranForm] = If[prec>8, d, e]; (* Choose exponent. *) - -(* Toggle to avoid infinite recursion formatting FORTRAN numbers. *) - - Real/: Format[r_Real,FortranForm]:= - (SequenceForm[First[#] 10, expsymb, -1+Last[#]]& @ - MantissaExponent[r]) /; (AvoidRule=!AvoidRule); - ]; - -(* Perform assignments and code translation. *) - - newexpr = - CommonAssign[ - Makelhs[lhs,FortranForm], - RangeTest[ - FortranDefs[ - MyN[expr,prec,atoarry,FMain], - trigQ,hypQ,optQ,prec,atoarry,optopts], - prec,FortranForm,rangeQ], - FortranForm, - " = ",acase,aend,tvar,atofile,zeroQ, - indent,index,albl,linbrk,amxsz,arep - ]; - -(* Remove real number rule. *) - - If[fnumsQ, - Format[Format`Private`r$_Real,FortranForm]=.; - Protect[Real]; - ]; - -(* Output a list as a column and avoid string delimiters "". *) - - ColumnForm[ Flatten[newexpr] ] //OutputForm - - ] - ]; (* End of FMain. *) - - - -(* Define rules for FORTRAN translation. *) - -(* FORTRAN expression head replacement. *) - -SetAttributes[ApplyFortDefs,Listable]; - -ApplyFortDefs[expr_]:= FRH[Map[FRH,expr,-2]]; - -Literal[FRH[ArcTan[x_,y_]]]:= atan2[y,x]; - -(* Nest logical operators. *) - -Literal[FRH[Equal[x_,y_,z__]]]:= Apply[FD[And], Map[FD[Equal][x,#]&,{y,z}] ]; -Literal[FRH[e:Unequal[x_,y_,z__]]]:= - Apply[FD[And], - Flatten[ Table[Map[FD[Unequal][e[[i]],#]&,Drop[{x,y,z},i]],{i,Length[e]-1}] ] - ]; -Literal[FRH[(h:Greater|GreaterEqual|Less|LessEqual)[x_,y__,z_]]]:= - Apply[FD[And],MapThread[FD[h],{{x,y},{y,z}}]]; -Literal[FRH[Inequality[x_,op_,y_,z__]]]:= FD[And][FD[op][x,y],FRH[Inequality[y,z]]]; -Literal[FRH[Inequality[x_,op_,y_]]]:= FD[op][x,y]; - -(* Recover minus sign. *) - -Literal[FRH[Times[-1.,x__]]]:= FD[Times][-1,x]; - -(* Replace heads in remaining expressions. *) - -Literal[FRH[expr_]]:= Operate[FD,expr]; - -(* Legal FORTRAN functions. *) - -fortfuns = {abs,acos,aimag,aint,alog,alog10,amax0,amax1,amin0,amin1,amod, - anint,asin,atan,atan2,cabs,ccos,cexp,char,clog,cmplx,conjg,cos,cosh, - csin,csqrt,dabs,dacos,dasin,datan,datan2,dble,dcos,dcosh,ddim,dexp, - dim,dint,dlog,dlog10,dmax1,dmin1,dmod,dnint,dprod,dsign,dsin,dsinh, - dsqrt,dtan,dtanh,exp,float,iabs,ichar,idim,idint,idnint,ifix,index, - int,isign,len,lge,lgt,lle,llt,log,log10,max,max0,max1,min,min0,min1, - mod,nint,real,sign,sin,sinh,sngl,sqrt,tan,tanh}; - -ANSIF[funct_]:= - If[MemberQ[fortfuns,funct], - funct, - Message[AssignFunction::undef,funct,"FORTRAN"]; funct - ]; - -(* Add FORTRAN definitions. *) - -SetAttributes[FortranDefs,{HoldAll}]; - -FortranDefs[expr_,trigQ_,hypQ_,optQ_,prec_,atoarry_,{optopts___}]:= - Block[{Csc,Cot,Sec,ArcCsc,ArcCot,ArcSec,Csch,Coth,Sech, - ArcCsch,ArcCoth,ArcSech,acosh,asinh,atanh,FD}, - With[{one=N[1,prec],two=N[2,prec]}, - Module[{optexpr}, - -(* Handled correctly by FortranForm. *) - - FD[Times]=Times; FD[Plus]=Plus; FD[Equal]=Equal; FD[Unequal]=Unequal; - FD[Greater]=Greater; FD[Less]=Less; FD[GreaterEqual]=GreaterEqual; - FD[LessEqual]=LessEqual; FD[Or]=Or; FD[And]=And; FD[Not]=Not; - -(* Needs additional rules. *) - - FD[Power]=Power; - -(* Numeric. *) - - FD[Abs]=abs; FD[Conjugate]=conjg; FD[Floor]=int; FD[Max]=max; - FD[Min]=min; FD[Mod]=mod; FD[Re]=real; FD[Round]=nint; FD[Sqrt]=sqrt; - -(* Trigonometric related. *) - - FD[ArcCos]=acos; FD[ArcCosh]=acosh; FD[ArcSin]=asin; - FD[ArcSinh]=asinh; FD[ArcTan]=atan; FD[ArcTanh]=atanh; - FD[Cos]=cos; FD[Cosh]=cosh; FD[Sin]=sin; FD[Sinh]=sinh; - FD[Tan]=tan; FD[Tanh]=tanh; FD[Log]=log; FD[exp]=exp; - -(* Numbers. *) - - FD[Complex]=Complex; FD[Rational]=Rational; - -(* Arrays. *) - - Map[ (FD[#]=#)&, atoarry ]; - -(* Legal FORTRAN function? Only check head once. *) - - FD[x_]:= FD[x]=ANSIF[x]; - -(* Add format rules. *) - - If[trigQ, - Csc[x_]:= Evaluate[one/FD[Sin][x]]; - Cot[x_]:= Evaluate[one/FD[Tan][x]]; - Sec[x_]:= Evaluate[one/FD[Cos][x]]; - ArcCsc[x_]:= Evaluate[FD[ArcSin][one/x]]; - ArcCot[x_]:= Evaluate[FD[ArcTan][one/x]]; - ArcSec[x_]:= Evaluate[FD[ArcCos][one/x]]; - ]; - - If[hypQ, - Csch[x_]:= Evaluate[one/FD[Sinh][x]]; - Coth[x_]:= Evaluate[one/FD[Tanh][x]]; - Sech[x_]:= Evaluate[one/FD[Cosh][x]]; - ArcCsch[x_]:= Evaluate[FD[ArcSinh][one/x]]; - ArcCoth[x_]:= Evaluate[FD[ArcTanh][one/x]]; - ArcSech[x_]:= Evaluate[FD[ArcCosh][one/x]]; - FD[ArcCosh][x_]:= Evaluate[FD[Log][x+FD[Sqrt][x^2-one]]]; - FD[ArcSinh][x_]:= Evaluate[FD[Log][x+FD[Sqrt][x^2+one]]]; - FD[ArcTanh][x_]:= Evaluate[FD[Log][(one+x)/(one-x)]/two]; - FD[ArcTanh][(x_:one)/y_]:= Evaluate[FD[Log][(y+x)/(y-x)]/two]; - ]; - -(* Apply formatting rules and optimize. *) - - optexpr = If[optQ,AssignOpt[#,optopts],#]& @ ApplyFortDefs[expr]; - -(* Add remaining formatting rules. These are applied here to avoid - any conflict with code optimization. *) - - Block[{Power}, - -(* Rational powers. *) - - Power[x_,Rational[1,2]]:= Evaluate[FD[Sqrt][x]]; - Power[x_,Rational[-1,2]]:= Evaluate[one/FD[Sqrt][x]]; - - Power[a_,Rational[b_,c_]]:= - With[{nb=N[b,prec],nc=N[c,prec]}, HoldForm[a^(nb/nc)] ]; - - optexpr - ] - - ] - ] - ]; (* End of FortranDefs. *) - - - - -(* Define Maple assignment format. *) - -SetAttributes[MapleAssign,HoldAll]; - -Options[MapleAssign]:= { -AssignBreak->{Options[$Output,PageWidth][[1,2]]-2,"\\\n"}, -AssignCase->Default, AssignEnd->";", AssignFortranNumbers->False, AssignHyperbolic->False, -AssignIndent->"", AssignIndex->1, AssignLabel->"", AssignMaxSize->Infinity, -AssignOptimize->False, AssignPrecision->Infinity, AssignRange->False, -AssignReplace->{}, AssignTemporary->{}, AssignToArray->{}, -AssignToFile->"", AssignTrig->False, AssignZero->True}; - - -MapleAssign[lhs_:"",expr_?(!OptionQ[#]&),opts___?OptionQ]:= - Module[{optvals}, - optvals /; - And[ - (optvals = OptionTest[expr,GetShape[lhs],MapleAssign,opts])=!=$Failed, - optvals = MMain[lhs,Unevaluated[expr],optvals]; True - ] - ]; - - -SetAttributes[MMain,HoldFirst]; - -MMain[lhs_,expr_,{linbrk_,acase_,aend_,fnumsQ_,hypQ_,indent_,index_,albl_, -amxsz_,optQ_,prec_,rangeQ_,arep_,tvar_,atoarry_,atofile_,trigQ_,zeroQ_}]:= - Block[{$RecursionLimit=Infinity}, - - AssignTemporaryIndex = 0; - -(* Perform assignments and code translation. *) - - OutputForm[ - Flatten[ - CommonAssign[ - Makelhs[lhs,InputForm], - MyN[Evaluate[MapleDefs[expr]],prec,atoarry], - InputForm, - " := ",acase,aend,tvar,atofile,zeroQ, - indent,index,albl,linbrk,amxsz,arep - ] - ] //ColumnForm - ] - - ] (* End of MMain. *) - - - -(**** Maple function redefinitions. ****) - -SetAttributes[MRH,HoldAll]; - -ApplyMapleDefs[expr_]:= MapAll[ MRH, Unevaluated[expr] ]; - -(* Special Mathematica expressions. *) - -Literal[MRH[Head[x_]]]:= MapleFun[Head,0,x]; -Literal[MRH[Part[x_,y_]]]:= MapleFun[Part,0,x]; -Literal[MRH[Part[x_,y_List]]]:= MapleFun[Part,Apply[Sequence,y],x]; - -Literal[MRH[Replace[x_,rep_]]]:= MapleFun[Replace,rep,x]; -Literal[MRH[ReplaceAll[x_,rep_]]]:= MapleFun[ReplaceAll,rep,x]; - -Literal[MRH[Rule[Trig,True]]]:= trig; -Literal[MRH[Rule[x_,y_]]]:= SequenceForm[MapleArgs["=",x,y]]; -Literal[MRH[Equal[x_,y_]]]:= SequenceForm[MapleArgs["=",x,y]]; - -(* Nest logical operators. *) - -Literal[MRH[Equal[x_,y_,z__]]]:= - Apply[MD[And], Map[SequenceForm[MapleArgs[MD[Equal],x,#]]&,{y,z}] ]; -Literal[MRH[e:Unequal[x_,y_,z__]]]:= - Apply[MD[And], - Flatten[ - Table[ - Map[SequenceForm[MapleArgs[MD[Unequal],e[[i]],#]]&,Drop[{x,y,z},i]], - {i,Length[e]-1}] - ] - ]; -Literal[MRH[Unequal[x_,y_]]]:= SequenceForm[MapleArgs[MD[Unequal],x,y]]; -Literal[MRH[(h:Greater|GreaterEqual|Less|LessEqual)[x_,y__,z_]]]:= - Apply[MD[And],MapThread[SequenceForm[MapleArgs[MD[h],#1,#2]]&,{{x,y},{y,z}}]]; -Literal[MRH[(h:Greater|GreaterEqual|Less|LessEqual)[x_,y_]]]:= - SequenceForm[MapleArgs[MD[h],x,y]]; -Literal[MRH[Inequality[x_,op_,y_,z__]]]:= -MD[And][SequenceForm[MapleArgs[MD[op],x,y]],MRH[Inequality[y,z]]]; -Literal[MRH[Inequality[x_,op_,y_]]]:= SequenceForm[MapleArgs[MD[op],x,y]]; - -(* Logicals. *) - -MRH[True] = true; MRH[False] = false; - -(* Trigonometric related. *) - -Literal[MRH[ArcTan[x_,y_]]]:= Evaluate[MapleFun[MD[ArcTan],y,x]]; -Literal[MRH[Power[MRH[E],x_]]]:= Evaluate[MapleFun[MD[Exp],x]]; - -(* Required for formatting. *) - -Literal[MRH[x_SequenceForm|x_OutputForm]]:= x; - -(* Arithmetic. *) - -Literal[MRH[x_Plus|x_Power|x_Times]]:= x; - -Literal[MRH[x_Complex|x_Integer|x_Rational|x_Real]]:= x; - -Literal[MRH[Infinity|ComplexInfinity|DirectedInfinity[___]]]:= - Evaluate[MD[DirectedInfinity]]; - -(* Lists. *) - -Literal[MRH[List[x__]]]:= SequenceForm[OutputForm["["],MapleArgs[",",x],OutputForm["]"]]; - -(* General function head replacement. *) - -special = {And,Or,Complex,D,Factorial,Integrate,Product,Sum, - Series,Sign,NSolve,Solve}; - -Literal[MRH[f_[x__]]]:= If[MemberQ[special,f], MD[f][x], MapleFun[f,x] ]; - -(* Remaining expressions. *) - -Literal[MRH[expr_]]:= MD[expr]; - -(**** End of Maple function redefinitions. ****) - - -(**** Maple function head redefinitions. ****) - - MD[Abs]=abs; MD[AiryAi]=Ai; MD[AiryBi]=Bi; MD[And]=and; MD[ArcCos]=arccos; MD[ArcCosh]=arccosh; - MD[ArcCot]=arccot; MD[ArcCoth]=arccoth; MD[ArcCsc]=arccsc; MD[ArcCsch]=arccsch; - MD[ArcSec]=arcsec; MD[ArcSech]=arcsech; MD[ArcSin]=arcsin; MD[ArcSinh]=arcsinh; - MD[ArcTan]=arctan; MD[ArcTanh]=arctanh; MD[BernoulliB]=bernoulli; - MD[Binomial]=binomial; MD[Collect]=collect; MD[Cos]=cos; MD[Cosh]=cosh; - MD[CosIntegral]=Ci; MD[Cot]=cot; MD[Coth]=coth; MD[Csc]=csc; MD[Csch]=csch; - MD[D]=diff; MD[Denominator]=denom; MD[DirectedInfinity]=infinity; MD[Erf]=erf; - MD[Erfc]=erfc; MD[EulerE]=euler; MD[Exp]=exp; MD[Expand]=expand; MD[ExpIntegral]=Ei; - MD[Factor]=factor; MD[Factorial]=factorial; MD[Gamma]=GAMMA; - MD[Head]=op; MD[Integrate]=int; - MD[Length]=nops; MD[Log]=log; MD[LogGamma]=lnGAMMA; MD[Map]=map; MD[Max]=max; - MD[Min]=min; MD[Mod]=mod; MD[N]=evalf; MD[NIntegrate]=int; MD[NSolve]=fsolve; MD[Not]=not; - MD[Null]=NULL; MD[Numerator]=num; MD[Or]=or; MD[Part]=op; MD[PolyGamma]=Psi; - MD[PolyLog]=dilog; MD[Product]=product; MD[Replace]=subs; MD[ReplaceAll]=subs; - MD[Roots]=RootOf; MD[Round]=round; MD[Sec]=sec; MD[Sech]=sech; - MD[Series]=series; MD[Sign]=sign; MD[Simplify]=simplify; MD[Sin]=sin; - MD[Sinh]=sinh; MD[SinIntegral]=Si; MD[Solve]=solve; MD[Sqrt]=sqrt; MD[Sum]=sum; - MD[Tan]=tan; MD[Tanh]=tanh; MD[Together]=normal; - -(* Logical symbols. *) - - MD[Greater]=">"; MD[GreaterEqual]=">="; MD[Less]="<"; MD[LessEqual]="<="; - MD[Equal]="="; MD[Unequal]="<>"; - -(* Not yet implemented. *) - - MD[x_]:= x; - -(**** End of Maple function head redefinitions. ****) - - - - -(**** Rules to convert arguments and functions to Maple form. ****) - -(* Recursive argument conversion. *) - -MapleArgs[str_,x_]:= x; -MapleArgs[str_,x_,y__]:= Sequence[x,OutputForm[str],MapleArgs[str,y]]; - -(* Function conversion. *) - -MapleFun[f_,x__]:= SequenceForm[MD[f],OutputForm["("],MapleArgs[",",x],OutputForm[")"]]; - -MapleDerivs[SequenceForm[_,a_,_,b_,_]]:= SequenceForm[a,OutputForm["$"],b]; - -MapleDerivs[x_]:= x; - -MapleRange[SequenceForm[_,x_,_,r2_,_],str_]:= - SequenceForm[ x,OutputForm["="],MapleArgs[str,1,r2] ]; - -MapleRange[SequenceForm[_,x_,_,r1_,_,r2_,_],str_]:= - SequenceForm[ x,OutputForm["="],MapleArgs[str,r1,r2] ]; - -MapleRange[x__,y_]:= x; - -MapleSeries[x_]:= - Module[{mterms = Map[MapleRange[#,","]&,x],trunc}, - trunc = Max[Map[Part[#,-1]&,mterms]]; (* Max truncation order. *) - SequenceForm[ - OutputForm["["], - Apply[Sequence, Insert[ Map[Drop[#,-1]&,mterms], OutputForm["]"], {-1,-2}] ], - trunc - ] - ]; - -(**** End of rules to convert arguments and functions to Maple form. ****) - - -(* Define rules for Maple translation. *) - -SetAttributes[MapleDefs,{HoldAll}]; - -MapleDefs[expr_]:= - Block[{and,or,diff,factorial,int,product,sum,series,sign,fsolve,solve}, - -(* Add formatting rules. *) - - and[x__]:= SequenceForm[MapleArgs[" and ",x]]; - or[x__]:= SequenceForm[MapleArgs[" or ",x]]; - diff[x_,a_]:= MapleFun[diff,x,MapleDerivs[a]]; - diff[x_,a__,b_]:= diff[ diff[x,a], MapleDerivs[b]]; - factorial[x_]:= SequenceForm[x,OutputForm["!"]]; - int[f_,x_]:= MapleFun[int,f,MapleRange[x,".."]]; - int[f_,x__,y_]:= MapleFun[int,int[f,x], MapleRange[y,".."]]; - product[x_,y_]:= MapleFun[product,x,MapleRange[y,".."]]; - product[x_,y__,z_]:= MapleFun[product,product[x,y],MapleRange[z,".."]]; - sum[x_,y_]:= MapleFun[sum,x,MapleRange[y]]; - sum[x_,y__,z_]:= MapleFun[sum,sum[x,y],MapleRange[z]]; - series[x_,y_]:= MapleFun[series,x,MapleRange[y,","]]; - series[x_,y__,z_]:= MapleFun[mtaylor,x,MapleSeries[{y,z}]]; - sign[x_Complex]:= MapleFun[signum,x]; - sign[x_]:= MapleFun[sign,x]; - fsolve[x__]:= MapleFun[fsolve,x] /. {"["->"{","]"->"}"}; - solve[x__]:= MapleFun[solve,x] /. {"["->"{","]"->"}"}; - - ApplyMapleDefs[Unevaluated[expr]] - - ]; (* End of Maple Defs. *) - - - - -(* Define assignment for specified format. *) - -SetAttributes[Assign,HoldFirst]; - -Options[Assign]:= { -AssignBreak->{Options[$Output,PageWidth][[1,2]]-1,"\n"}, -AssignCase->Default, AssignEnd->"", AssignFortranNumbers->False, AssignHyperbolic->False, -AssignIndent->"", AssignIndex->1, AssignLabel->"", AssignMaxSize->Infinity, -AssignOptimize->False, AssignPrecision->Infinity, AssignRange->False, -AssignReplace->{}, AssignTemporary->{}, AssignToArray->{}, -AssignToFile->"", AssignTrig->False, AssignZero->True}; - - -Assign[lhs_:"",expr_?(!OptionQ[#]&),form_?(!OptionQ[#]&),opts___?OptionQ]:= - Module[{optvals}, - optvals /; - And[ - (optvals = OptionTest[expr,GetShape[lhs],Assign,opts])=!=$Failed, - optvals = AMain[lhs,expr,form,optvals]; True - ] - ]; - - -(* Perform assignments and code translation. *) - -SetAttributes[AMain,HoldFirst]; - -AMain[lhs_,expr_,form_,{linbrk_,acase_,aend_,fnumsQ_,hypQ_,indent_,index_, -albl_,amxsz_,optQ_,prec_,rangeQ_,arep_,tvar_,atoarry_,atofile_,trigQ_,zeroQ_}]:= -Block[{$RecursionLimit=Infinity}, - - AssignTemporaryIndex = 0; - - OutputForm[ - Flatten[ - CommonAssign[ - Makelhs[lhs,form], - MyN[expr,prec,atoarry], - form, - " = ",acase,aend,tvar,atofile,zeroQ, - indent,index,albl,linbrk,amxsz,arep - ] - ] //ColumnForm - ] -]; (* End of AMain. *) - - - -(* Define main assignment formatting. *) - -(* This definition ensures compatibility with the code optimization - package Optimize.m - which returns a list of replacement rules - and an optimized expression or list of expressions. *) - -CommonAssign[lhs_,{optrules:{__Rule},expr_},form_,args__]:= - Apply[ - CommonAssign[ Join[Makelhs[#1,form],{lhs}], - Join[#2,{expr}],form,args]&, - Thread[optrules,Rule] - ]; - -(* Assignments to single expressions. *) - -CommonAssign[lhs_,expr_,form_,eqstr_,acase_,aend_,tvar_,atofile_, - zeroQ_,indent_,index_,albl_,linbrk_,amxsz_,arep_]:= - Module[{outchan,lbllen,redexpr,strings}, - -(* Remove zero-valued expressions and add array indices to lhs. *) - - redexpr = RemoveZeros[lhs,expr,form,index,!zeroQ]; - -(* Break up long expressions and convert to strings. *) - - strings = - Map[BreakExpression[#,eqstr,amxsz,tvar,form]&,redexpr]; - -(* Apply string replacement rules and indentation/termination strings. *) - - strings = - Map[ - StringJoin[ indent, #, aend ]&, - StringReplace[ Flatten[{strings}],arep ] - ]; - -(* Attach a label to the first expression. *) - - label = ToString[albl]; lbllen = StringLength[label]; - - If[ lbllen =!=0, - strings[[1]] = StringJoin[label,StringDrop[strings[[1]],lbllen]] - ]; - -(* Convert to LowerCase, or UpperCase case. *) - - Switch[acase, - UpperCase,strings = Map[ToUpperCaseCase,strings], - LowerCase,strings = Map[ToLowerCaseCase,strings] - ]; - -(* Add continuation characters to break up long lines of code. *) - - If[ListQ[linbrk], strings = Map[BreakLines[#,linbrk]&,strings] ]; - -(* Output results to a file. *) - - If[atofile=!="", - outchan = OpenWrite[atofile,FormatType->OutputForm]; - Write[outchan, strings //ColumnForm]; - Close[outchan] ]; - - strings (* Output. *) - - ]; (* End of CommonAssign. *) - - - -(* Add index and delete zero-valued elements. *) - -(* Remove zero-valued elements. The variable index is used as - an offset for the starting index. *) - -(* Lists of assignments (remove outer List). *) - -RemoveZeros[lhs_List,rhs_List,format_,index_,remzero_]:= - Apply[Join,MapThread[ RemoveZeros[#1,#2,format,index,remzero]&, {lhs,rhs} ]]; - -(* No zeros removed. *) - -RemoveZeros["",rhs_List,format_,index_,False]:= Thread[{"",Flatten[rhs]}]; - -RemoveZeros[lhs_,rhs_List,format_,index_,False]:= - JoinIndices[lhs,FindPositions[rhs,Null],Flatten[rhs],format,index]; - -RemoveZeros[lhs_,rhs_,format_,index_,False]:= {{lhs,rhs}}; - -(* Zeros removed. *) - -(* Check for expressions with no non-zeros present. *) - -AssignZero::continue = "Expression encountered with no non-zero elements. -Continuing with zero assignments."; - -RemoveZeros[lhs_,0,format_,index_,True]:= - (Message[AssignZero::continue]; {{lhs,0}}); - -RemoveZeros["",rhs_List,format_,index_,True]:= - Module[{redrhs = Flatten[Delete[rhs,Position[rhs,0,Heads->False]]]}, - If[redrhs==={}, Message[AssignZero::continue]; redrhs = Flatten[rhs]]; - Thread[{"",redrhs}] - ]; - -RemoveZeros[lhs_,rhs_List,format_,index_,True]:= - Module[{redrhs = Flatten[Delete[rhs,Position[rhs,0,Heads->False]]],posntest=0}, - If[redrhs==={}, - Message[AssignZero::continue]; redrhs = Flatten[rhs]; posntest=Null;]; - JoinIndices[lhs,FindPositions[rhs,posntest],redrhs,format,index] - ]; - -RemoveZeros[lhs_,rhs_,format_,index_,True]:= {{lhs,rhs}}; - -(* Find positions of non-null and non-zero elements. *) - -FindPositions[expr_,Null]:= - Position[ Function[x,UnsameQ[x,Null],Listable][expr],True,Heads->False]; - -FindPositions[expr_,0]:= - Position[ Function[x,UnsameQ[x,0]&&UnsameQ[x,Null],Listable][expr],True,Heads->False]; - -(* Join index string to lhs string. *) - -JoinIndices[lhs_,posns_List,rhs_,format_,index_]:= - (MapThread[ - {StringJoin[ lhs, StringIndex[#1,format] ],#2}&, - {posns+index-1,Flatten[rhs]} - ]); - -(* StringIndex is used to convert the position into the - appropriate form for an array element. *) - -StringIndex[psn_,CForm]:= - StringReplace[ ToString[psn] ,{"{"->"[","}"->"]",", "->"]["}]; - -(* Default is FORTRAN case. *) - -StringIndex[psn_,_]:= - StringReplace[ ToString[psn] ,{"{"->"(","}"->")"}]; - - - -(* Break up large expressions into sub-expressions. *) - -BreakUp[subexpr_,maxlen_,temp_]:= - If[LengthTest[subexpr,maxlen], - Fragment[subexpr,maxlen,temp], - subexpr (* else *) - ]; - -(* Add temporary variable and sub-expression to list. *) - -AddTemp[temp_,subexpr_]:= (parts = Join[parts,{{temp,subexpr}}]; temp); - -(* Test used for permissible sub-expression size. *) - -LengthTest[expr_,maxlen_]:= ByteCount[expr]>maxlen; - -(* Ignore numeric exponents, temporary variables etc. *) - -Fragment[subexpr:(_temp|_?AtomQ),maxlen_,tmpvar_]:= subexpr; - -(* Binary decomposition of Plus and Times. *) - -Fragment[subexpr:(_Plus|_Times),maxlen_,temp_]:= - If[LengthTest[subexpr,maxlen], - With[{quo = Quotient[Length[subexpr],2]}, - BreakUp[ - Head[subexpr][ - Fragment[Take[subexpr,quo],maxlen,temp], - Fragment[Drop[subexpr,quo],maxlen,temp] - ], - maxlen,temp] - ], - AddTemp[temp[++index],subexpr] (* else *) - ]; - -(* n-ary decomposition of remaining functions. *) - -Fragment[subexpr_,maxlen_,temp_]:= - If[LengthTest[subexpr,maxlen], - BreakUp[Map[Fragment[#,maxlen,temp]&,subexpr],maxlen,temp], - AddTemp[temp[++index],subexpr] (* else *) - ]; - - -(* Recursively decompose expression. *) - -BreakExpression[args_,eqstr_,Infinity,_,form_]:= - MyFormat[args,eqstr,form]; - -Assign::notemp = "No temporary variable was specified. Continuing -with original expression."; - -BreakExpression[args_,eqstr_,maxlen_,{}|{"",_},form_]:= - (Message[Assign::notemp]; MyFormat[args,eqstr,form]); - -BreakExpression[{lhs_,expr_},eqstr_,maxlen_,{tvar_,tform_},form_]:= - Block[{index=0,parts={},$RecursionLimit=Infinity}, - Module[{outexpr,tmp}, - -(* Array or sequence of temporaries. *) - - If[tform===Array, - If[form===CForm, - Format[tmp[i_],form]:=HoldForm[Part[#,i]], - Format[tmp[i_],form]:=#[i] - ], - Format[tmp[i_],form]:= SequenceForm[#,i] - ]& @ ToExpression[ToString[tvar]]; - -(* Recursively break up expression and re-use temporary variables. *) - - outexpr = BreakUp[expr,maxlen,tmp]; - -(* Store maximum number of temporaries introduced. *) - - If[ index>AssignTemporaryIndex, AssignTemporaryIndex=index ]; - -(* Output list of temp strings and final expression. *) - - {Map[ MyFormat[#,eqstr,form]&, parts ], - MyFormat[{lhs,outexpr},eqstr,form]} - ] - ]; (* End of BreakExpression *) - - -(* Convert the expression to a string of appropriate form. *) - -MyFormat[{"",expr_},_,form_]:= ToString[ expr, FormatType->form ]; - -MyFormat[{lhs_String,expr_},eqstr_,form_]:= - StringJoin[ lhs, eqstr, ToString[ expr, FormatType->form ] ]; - -MyFormat[{lhs_,expr_},eqstr_,form_]:= - StringJoin[ - ToString[ lhs, FormatType->form ], - eqstr, - ToString[ expr, FormatType->form ] - ]; - - -(* Break up long lines of code and add continuation characters. *) - -BreakLines[string_,{lineln_,indstr_}]:= - Module[{indlen=StringLength[indstr],linelen,numlines, - strlen=StringLength[string]}, - -(* (\n is counted as one character). *) - - linelen = lineln - indlen + 1; - - If[strlen >=linelen, - numlines = Floor[(strlen - (linelen+indlen))/linelen]; - StringJoin[ - StringTake[string,indlen-1], (* first part *) - Table[ - StringTake[ - string, (* middle part *) - {linelen i + indlen, - linelen (i+1) + indlen-1} - ]<>indstr - ,{i,0,numlines}], - StringTake[ - string (* end part *) - ,((numlines+1) linelen + indlen-1) - strlen] - ], - string (* else *) - ] - ]; (* End of BreakLines. *) - - -(* Determine `shape' of lhs lists. Extract elements to avoid evaluation. *) - -SetAttributes[GetShape,{Listable,HoldAll}]; -GetShape[_]:=""; - - -(* Make lhs into a list of held strings. *) - -SetAttributes[Makelhs,{Listable,HoldAll}]; -Makelhs[lhs_String,_]:= lhs; -Makelhs[lhs_,InputForm]:= ToString[ HoldForm[lhs] ]; -Makelhs[lhs_,form_]:= ToString[ form[HoldForm[lhs]] ]; - - -(* Slightly modified version of N. Arguments to specified - symbols are temporarily protected from N. *) - -SetAttributes[MyN,HoldAll]; - -(* Protect exponential from N. *) - -MyN[expr_,_DirectedInfinity,_,CMain|FMain]:= - Block[{E}, E /: Power[E,x_]:= exp[x]; expr ]; - -(* Approximate numeric Exp. *) - -MyN[args__,CMain|FMain]:= - Block[{E}, E /: Power[E,x_?(!NumberQ[#]&)]:= exp[x]; MyN[args] ]; - -(* Infinite Precision. *) - -MyN[expr_,_DirectedInfinity,__]:= expr; - -(* Finite precision. *) - -MyN[expr_,prec_,{}]:= - If[prec===$MachinePrecision, - #, - # //. {r_Real:>SetPrecision[r,prec]} - ]& @ N[ expr, prec ]; - -(* Finite Precision, protect array arguments from N. *) - -MyN[expr_,prec_,atoarry_]:= - Block[atoarry, - SetAttributes[atoarry,NProtectedAll]; - MyN[ expr, prec, {} ] - ]; - - -(* Optimize expressions. *) - -AssignOpt[expr_,optopts___?OptionQ]:= - Check[ - RuleGen[ - Optimize`Optimize[expr,optopts], - expr - ], - Message[AssignOptimize::fail]; expr, (* Else proceed with unoptimized expression. *) - Optimize`Optimize::args (* Check only for this message. *) - ]; - -(* Check for optimization. *) - -RuleGen[{{},expr_},expr_]:= expr; (* No optimization. *) -RuleGen[optexpr_,_]:= optexpr; (* Optimization. *) - - - -(* Test range of real and integer numbers. *) - -spfortran = {2.^-126,2.^127,HoldForm[-2^31],HoldForm[2^31-1], - -2^31,2^31-1,"single"}; -spc = {2.^-125,2.^128,HoldForm[-2^31],HoldForm[2^31-1],-2^31,2^31-1,"single"}; -dpfortran = {2.^-1022,2.^1023,HoldForm[-2^63],HoldForm[2^63-1], - -2^63,2^63-1,"double"}; -dpc = {2.^-1021,2.^1024,HoldForm[-2^63],HoldForm[2^63-1],-2^63,2^63-1,"double"}; - -SetAttributes[RangeTest,HoldFirst]; - -RangeTest[expr_,nprec_,form_,False]:= expr; - -RangeTest[expr_,nprec_,FortranForm,True]:= - CheckRange[expr,FortranForm,If[nprec<=8, spfortran, dpfortran]]; - -RangeTest[expr_,nprec_,CForm,True]:= - CheckRange[expr,CForm,If[nprec<=8, spc, dpc]]; - -AssignRange::float = "Expression contains machine numbers outside -the permissible range `1` to `2` for IEEE `3` precision."; - -AssignRange::integer = "Expression contains integers outside the -permissible range `1` to `2` which cannot be represented in IEEE -`3` precision and have been converted to floating point numbers."; - -CheckRange[expr_,form_,{xrmin_,xrmax_,xihmin_,xihmax_,ximin_,ximax_,prec_}]:= - Module[{complxQ,intmsg=True,intQ,realQ,rlmsg=True}, - - realQ = r_Real?((Abs[#]>xrmax||Abs[#]<xrmin)&&rlmsg&):> - (If[rlmsg, rlmsg=False; Message[AssignRange::float,xrmin,xrmax,prec]]; - r); - - intQ = i_Integer?(#>ximax||#<ximin&):> - (If[intmsg, intmsg=False; Message[AssignRange::integer,xihmin,xihmax,prec]]; - N[i] /. realQ); - - cmplxQ = Complex[r_,i_]:>Complex[r /. {realQ,intQ},i /. {realQ,intQ}]; - - expr /. {realQ,intQ,cmplxQ} - ]; (* End of CheckRange. *) - - -End[]; (* End `Private` Context. *) - -(* Protect exported symbols. *) - -SetAttributes[{Assign,CAssign,FortranAssign,MapleAssign},ReadProtected]; - -Protect[d,e,abs,acos,acosh,Ai,aimag,aint,alog,alog10,amax0,amax1,amin0,amin1, -amod,and,anint,arccos,arccosh,arccot,arccoth,arccsc,arccsch,arcsec,arcsech,arcsin, -arcsinh,arctan,arctanh,asin,asinh,atan,atan2,atanh,bernoulli,Bi,binomial,cabs, -ccos,ceil,cexp,char,Ci,clog,cmplx,collect,conjg,cos,cosh,cot,coth,csc,csch,csin, -csqrt,dabs,dacos,dasin,datan,datan2,dble,dcos,dcosh,ddim,denom,dexp,dilog,dim, -dint,dlog,dlog10,dmax1,dmin1,dmod,dnint,dprod,dsign,dsin,dsinh,dsqrt,dtan,dtanh, -Ei,erf,erfc,euler,evalf,exp,expand,factor,factorial,false,float,fsolve,GAMMA,iabs, -ichar,idim,idint,idnint,ifix,index,infinity,int,isign,len,lge,lgt,lle,llt,log,log10,lnGAMMA, -map,max,max0,max1,min,min0,min1,mod,mtaylor,nint,not,NULL,num,op,or,pow,Psi,real,RootOf, -round,sec,sech,series,Si,sign,sin,sinh,sngl,solve,sqrt,subs,tan,tanh,true, -LowerCase,UpperCase,Assign,AssignBreak,AssignCase,AssignEnd,AssignFortranNumbers, -AssignIndent,AssignHyperbolic,AssignLabel,AssignMaxSize,AssignPrecision, -AssignRange,AssignReplace,AssignTemporary,AssignToArray,AssignToFile,AssignTrig, -CAssign,FortranAssign,MapleAssign]; - -EndPackage[]; (* End package Context. *) diff --git a/Tools/External/SetTensor.m b/Tools/External/SetTensor.m deleted file mode 100644 index e718ff0..0000000 --- a/Tools/External/SetTensor.m +++ /dev/null @@ -1,723 +0,0 @@ -Print["Ignore the following warning message: Lower::shdw"]; - -Needs["MathTensor`","MathTensor.m"]; -Needs["Format`","Format.m"]; -Needs["Optimize`","Optimize.m"]; -BeginPackage["SetTensor`",{"MathTensor`","Format`","Optimize`"}]; -Print["Turning off AssignFunction::undef"]; -Off[AssignFunction::undef]; - -AddReplaceList::usage = "AddReplaceList is a place to store a -list of replacement rules"; -FortranInt::usage = "FortranInt[x1_Integer] formats an integer -for output by the fwri function."; - -AddReplace::usage = "fwri[...,AddReplace->{from_String,to_String}]"; - -MTEval[x1_] := EvalMT[RicciToAffine[x1]] -MTEval[x1_,x2_] := EvalMT[RicciToAffine[x1],x2] - -SetSqrtDetg::usage = "Define this quantity to aid evaluation where -the determinant of the metric is required."; - -(* something to make SqrtDetg work right *) -prot=Unprotect[Power,Abs]; -Power[Power[sDetgVal,2],1/2] := sDetgVal -Abs[sDetgVal^2] := sDetgVal^2 -DetgVal := sDetgVal^2 -Protect /@ prot; - -SetTensor::usage = -"SetTensor[name[ua,ub],{{n11,n12,n13,...},{n12,n22,...},...}] -SetTensor[name[ua,ub],MyFunction[ua,ub]] -The first form given above for SetTensor will -assign the components of the array on the right hand side to the -tensor on the left hand side. The second form of this function -is like SetComponents, except that it does far more than merely -summing dummy indices. Most importantly, it does not evaluate -MyFunction until a numerical value has been assigned to the index. -Secondly, before assigning it calls EvalMT to resolve ordinary -derivatives, sums, etc. If you wish to see a message as each -component is evaluated, you can do that by typing On[EvalMT::PrintIndex] -before calling SetTensor."; - -EvalMT::PrintIndex = "If this flag is set by the On[] command, then -EvalMT prints its second argument when it runs (if it was called -with two arguments. This means that SetTensor will tell you the -indices of each component of the tensor it is assigning values to." - -EvalMT::usage = "EvalMT[expression], EvalMT[name[la,lb],{la->-1,lb->-1}] -In the first form, this function lowers all covariant derivative -indices, expands all sums, and evaluates all ordinary derivatives, -and Affine connection terms. In the second form, the values of the -indices in the expression are given in list. In order for this command -to work properly, you must first use the command InitializeMetric."; - -InitializeMetricg = InitializeMetric; -InitalizeMetric::usage = "InitializeMetric[array], -InitializeMetric[array,MySimplify] This command -takes the array metdn, assigns its components to the lower indexed -Metricg, assigns Inverse[metdn] to the upper index Metricg, and then -evaluates all AffineG components. An optional function to simplify -these various stages is provided."; - -EvalOD::usage = "EvalOD[expression] Evaluates ordinary derivatives -within an expression."; - -MetricgVal::usage = "This object contains the component values for the -Metricg tensor." - -AffineGVal::usage = "This object contains the component values for the -AffineG tensor." - -SubFun::usage = "SubFun[expression,pattern,value] operates like -the normal substitution rule ->, except that if pattern is -a function it will also substitute for derivatives of that -function. Furthermore, if pattern is an expression to a power, -it will match the negative power, Thus SubFun[Sqrt[x]+1/Sqrt[x],Sqrt[x],y] -becomes y+1/y."; - -(* The user can over-ride this function *) -Clear[MakeDeriv]; -MakeDeriv[x1_,x2_,x3_] := ToExpression["d"<>x1<>x2<>x3] -MakeDeriv::usage = "MakeDeriv[derivs,function,args] a user definable -function to make the representation of derivatives more suitable for -printing."; - -fwri::usage = "fwri[OuputStream,lhs,rhs] an interface to the FortranAssign -command provided through MathSource. It is an unnecessary but user- -friendly piece of syntatic sugar. Obsolete. See new function: FortranWrite"; - -$FortranOptimize::usage = "Set to True or False. Determines whether Fortran -output will be optimized automatically." -$FortranOptimize = True; - -$FortranReplace::usage = "This is an array of rules of the form one might -hand to StringReplace. It will be used to process the output of FortranWrite."; - -$FortranArrayList::usage = "The optimize routine eliminates multiple calls to -subroutines within a function by assigning the output of the function to a -variable. Since it is hard to distinguish arrays from functions syntactically -in fortran, you can use this variable to avoid the unnecessary creation of -excess scalar variables." - -FortranReplaceDefault::usage = "Calling FortranReplaceDefault[] resets the value of -$FortranReplace to its initial value." - -FortranOpen::usage = "A call to OpenWrite that makes sure the file is closed first. Aside -from this, it is the same as OpenWrite." -FortranWrite::usage = "A call to WriteString and FortranAssign, but wrapped together -and buffered. Output is only actually done when FortranFlush or FortranClose are called. -The purpose of the buffering is to allow the FortranAssign optimizer to re-use common -subexpressions in the equations."; - -FortranFlush::usage = "FortranFlush[fd] : Causes the output of the last several -FortranWrite's to be done."; - -FortranClose::usage = "Calls FortranFlush and then closes the file."; - -Iter::usage = "Iter[Tensor Object,Code] is a type of looping mechanism -similar to multiple nested For[] loops. The looping is over the number -of unique index values to the tensor object."; - -DerivRule::usage = "A rule to implement the MakeDeriv[] function."; - -AddStrs::usage = "AddStrs[Append/Prepend,arg] adds a string to the -front/end of each element of a -list composed of lists and/or strings (which may have -a minus sign) or zero's."; - -AddIndex::usage = "AddIndex[Append/Prepend,arg] adds an index to a -list composed of lists and/or strings (which may have -a minus sign) or zero's."; - -AddSym2::usage = "AddSym2[Append/Prepend,arg] adds two symmetric -indicies to a -list composed of lists and/or strings (which may have -a minus sign) or zero's."; - -AddAsym2::usage = "AddAsym2[Append/Prepend,arg] adds two -anti-symmetric indices to a -list composed of lists and/or strings (which may have -a minus sign) or zero's."; - -AddDeps::usage = "AddDeps[arg] adds the default dependency list -to the end of all strings in its arg, then runs Clear and ToExpression -on each symbol name." - -DepList::usage = "DepList[leftbracket,rightbracket] provides a string -object that represents the default list. The arguments are strings -which provide the left and right brackets you wish to use, (), [], or {}"; - -FortranOutputOfDepList::usage = "FortranOutputOfDepList is a variable -which is set to the string value you want your dependcy list to map -to when Fortran output is produced. It is null by default."; -FortranOutputOfDepList = ""; - -Set1Component::usage = "Set1Component[tensor element,value] sets one -element of a tensor. It takes into account the symmetries of the -tensor when performing its operation."; - -DefaultDepString::usage = "Set the value of this string to the default -dependency of your functions (without the brackets). For examples \"x,y,z\"."; - -NeedsIt::usage = "NeedsIt[func] Returns true if the function has -been in an expression handed to AddtoNeedsIt[]"; - -AddToNeedsIt::usage = "AddToNeedsIt[expr] finds all functions in -expr of the form f_Symbol[a__] and makes NeedsIt[f[a]] return -True."; - -ClearNeedsIt::usage = "ClearNeedsIt[] causes NeedsIt[_] to return -False."; - -Begin["Private`"]; - -EvalMT::DimensionNotSet = "This function will not evaluate -properly until you set the variable Dimension"; -DimNotSet[] := If[Not[MatchQ[Dimension,_Integer]], - Message[EvalMT::DimensionNotSet]; - True,False]; - -(* flag setting... *) -prot = Unprotect[On,Off]; -On[EvalMT::PrintIndex] := (Flag[EvalMT::PrintIndex] = True); -Off[EvalMT::PrintIndex] := (Flag[EvalMT::PrintIndex] = False); -Protect /@ prot; -On[EvalMT::PrintIndex] - -(* some helper functions *) -(* just some shorthand *) -sti[x1_] := ToString[InputForm[x1]] - -(* make a string that represents a comma joined list *) -CommaJoin[{x1_}] := x1 -CommaJoin[{x1_,x2_}] := x1<>","<>x2; -CommaJoin[{x1_,x2__}] := x1<>","<>CommaJoin[{x2}]; - -(* NoSimp is a simplification method that does nothing, - * PostSimp is a mechanism for applying the simplification - * method (its first arg) after the evaluation of EvalMT. - *) -Clear[PostSimp,NoSimp]; -NoSimp[x1_] := x1 -PostSimp[si_,fun_] := si[fun] /; FreeQ[fun,EvalMT]; -PostSimp[si_,x1_List] := PostSimp[si,#]& /@ x1; - -(* This section handles the form of SetTensor that - * takes a list as an argument. - *) -Clear[SetTensor,FunctionArg,ArrayArg] -FunctionArg[x1_?LowerIndexQ] := "l"<>ToString[x1] -FunctionArg[x1_?UpperIndexQ] := "u"<>ToString[x1] -ArrayArg[x1_?LowerIndexQ] := "-l"<>ToString[x1] -ArrayArg[x1_?UpperIndexQ] := "u"<>ToString[x1] - -SetTensor[x1_,x2_] := SetTensor[x1,x2,NoSimp]; - -SetTensor[x1_[x2___],x3_List,si_] := Module[{ftmp,atmp,res}, - If[DimNotSet[],Return[]]; - ftmp = "["<>CommaJoin[FunctionArg /@ {x2}]<>"]"; - atmp = "[["<>CommaJoin[ArrayArg /@ {x2}]<>"]]"; - res="Iter["<>sti[x1]<>ftmp<>",Set1Component["<> - sti[x1]<>ftmp<>","<>sti[PostSimp[si,x3]]<>atmp<>"]]"; - ToExpression[res]; - ] - -(* FakeIndex will not fool MathTensor, but it can - * be used for SetTensor, because SetTensor only - * looks at the Upper/LowerIndexQ functions. - *) -Clear[FakeIndex]; -FakeIndex[la_?LowerIndexQ] := Module[{tmp}, - tmp = Unique[la]; - LowerIndexQ[tmp] ^:= True; - tmp - ] -FakeIndex[la_?UpperIndexQ] := Module[{tmp}, - tmp = Unique[la]; - UpperIndexQ[tmp] ^:= True; - tmp - ] - -(* This form of SetTensor uses a function to set - * values. *) -SetTensor[x1_[x2__],x3_?NoList,si_] := Module[{rule,v1}, - If[DimNotSet[],Return[]]; - rule = {x2} /. v1_?IndexQ -> (v1->FakeIndex[v1]); - tmp="Private`AssignVals["<> - ToString[InputForm[x1[x2] /. rule]]<>",Private`PostSimp["<> - sti[si]<>",EvalMT["<> - ToString[InputForm[x3]]<>","<> - ToString[InputForm[rule]]<>"]]];"; - ToExpression[tmp]; -] - -Print["Turning off MetricgFlag"]; -Off[MetricgFlag]; - -(* evaluate ordinary derivatives *) -EvalOD[x1_] := Module[{ODtmp}, - On[EvaluateODFlag]; - ODtmp = x1; - Off[EvaluateODFlag]; - ODtmp]; - -(* rule for lowering covariant derivative indicies *) -RuleUnique[ - CDdown, - CD[x3_,ua_], - CD[x3,lb] Metricg[ub,ua], - UpperIndexQ[ua] - ]; - -(* fix a bug that exists in some versions of Mathematica *) -(* this is a kludge *) -DiagonalQ[x1_List] := Module[{id}, - id = IdentityMatrix[Length[x1]]; - If[x1 - (x1*id) === 0*id,True,False]]; -Unprotect[Inverse]; -Inverse[x1_?DiagonalQ] := Module[{i1,i2,ln}, - ln = Length[x1]; - Table[If[i1 == i2,1/x1[[i1,i2]],0], - {i1,1,ln},{i2,1,ln}] -]; -Protect[Inverse]; -(* End bug fix *) - -(* MathTensor Evaluator *) -EvalMT[x1_] := EvalMT[x1,{}]; -EvalMT[x1_,x2_] := Module[{tmp}, - If[DimNotSet[],Return[]]; - tmp=Dum[x1]; - While[Not[FreeQ[tmp,LieD]], - tmp=LieDtoCD[tmp]; - ]; (* expand LieD's *) - tmp=ApplyRulesRepeated[tmp,{CDdown}]; - (* we can only evaluate down indicies *) - While[Not[FreeQ[tmp,CD]], - tmp=CDtoOD[tmp]; - ]; (* expand CD's *) - tmp = SubVals[tmp]; - tmp = MakeSum[tmp]; - If[x2 =!= {}, - (* If[FreeQ[Messages[EvalMT], - Literal[EvalMT::PrintIndex] :> $Off[___]], *) - If[Flag[EvalMT::PrintIndex], - Print[sti[x2]] ]; (* print messages if PrintIndex is On *) - tmp = tmp //. x2; (* substitute index values *) - ]; - tmp = SubVals[tmp]; (* needed for Epsilon *) - tmp = EvalOD[tmp]; - tmp - ]; - -SetSqrtDetg[x2_,x1_] := Module[{},signDetg=x2;SqrtDetg = x1] - -SubVals[x1_] := (x1 /. { - Metricg -> MetricgVal, - AffineG -> AffineGVal, - Sqrt[Abs[Detg]] -> SqrtDetg - }) /. Detg -> signDetg SqrtDetg^2; - -(* Sets things up so that EvalMT can evaluate rapidly *) -NoList[_List] := False -NoList[_] := True -InitializeMetric[metdn_List] := InitializeMetric[metdn,NoSimp]; -InitializeMetric[metdn_List,SimpOp_?NoList] := Module[{}, - metup = SimpOp[Inverse[metdn]]; - InitializeMetric[metdn,metup,SimpOp]]; -InitializeMetric[metdn_List,metup_List] := - InitializeMetric[metdn,metup,NoSimp]; -InitializeMetric[metdn_List,metup_List,SimpOp_] := Module[{}, - Clear[MetricgVal]; - DefineTensor[MetricgVal,"gv",{{2,1},1}]; - SetTensor[MetricgVal[la,lb],metdn,SimpOp]; - SetTensor[MetricgVal[ua,ub],metup,SimpOp]; - SetTensor[MetricgVal[ua,lb],IdentityMatrix[Dimension]]; - - Print["Evaluating Affine Connections"]; - - Clear[AffineGVal]; - DefineTensor[AffineGVal,"Gv",{{1,3,2},1}]; - SetTensor[AffineGVal[ua,lb,lc],AffineToMetric[ - AffineG[ua,lb,lc] - ],SimpOp]; - - Print["Done"]; -]; - - -(* Set Zero's: this looks at the symmetries of a tensor - * and assigns the value 0 to components which must have - * it by symmetry, i.e. RiemannR[-1,-1,-2,-3]. - *) - -(* In reality, this functionality should be provided by - * DefineTensor, and probably will be eventually. - *) - -(* consider the example: - * DefineTensor[foo,{{2,1},-1}]; - * consider what SetZeros[foo[la,lb]] does... - * AllSymmetries returns {{1, 2}, 1, {2, 1}, -1} - *) -SetZeros[foo_[x1___]] := SetZeros[foo,{x1},AllSymmetries[foo[x1]] ]; -SetZeros[foo_,x1_List,sym_List] := Module[{zer,i1,i2}, - For[i1=1,i1<=Length[sym],i1 += 2, - If[sym[[i1+1]] == -1, - (* We collect indices not in their proper order, and - * stick them in zer. If sym[[i1]] were {1,3,2} - * zer would become {2,3}. *) - (* When we get here, in our example, - * i1==3, sym[[i1]]=={2,1} *) - zer={}; - For[i2=1,i2<=Length[sym[[i1]]],i2++, - If[i2 != sym[[i1,i2]],zer=AppendTo[zer,i2]]; - ]; - (* We make a copy of the non-symmetric index list, - * in our example {la,lb}, and use the next loop - * to fill it in so that it becomes {la,la} *) - list2 = x1; - For[i2=2,i2<=Length[zer],i2++, - list2[[ zer[[i2]] ]] = list2[[ zer[[1]] ]]; - ]; - (* Now, in our example, we call AssignVals with - * as follows AssignVals[foo[la,la],0] *) - AssignVals[list2 /. List->foo,0]; - ]; - ]; -] - - -(* EatIndex takes a list of objects (indices) and an object to be removed - * from the list, and returns the list with all instances of object - * rmoved. For example: EatIndex[{a,b,b,c},{b}] returns {a,c} - *) -EatIndex[x1_List,x2_] := EatIndex[x1,{},x2]; -EatIndex[{x1_,x2___},{x3___},x1_] := EatIndex[{x2},{x3},x1]; -EatIndex[{x1_,x2___},{x3___},x4_] := EatIndex[{x2},{x3,x1},x4]; -EatIndex[{},x2_List,x3_] := x2 - -(* just a shorthand *) -AssignVals[x1_[xa__],x2_] := Module[{tmp,tmp2,res}, - IterNoZeros[x1[xa],Set1Component[x1[xa],x2]]; -]; - -SetAttributes[AssignVals,HoldRest]; - -Iter[x1_,x2_] := Module[{}, - If[DimNotSet[],Return[]]; - SetZeros[x1]; - IterNoZeros[x1,x2] -] -IterNoZeros[foov_[v1___],thingv_] := Module[{IterInternal}, - Clear[IterInternal,IterSet]; - IterSet[0] := 0; - IterInternal[{x1_?LowerIndexQ,x2___},fo_,foo_,thing_,ru_List] := - Module[{ix,tmp}, - For[ix=-Dimension,ix<0,ix++, - tmp=ru; - IterInternal[EatIndex[{x2},x1],fo,foo /. x1->ix,thing, - AppendTo[tmp,x1->ix]] - ] - ]; - IterInternal[{x1_?UpperIndexQ,x2___},fo_,foo_,thing_,ru_List] := - Module[{ix,tmp}, - For[ix=1,ix<=Dimension,ix++, - tmp=ru; - IterInternal[EatIndex[{x2},x1],fo,foo /. - x1->ix,thing,AppendTo[tmp,x1->ix]] - ] - ]; - IterInternal[{},foo_,IterSet[foo_[x1__]], - thing_,ru_List] := (Evaluate[Release[thing /. - ru]];IterSet[foo[x1]]=1); - IterInternal[{},fo_,x1_,x2_,ru_] := Null; - IterInternal[{v1},foov,IterSet[foov[v1]],Hold[thingv],{}]; - ]; -SetAttributes[Iter,HoldRest]; -SetAttributes[IterNoZeros,HoldRest]; - -(* SubFun is part of a larger idea for a more general substitution - * function. This version only does functions and powers - *) -Clear[SubFun,unList,mkdiv]; -SubFun[x1_,Power[x2_,x3_],x4_] := - x1 /. { - Power[x2,x3]->x4, - Power[x2,-x3]->1/x4 - }; - -unList[List[x1__]] := x1; -mkdiv[val_,nums_,args_] := Module[{tmp,ii}, - tmp=Table[{args[[ii]],nums[[ii]]},{ii,1,Length[args]}]; - D[val,Evaluate[unList[tmp]] ] - ]; - -SubFun[x1_,fun_[args__],val_] := - x1 /. { - fun[args]:>val, - Derivative[nums__][fun][args]:>mkdiv[val, - List[nums],List[args]] - }; - -SubFun[x1_,x2_,x3_] :> x1 /. x2 -> x3 -(* End of SubFun *) - -(* This section is for generating values for tensors *) -Clear[IsAppPrep]; -IsAppPrep[Prepend] := True; -IsAppPrep[Append] := True; -IsAppPrep[_] := False; - -Clear[AddStrs] -AddStrs[Append,x1_String,x2_String] := Module[{}, - If[DimNotSet[],Return[]];x1<>x2]; -AddStrs[Prepend,x1_String,x2_String] := x2<>x1; -AddStrs[pa_?IsAppPrep,x1_String,x2_List] := - AddStrs[pa,x1,#]& /@ x2; -AddStrs[x1_String,x2_] := AddStrs[Append,x1,x2]; -AddStrs[pa_,-x1_,x2_] := -AddStrs[pa,x1,x2]; -AddStrs[pa_,x1_,-x2_] := -AddStrs[pa,x1,x2]; -AddStrs[pa_,-x1_,-x2_] := AddStrs[pa,x1,x2]; -AddStrs[pa_,0,x2_] := 0 -AddStrs[pa_,x1_,0] := 0 -AddStrs[pa_,x1_List,x2_] := AddStrs[pa,#,x2]& /@ x1; -AddStrs[x1_List,x2_] := AddStrs[Append,x1,x2]; - -Clear[AddIndex]; -AddIndex[pa_?IsAppPrep,x1_String] := Module[{}, - If[DimNotSet[],Return[]]; - AddStrs[pa,x1,#]& /@ - Table[ToString[x[i]],{i,1,Dimension}]]; -AddIndex[pa_?IsAppPrep,x1_List] := AddIndex[pa,#]& /@ x1; -AddIndex[x1_] := AddIndex[Append,x1]; -AddIndex[pa_?IsAppPrep,-x1_] := -AddIndex[x1] -AddIndex[pa_?IsAppPrep,0] := Module[{i},Table[0,{i,1,Dimension}]] - -Clear[AddSym2,Sym2]; -Sym2[x1_Integer,x2_Integer] := Module[{tmp}, - If[DimNotSet[],Return[]]; - tmp = {x1,x2}; - tmp = Abs /@ tmp; - tmp = Sort[tmp]; - tmp = x /@ tmp; - tmp = ToString /@ tmp; - tmp = tmp /. List->StringJoin - ]; -Sym2[] := Module[{i,j},Table[Sym2[i,j], - {i,1,Dimension},{j,1,MathTensor`Dimension}] ]; -AddSym2[pa_?IsAppPrep,x1_String] := AddStrs[pa,x1,Sym2[]]; -AddSym2[pa_?IsAppPrep,x1_List] := AddSym2[pa,#]& /@ x1; -AddSym2[x1_] := AddSym2[Append,x1]; -AddSym2[pa_?IsAppPrep,0] := Module[{i,j}, - Table[0,{i,1,Dimension},{j,1,MathTensor`Dimension}] - ]; -AddSym2[pa_?IsAppPrep,-x1_] := -AddSym2[pa,x1]; - -Clear[AddAsym2,Asym2]; -Asym2[x1_Integer,x2_Integer] := Module[{tmp,sgn}, - If[DimNotSet[],Return[]]; - If[x1 === x2,Return[0]]; - tmp = {x1,x2}; - tmp = Abs /@ tmp; - tmp = Sort[tmp]; - sgn = If[tmp === {x1,x2},1,-1]; - tmp = x /@ tmp; - tmp = ToString /@ tmp; - tmp = tmp /. List->StringJoin; - tmp sgn - ]; -Asym2[] := Module[{i,j},Table[Asym2[i,j], - {i,1,Dimension},{j,1,MathTensor`Dimension}] ]; -AddAsym2[pa_?IsAppPrep,x1_String] := AddStrs[pa,x1,Asym2[]]; -AddAsym2[pa_?IsAppPrep,x1_List] := AddAsym2[pa,#]& /@ x1; -AddAsym2[x1_] := AddAsym2[Append,x1]; -AddAsym2[pa_?IsAppPrep,0] := Module[{i,j}, - Table[0,{i,1,Dimension},{j,1,MathTensor`Dimension}] - ]; -AddAsym2[pa_?IsAppPrep,-x1_] := -AddAsym2[pa,x1]; - -ClearStrs[x1_List] := ClearStrs /@ x1; -ClearStrs[x1_String] := Clear[x1]; -ClearStrs[-x1_String] := Clear[x1]; - -Clear[ExtendedToExpression]; -ExtendedToExpression[0] := 0; -ExtendedToExpression[-x1_String] := -ToExpression[x1]; -ExtendedToExpression[x1_String] := ToExpression[x1]; -ExtendedToExpression[x1_List] := ExtendedToExpression /@ x1; -AddDeps[x1_] := Module[{}, - If[DimNotSet[],Return[]]; - ClearStrs[x1]; - ExtendedToExpression[ AddStrs[Prepend,DepList["[","]"],x1] ] - ]; - -(* Note that this does not do the same thing as x1 = x2 - * by itself. MathTensor expressions order themselves - * according to symmetry, and this puts that action first - * in the order of evaluations. - *) -Clear[Set1Component]; -Set1Component[-x1_,x2_] := x1 = -x2; -Set1Component[x1_,x2_] := x1 = x2; - -(* Derivative conversion *) -Clear[DerivList,DerivWithRespect2,DerivOf,DerivDeps,StringRepeat]; - -(* I keep thinking that there must be some - * utility for this already, but I don't know - * what it is. - *) -StringRepeat[x1_,0] := ""; -StringRepeat[x1_,1] := x1; -StringRepeat[x1_String,n1_Integer] := - x1<>StringRepeat[x1,n1-1]; - -DerivList[n_,args_,n1_] := StringRepeat[ToString[args[[n]]],n1]; -DerivList[n_,args_,n1_,n2__] := DerivList[n,args,n1]<> - DerivList[n+1,args,n2]; -DerivWithRespect2[Derivative[n___][x2_][x3___]] := - DerivList[1,{x3},n]; -DerivOf[Derivative[x1___][x2_][x3___]] := ToString[x2] -DerivDeps[Derivative[x1___][x2_][x3___]] := "["<> - CommaJoin[ToString /@ {x3}]<>"]"; - -Clear[DerivRule]; -DerivRule := Derivative[x1___][x2_][x3___] :> - MakeDeriv[DerivWithRespect2[Derivative[x1][x2][x3]], - DerivOf[Derivative[x1][x2][x3]], - DerivDeps[Derivative[x1][x2][x3]] ]; - -Clear[DepList] -DepList[s1_String,s2_String] := Module[{i}, - If[DimNotSet[],Return[]]; - If[MatchQ[DefaultDepString,_String],Return[s1<> - DefaultDepString<>s2]]; - s1<>CommaJoin[Table[ToString[x[i]],{i,1,Dimension}]]<>s2 - ] - -Clear[NeedsIt,AddToNeedsIt]; -NeedsIt[_] := False -ClearNeedsIt[] := ( - Clear[NeedsIt]; - NeedsIt[_] := False; - ) -AddToNeedsIt[x1_] := Module[{tmp,x2,srule,dep}, - tmp=x1 /. DerivRule; - dep=DepList["[","]"]; - srule = sti[x2]<>"_Symbol"<>dep<> - " :> (NeedsIt["<> - sti[x2]<>dep<>"] = True; "<>sti[x2]<>dep<>")"; - tmp /. ToExpression[srule]; - ]; - -(* Here is how I make fwri, so I made a short symbol name for once. - * Once in a while we should save on typing.. - *) -Clear[fwri,GetAddReplaceRule,IsAddReplace,FortranAssignArray,IsCall] -GetAddReplaceRule[AddReplace->{x1_}] := x1; -IsAddReplace[AddReplace->_] := True -IsAddReplace[_] := False -FortranAssignArray[{x1___}] := FortranAssign[x1]; -IsCall[x1_] := Module[{tmp}, - tmp = ToString[x1]; - StringMatchQ[tmp,"call"] || - StringMatchQ[tmp,"Call"] || - StringMatchQ[tmp,"CALL"]] - -Clear[FortranInt] -FortranInt[x1_?PosIntegerQ] := ToExpression["EraseMe"<>ToString[x1]] -FortranInt[x1_?NegIntegerQ] := ToExpression["MinusSign"<>ToString[-x1]] - -Options[fwri] := {AddReplace->{x1_String->x2_String}}; -fwri[fd_,v1_,v2_,v3___] := Module[{tmp,i,faArgs,li}, - If[MatchQ[Dimension,_Integer], - tmp={DepList["(",")"]->FortranOutputOfDepList}, - tmp={} - ]; - tmp=AppendTo[tmp,"EraseMe"->""]; - tmp=AppendTo[tmp,"UND"->"_"]; - tmp=AppendTo[tmp,"MinusSign"->"-"]; - If[IsCall[v1],tmp=AppendTo[tmp,"="->""]]; - faArgs={}; li={v3}; - If[MatchQ[AddReplaceList,_List], - li=Join[li,AddReplaceList]]; - For[i=1,i<=Length[li],i++, - If[IsAddReplace[li[[i]]], - tmp=AppendTo[tmp,GetAddReplaceRule[li[[i]]] ], - faArgs=AppendTo[faArgs,li[[i]] ] - ]; - ]; - faArgs = AppendTo[faArgs,AssignReplace->tmp]; - faArgs = PrependTo[faArgs,v2 /. DerivRule]; - faArgs = PrependTo[faArgs,v1]; - Write[fd,FortranAssignArray[faArgs]]; -]; - -Clear[FortranOpen,FortranWrite,FortranClose,FortranSimp, -$FortranArrayList,$FortranReplace,DefaultFortranReplace,FortranFlush,FortranLHS,FortranRHS]; -DefaultFortranReplace[] := - $FortranReplace = { - "(r,q)"->"(i,j)", - "UND"->"_", - "sin(q)"->"sint(j)", - "cos(q)"->"cost(j)", - "ric"->"r", - "phi"->"p", - "tan(q)"->"tant(j)", - "EraseMe"->"", - "MinusSign"->"-" - }; -DefaultFortranReplace[]; -$FortranArrayList = {}; - -FortranOpen[file_] := FortranOpen[file,NoSimp]; -FortranOpen[file_,Simp_] := Module[{fd}, - Off[General::openx]; - Close[file]; - Print["Opening: ",file]; - fd = OpenWrite[file]; - FortranLHS[fd] = {}; - FortranRHS[fd] = {}; - FortranSimp[fd][x1_] := Simp[x1]; - Return[fd]; - ]; -FortranWrite[fd_,from_,to_,etc___] := Module[{tmpto}, - from /. xxx_[args___] :> ($FortranArrayList=Union[$FortranArrayList,{xxx}];xxx[i,j]); - tmpto = FortranSimp[fd][to /. DerivRule]; - FortranLHS[fd] = AppendTo[FortranLHS[fd],from]; - FortranRHS[fd] = AppendTo[FortranRHS[fd],tmpto]; - ]; -fprep[x1_] := Flatten[x1]; -fprep[{x1_}] := x1; -FortranFlush[fd_] := Module[{}, - If[Length[FortranLHS[fd]]==0,Return[]]; - If[$FortranOptimize, - WriteString[fd,FortranAssign[Evaluate[fprep[FortranLHS[fd]]], - Evaluate[fprep[FortranRHS[fd]]], - AssignOptimize->True,OptimizeNull->$FortranArrayList,OptimizePower->Binary, - AssignReplace->$FortranReplace],"\n"]; - , - WriteString[fd,FortranAssign[Evaluate[fprep[FortranLHS[fd]]], - Evaluate[fprep[FortranRHS[fd]]], - AssignReplace->$FortranReplace],"\n"]; - ]; - FortranLHS[fd]={}; - FortranRHS[fd]={}; -]; -FortranClose[_] := Print["Bad call to FortranClose -- not opened with FortranOpen"]; -FortranClose[OutputStream[s1_String, n1_Integer]] := Module[{fd}, - fd = OutputStream[s1, n1]; - FortranFlush[fd]; - Print["Closing: ",s1 ];Close[fd]; -]; - - -Protect[SetTensor,EvalOD,EvalMT,InitializeMetric,SetSqrtDetg, - Iter,AddToNeedsIt,ClearNeedsIt,fwri,DerivRule, - Set1Component]; - -End[]; -EndPackage[]; diff --git a/Tools/External/SetTensor.tex b/Tools/External/SetTensor.tex deleted file mode 100644 index b04cf21..0000000 --- a/Tools/External/SetTensor.tex +++ /dev/null @@ -1,843 +0,0 @@ -\documentstyle{article} -\begin{document} - -\title{{\it SetTensor}, a package for {\it MathTensor}} -\author{S. Brandt} -\maketitle -\section{Introduction} -{} - -{\it MathTensor} provides a series of powerful tools for evaluating -tensor objects. These functions must be implemented in a specific -sequence of steps if the desired output is to be obtained. First -you must apply transformation rules, make sure derivative indices -are lowered, evaluate covariant derivatives (the function {\tt -CDtoOD} may need to be called more than once to accomplish this -and there is no builtin automatic way to repeat it), make sums, -assign index values, and last of all to evaluate ordinary derivatives. -For optimization purposes it is useful to have some quantities -(like affine connections) pre-calculated. -All this can be a bit of a nuissance to write out. The {\it -SetTensor} package is designed to make this easier. - -Some of the functionality of {\it SetTensor} -can be obtained with the package -{\it Components}, but there are a few advantages to using -{\it SetTensor}. {\it Components} requires you to edit a template file -to define the metric in the appropriate way, set flags, etc. -No such file is needed with {\it SetTensor}. Also {\it Components} -may calculate -some quantities that you do not really need. You may only need -the lower, and not the upper, indexed values of the Riemann -tensor. With {\it SetTensor} you will only calculate the quantities -that you need. {\it Components} does not allow you to change the -size of your metric and the value of your metric components -during a session, {\it SetTensor} does. - -{\it SetTensor} adds new symbols to the environment, some of these -are as follows: -{\tt EvalMT}, {\tt Iter}, {\tt SetSqrtDetg}, -and {\tt InitializeMetric}. In order to use -these commands you need to -first define some basic objects, most of which are standard to -{\it MathTensor}. These standard objects are {\tt Dimension} and the -variables {\tt x[1]}, {\tt x[2]}, ... {\tt x[Dimension]}. You may also want -to define the value of {\tt Sqrt[Abs[Detg]]}. Your next step is -to call {\tt InitializeMetric}. - -{\tt InitializeMetric} can be called in one of four ways: -\begin{verbatim} -MetricDown = { ... }; -MetricUp = { ... } -(* will call Inverse[] to make MetricUp *) -InitializeMetric[MetricDown]; -(* will call Inverse[] to make MetricUp, then apply MySimp *) -(* to simplify the resulting matrix and affine connections. *) -InitializeMetric[MetricDown,MySimp]; -(* will simply accept the user's definition of MetricUp *) -InitializeMetric[MetricDown,MetricUp]; -(* will simply accept the user's definition of MetricUp *) -(* and apply MySimp to the affine connection terms *) -InitializeMetric[MetricDown,MetricUp,MySimp]; -\end{verbatim} -Where the {\tt MetricUp} and {\tt MetricDown} are -{\tt Dimension}$\times${\tt Dimension} matrices. - -The last two of the methods above are espcially important. It -may be that you are using a full 3-metric and do not wish -to have to deal with the true metric inverse. You might -prefer to deal with the metric in this form: -\begin{verbatim} -MetricDown = { - {g11[x,y,z],g12[x,y,z],g13[x,y,z]}, - {g21[x,y,z],g22[x,y,z],g23[x,y,z]}, - {g31[x,y,z],g32[x,y,z],g33[x,y,z]} -}; -MetricUp = { - {gu11[x,y,z],gu12[x,y,z],gu13[x,y,z]}, - {gu21[x,y,z],gu22[x,y,z],gu23[x,y,z]}, - {gu31[x,y,z],gu32[x,y,z],gu33[x,y,z]} -}; -\end{verbatim} -This form for {\tt MetricUp} will be much easier for -Mathematica to handle than {\tt Inverse[MetricDown]}. - -For added convenience, a function {\tt SubFun} is added -to this package which can be used to replace a function -(and all its derivatives) with a new form. The usage -is illustrated by this example: -\begin{verbatim} -In[]= - SubFun[f'[x]+f[x],f[x],x^2] -Out[]= - 2 x+x^2 -\end{verbatim} - -\section{The {\tt EvalMT} command} -Once these basic steps outlined above are accomplished, -it is a straightforward -matter to calculate the components of almost any tensor, or -scalar object within the {\it MathTensor} framework. For a scalar, you need -merely to issue the {\tt EvalMT} command. A complete example follows: -\begin{verbatim} -<<SetTensor.m -x[1] = theta; x[2] = phi; -Dimension = 2; -InitializeMetric[{ - {f1[theta,phi],0}, - {0,f2[theta,phi]}}]; -EvalMT[CD[foo[theta,phi],la,ua]] -\end{verbatim} -The routine {\tt EvalMT} will automatically lower all covariant -derivative indicices, sum paired indices, and evaluate ordinary -derivatives and affine connections. - -If you wish to call {\tt EvalMT} for an indexed quantity, you need -to supply a second argument. It works this way: -\begin{verbatim} -EvalMT[RicciToAffine[RicciR[li,lj]],{li->-1,lj->-1}] -\end{verbatim} -Note that because only the affine connections are defined, it is -necessary for you to provide the explicit call to the {\it MathTensor} -builtin command {\tt RicciToAffine}. In evaluating tensors and -components it is useful to remember the following additional -{\it MathTensor} commands: {\tt ScalarRtoAffine}, and {\tt RiemannToAffine}. - -%\section{The First Form of {\tt SetTensor}} -%{\it Mathematica} provides a command {\tt SetComponents} to assign -%components to a tensor the user defines, or one of the standard -%builtin tensors. Unfortunately, {\tt SetComponents} cannot be -%made to evaluate the ordinary derivatives of its arguments or -%to simplify them before assignment with any kind of ease. This -%is one of the motivations of {\tt SetTensor}. {\tt SetComponents} -%also does not recognize when antisymmetric indices make a component -%zero. {\tt SetTensor} does this automatically, thereby avoiding -%the needless calculation and simplification that may be necessary -%for {\it Mathematica} to realize that a component is zero. - -%If you only want to know one component of the Ricci tensor, the -%above example is fine. To evaluate them all, the {\it SetTensor} -%package -%provides the function {\tt SetTensor} which calls both the builtin -%{\tt SetComponents} and the new routine {\tt EvalMT}. -%It also allows for a means of post-processing the output of {\tt EvalMT} -%with a command such as {\tt Simplify}. -%You can use -%{\tt SetTensor} to calculate all the lower indexed -%Ricci components as follows: -%\begin{verbatim} -%SetTensor[RicciR[la,lb],RicciToAffine[RicciR[la,lb]] ]; -%\end{verbatim} -%This may take a while if you are using a higher dimensional or -%more complicated matrix. If you want to know what's happening, -%you can turn on the {\tt EvalMT::PrintIndex} flag using the {\tt -%On[]} command provided by Mathematica (i.e. you can simply type -%{\tt On[EvalMT::PrintIndex]}). If you do this it will -%print out the indices of the tensor component being evaluated, as -%each component is evaluated. - -%It may be that you wish to only assign simplified values to the -%Ricci tensor. The last argument to {\tt SetTensor} is understood -%to be a post-processing function, such as {\tt Simplify}. -%\begin{verbatim} -%SetTensor[RicciR[la,lb],RicciToAffine[RicciR[la,lb]],Simplify]; -%\end{verbatim} - -%However, it is my recommendation that you do not directly assign -%to any of {\it MathTensor}'s builtin objects. Instead, I recommend that -%you enter this command: -%\begin{verbatim} -%sym=Symmetries[RicciR[la,lb]]; -%DefineTensor[RicciRVal,"Rv",sym]; -%SetTensor[RicciRVal[la,lb],RicciToAffine[RicciR[la,lb]],Simplify]; -%\end{verbatim} -%I recommend this because you can clear {\tt RicciRVal} from your -%session and redefine it, something you cannot do to {\tt RicciR}. -%Moreover, you have lost nothing in the process. You can use -%{\tt RicciRVal} as follows to evaluate {\tt SclarR}. -%\begin{verbatim} -%EvalMT[RicciRVal[la,lb] Metricg[ua,ub]] -%\end{verbatim} -%In addition you now have the -%option to look at the same quantity {\em without} substituting -%for {\tt RicciR}. -%\begin{verbatim} -%tmp = EvalMT[RicciR[la,lb] Metricg[ua,ub]] -%\end{verbatim} -%It is completely legitimate to evalute {\tt RicciR} in this -%expression simply by doing this: -%\begin{verbatim} -%tmp /. RicciR->RicciRVal -%\end{verbatim} -%This is actually how {\it SetTensor} -%stores and evaluates the components for the metric -%and affine connections. -%That is, they are stored in {\tt MetricgVal} and -%{\tt AffineGVal} respectively and {\tt EvalMT} substitues them. -%You can access them directly if you -%want, for example, to know the components of the affine connection. -%Because {\it SetTensor} does nothing to the objects {\tt Metricg} and -%{\tt AffineG} you can call -%{\tt InitializeMetric} with different values during the same session -%and have the subsequent evaluations behave properly. - -%The {\tt SetTensor} command is actually used internally by {\tt -%InitializeMetric} to set the values of {\tt AffineGVal}. - -%\section{The Second Form of {\tt SetTensor}} - -%Another feature of the {\tt SetTensor} command is that it can be -%used to assign arrays to tensor objects. For example: -%\begin{verbatim} -%DefineTensor[Shift,"b",{{1},1}]; -%SetTensor[Shift[ua],{b1,b2,b3}]; -%\end{verbatim} -%Assigns the array on the right hand side to the upper indexed tensor -%components on the left. This mechanism is actually used internally -%by {\tt InitializeMetric} to assign the components to {\tt MetricgVal}. -%This summarizes the basic features of this package. - -\section{\tt SetSqrtDetg} - -In calculations involving the Levi-Civita symbol, {\tt Epsilon}, one -obtains (from {\it MathTensor} expressions like {\tt Sqrt[Abs[Detg]]} -or {\tt Sqrt[Abs[Detg]]/Detg}. The {\tt SetTensor} package provides -a function called {\tt SetSqrtDetg[]} which takes, as an argument, -a function which is assumed to be the absolute value of the square -root of the determinant. - -{\tt SetSqrtDetg[sign,val]} takes two arguments. The term -{\tt sign} must be a number with a value equal to either {\tt 1} -or {\tt -1}. -{\tt SetSqrtDetg[sign,val]} uses {\tt val} to represent -{\tt Sqrt[Abs[Detg]]}, and -{\tt sign*val${}^2$} to represent {\tt Detg} when it does not appear -otherwise. - - -\section{Iter[Tensor Object,Code]} -{\tt Iter} will loop over the {\em unassigned} indices of a tensor object, -taking into account the objects symmetries. The index variables -applied to the tensor object are filled in for the {\it Code} section to -use. For example: -\begin{verbatim} -DefineTensor[foo,{{2,1},1}]; -Iter[foo[la,lb], - Print[la," and ",lb]; -]; -\end{verbatim} -Produces the following output: -\begin{verbatim} -PermWeight::sym: Symmetries of foo assigned - -PermWeight::def: Object foo defined - --3 and -3 --3 and -2 --3 and -1 --2 and -2 --2 and -1 --1 and -1 -\end{verbatim} - -If we wish {\tt Iter} to avoid one or more of these indices -we can use {\tt Set1Component} which, as its name implies, sets -one component. Running the code -\begin{verbatim} -Set1Component[foo[-1,-2],0]; -Iter[foo[la,lb], - Print[la," and ",lb]; -]; -\end{verbatim} -produces -\begin{verbatim} - --3 and -3 --3 and -2 --3 and -1 --2 and -2 --1 and -1 -\end{verbatim} -Note that if a {\tt foo} had been anti-symmetric in its two -indices, then {\tt foo[-1,-1]} would automatically get the value -zero and {\tt Iter} would not loop over that element. For example: -\begin{verbatim} -DefineTensor[foo,{{2,1},-1}]; -Iter[foo[la,lb], - Print[la," and ",lb]; -]; -\end{verbatim} -Produces the following output: -\begin{verbatim} -PermWeight::sym: Symmetries of foo assigned - -PermWeight::def: Object foo defined - --3 and -2 --3 and -1 --2 and -1 -\end{verbatim} -\subsection{Assigning to Tensor Objects} -You can use Iter to fill in the components of a tensor object. -For example: -\begin{verbatim} -DefineTensor[foo,{{1},1}] -Iter[foo[la], - Set1Component[ - foo[la],{f1[x],f2[x],f3[x]}[[-la]] - ] -] -\end{verbatim} -will assign the values {\tt f1[x]}, etc. to the components of -the tensor object {\tt foo}. Note that {\tt la} takes on negative -values inside the {\tt Iter} loop, so when the array is indexed -we used a negative sign. - -You can also combine this with {\tt EvalMT} and evaluate the -simplified components of the {\tt Ricci} tensor. -\begin{verbatim} -DefineTensor[ric,{{2,1},1}]; -Iter[ric[la,lb], - Set1Component[ - ric[la,lb],Simplify[ - EvalMT[RicciToAffine[RicciR[lc,ld]],{lc->la,ld->lb}] - ] - ] -] -\end{verbatim} - -\section{SetTensor} -The package's namesake, the function {\tt SetTensor}, provides -a shorthand for calling {\tt Iter}. The following examples -illustrate how it works. -\begin{verbatim} -SetTensor[foo[la,ub],{ - {f1,f2,f3}, - {f4,f5,f6}, - {f7,f8,f9}}] -\end{verbatim} -is the equivalent of -\begin{verbatim} -Iter[foo[la,ub], - Set1Component[foo[la,ub],{ - {f1,f2,f3}, - {f4,f5,f6}, - {f7,f8,f9}}[[-la,ub]] - ] -] -\end{verbatim} -Notice that lower indices automatically get minus signs, but upper -indices don't. -\begin{verbatim} -SetTensor[ric[la,lb],RicciToAffine[RicciR[la,lb]]] -\end{verbatim} -is equivalent to -\begin{verbatim} -DefineTensor[ric,{{2,1},1}]; -Iter[ric[la,lb], - Set1Component[ - ric[la,lb], - EvalMT[RicciToAffine[RicciR[lc,ld]],{lc->la,ld->lb}] - ] -] -\end{verbatim} - -\section{Naming Components of Arrays} -It may be the case that, for the code you are writing, you wish to -name all the components of an array in a similar way. Rather than -typing out lengthy arrays, {\it SetTensor} provides a bit of shorthand -for you. - -\subsection{AddDeps[Object], DefaultDepString} -This is a very simple function which adds a dependency list to a -string, then turns it into an expression. For example: -\begin{verbatim} -x[1] = x; x[2] = y; x[3] = z; -Dimension = 3; -AddDeps["psi"] -\end{verbatim} -produces -\begin{verbatim} -Out[]= - psi[x,y,z] -\end{verbatim} -The utility of this function will become more apparent when it is -combined with objects to be described in the next sections. - -If you do not want the dependency list generated automatically from -{\tt x[1]}, {\tt x[2]}, and {\tt x[3]}, you can over-ride this by -setting {\tt DefaultDepString}. Continuing the above example we find -that -\begin{verbatim} -DefaultDepString="x,y"; -AddDeps["psi"] -\end{verbatim} -produces -\begin{verbatim} -Out[]= - psi[x,y]; -\end{verbatim}. - -\subsection{AddIndex[Object]} -{\tt AddIndex} adds an index. To create a single vector named ``U'' you -would do the following: -\begin{verbatim} -x[1] = x; x[2] = y; x[3] = z; -Dimension = 3; -AddIndex["U"]; -\end{verbatim} -And this would produce the output -\begin{verbatim} -Out[]= - {"Ux","Uy","Uz"} -\end{verbatim} -If we apply {\tt AddDeps} to this we obtain -\begin{verbatim} -Out[]= - {Ux[x, y, z], Uy[x, y, z], Uz[x, y, z]} -\end{verbatim} -There is an optional argument to AddIndex, and its value can be -either {\tt Prepend} or {\tt Append}. The latter is its default -value. However, using the former value we obtain: -\begin{verbatim} -In[]= - AddDeps[AddIndex[Prepend,"U"]] - -Out[]= - {xU[x, y, z], yU[x, y, z], zU[x, y, z]} -\end{verbatim} - -You can also apply {\tt AddIndex} to itself. -\begin{verbatim} -In[]= - AddDeps[AddIndex[AddIndex["U"]]] - -Out[]= -{{Uxx[x, y, z], Uxy[x, y, z], Uxz[x, y, z]}, - {Uyx[x, y, z], Uyy[x, y, z], Uyz[x, y, z]}, - {Uzx[x, y, z], Uzy[x, y, z], Uzz[x, y, z]}} -\end{verbatim} - -\subsection{AddSym2[Object], AddAsym2} -The last example above showed how to create a 2 index tensor. What -if we want that tensor to be symmetric? We need not really do anything, -as the symmetries of the tensor cannot be violated by the assignment -process using {\tt SetTensor}. However, we might wind up with -\begin{verbatim} -In[]= - foo[-2,-1] - -Out[]= - fooyx[x, y, z] -\end{verbatim} -when we had wanted -\begin{verbatim} -Out[]= - fooyx[x, y, z] -\end{verbatim} -if we were not careful. -For this purpose, and to provide a shorthand for adding 2 indices at once, we provide -{\it AddSym2}. -\begin{verbatim} -In[]= - AddDeps[AddSym2["U"]] - -Out[]= -{{Uxx[x, y, z], Uxy[x, y, z], Uxz[x, y, z]}, - {Uxy[x, y, z], Uyy[x, y, z], Uyz[x, y, z]}, - {Uxz[x, y, z], Uyz[x, y, z], Uzz[x, y, z]}} -\end{verbatim} -{\it AddSym2} also takes the optional first argument which may be -set to {\tt Prepend} with effects similar to that for {\tt AddIndex}. -{\it AddAsym2} works the same way as {\it AddSym}, but obviously -produces an anti-symmetric rather than a symmetric matrix. -\begin{verbatim} -In[]= - AddDeps[AddAsym2["U"]] - -Out[]= -{{0, Uxy[x, y, z], Uxz[x, y, z]}, - {-Uxy[x, y, z], 0, Uyz[x, y, z]}, - {-Uxz[x, y, z], -Uyz[x, y, z], 0}} -\end{verbatim} -As a last example, let us make a matrix that has three indices, but is -symmetric in the last two indices. The declaration looks like this: -\begin{verbatim} -tmp=AddIndex[AddSym2["U"]] -\end{verbatim} -For this array, {\tt tmp[[1,2,3]] == tmp[[1,3,2]]}. - -\section{Fortran Output} -The package {\it Format}\footnote{For documentation, see -http://www.wri.com/MathSource/.aliases/0205-254/Format.ps} -with its function {\tt FortranAssign} function replaces -the builtin {\it Mathematica} function {\tt FortranForm}. {\it Format} is automatically -loaded by {\it SetTensor}. Note, however, that there is a namespace conflict between -the two packages for the symbol {\tt Lower}. Please ignore the warning message this -generates during loading. - -Several functions have been provided to interface between the package {\it Format} -available from {\it MathSource} and {\it SetTensor}: {\tt DerivRule} provides a -mechanism for making the derivatives of functions format in a reasonable way, and -{\tt fwri} (Fortran write) simply calls {\tt Write[]}, {\tt DerivRule}, -and {\tt FortranAssign} with some specific default options. - -\subsection{DerivRule, MakeDeriv[String,String,String]} -By default, {\tt DerivRule} will convert a derivative to a function. -Here are some examples to show you how it works: -\begin{verbatim} -In[]= - D[foo[n,x],n] /. DerivRule - -Out[]= - dnfoo[n, x] - -In[]= - D[foo[n,x],x] /. DerivRule - -Out[]= - dxfoo[n, x] - -In[]= - D[foo[n,x],x,n] /. DerivRule - -Out[]= - dnxfoo[n, x] - -In[]= - D[foo[n,x],x,x] /. DerivRule - -Out[]= - dxxfoo[n, x] -\end{verbatim} -The format of the derivative function is specified by {\tt MakeDeriv}. -MakeDeriv is called by {\tt DerivRule} with three {\tt String} -arguments. The first specifies the variables we are using to take the -derivatives, i.e. in the above examples we get ``n'', ``x'', ``nx'', -and ``xx'' respectively. The second argument specifies the name of -the function, in the above example that would be ``foo'' in every -case. The last argument is a string which supplies the function's -variable dependence, ``[n,x]'' in every example above. - -The default definition of {\tt MakeDeriv} is, therefore: -\begin{verbatim} -MakeDeriv[wr2_,fun_,args_] := ToExpression["d"<>wr2<>fun<>args] -\end{verbatim} - -You can over-ride this function to obtain the kind of expression you -think is appropriate if the default is unacceptable. - -\subsection{fwri[Outputstream,lhs,rhs]} -To use this function you need an {\tt Outputstream}, i.e. the output -of the Mathematica function {\tt OpenWrite} for the first argument -(for testing purposes you can use the string ``stdout'' to simply -write to the screen). Next you supply the left-hand side and the -right-hand side of the output you wish to produce. For example: -\begin{verbatim} -fwri["stdout",a,b] -\end{verbatim} -produces (because {\tt fwri} calls {\tt FortranAssign}) -\begin{verbatim} - a = b -\end{verbatim} -appropriately spaced for punchcards and thus for modern Fortran -compilers. Note that {\tt fwri} automatically calles {\tt DerivRule}, -and provides a few mappings. The character sequence ``UND'' is mapped -to the underscore character. The default list of arguments is mapped -to the null string, ``''. To understand this, consider for example the -spacetime specified by -\begin{verbatim} -x[1] = x; x[2] = y; x[3] = z; -Dimension = 3; -\end{verbatim} -The default argument list for it is ``(x,y,z)''. - -Now let us look at two slightly longer examples to see how all this -works: -\begin{verbatim} -In[]= - MakeDeriv[x1_,x2_,x3_] := ToExpression[ - x2<>"UND"<>x1<>x3]; - tmp=D[foo[n,x],x,x] /. DerivRule; - fwri["stdout",a,tmp] - -Out[]= - a = foo_xx(n,x) - -In[]= - tmp=D[foo[x,y,z],x,x] /. DerivRule; - fwri["stdout",a,tmp] - -Out[]= - a = foo_xx -\end{verbatim} -In the second example we see that the argument list is suppressed. -This is because it is the default list ``(x,y,z)'' given above. - -If you call {\tt fwri} with the {\it lhs} value set to -the symbol {\tt call}, then the assignment symbol ``='' will be suppressed on -output. Since {\tt FortranAssign} converts integers to reals, we provide -the symbol {\tt FortranInt[x1\_Integer]} to allow integers to format literally. -\begin{verbatim} -In[]= - fwri["stdout",call,func[FortranInt[3]] ]; - -Out[]= - call func(3) -\end{verbatim} - -If you are writing F90 code with array notation, this is what you want -to have happen. However, it may be that you are writing F77 code and -want ``(x,y,z)'' to map to ``(i,j,k)'' instead. If this is so, you -can do the following: -\begin{verbatim} -In[]= - FortranOutputOfDepList = "(i,j,k)"; - tmp=D[foo[x,y,z],x,x] /. DerivRule; - fwri["stdout",a,tmp] - -Out[]= - a = foo_xx(i,j,k) -\end{verbatim} - -Note that you can supply all the arguments to {\tt FortranAssign} that -you might normally want to, however if you use {\tt AssignReplace} -(the mechanism used to produce the above string mappings) you lose the -string mapping definitions supplied by SetTensor. -\begin{verbatim} -In[]= - FortranOutputOfDepList = "(i,j,k)"; - tmp=D[foo[x,y,z],x,x] /. DerivRule; - fwri["stdout",a,tmp,AssignRelplace->{"x"->"X"}]; - -Out[]= - a = fooUNDXX(X,y,z) -\end{verbatim} -\subsection{AddReplace} -This unfortunate state of affairs can be remedied by using the -argument {\tt AddAssign} as follows: -\begin{verbatim} -In[]= - FortranOutputOfDepList = "(i,j,k)"; - tmp=D[foo[x,y,z],x,x] /. DerivRule; - fwri["stdout",a,tmp,AddRelplace->{"x"->"X"}]; - -Out[]= - a = foo_XX(X,y,z) -\end{verbatim} - -\section{NeedsIt[],ClearNeedsIt[],AddToNeedsIt[]} - -Sometimes you may wish to only write out some components of a tensor. -For example, suppose you want to calculate the Ricci scalar. -\begin{verbatim} -Needs["SetTensor`"]; -Dimension=3; -x[1] = x; x[2] = y; x[3] = z; -DefaultDepString = "x,y"; -gv = { -{AddDeps["f1"],0,0}, -{0,AddDeps["f2"],0}, -{0,0,AddDeps["f3"]}}; -InitializeMetric[gv,Simplify]; - -ClearNeedsIt[]; -fd = OpenWrite["rscal.h"]; -rhs = ScalarRtoAffine[ScalarR]; -rhs = rhs /. AffineG->af -rhs = EvalMT[rhs]; -AddToNeedsIt[rhs]; -fwri[fd,rsc,rhs]; -Close[fd]; -\end{verbatim} -The function {\tt NeedsIt} now knows which derivatives of the Affine -connection you need. You can use this info to calculate only those -components. -\begin{verbatim} -(* derivAf - Derivative of Affine Connection *) -DefineTensor[derivAf,{{1,3,2,4},1}]; - -(* the next two lines make the same affine symbol used above *) -tmp = AddIndex["A"]; -tmp = AddSym2[tmp]; - -(* the next two lines prepend a dx, dy, or dz to the - * affine connection name. - *) -tmp = AddIndex[Prepend,tmp]; -tmp = AddStrs["d",tmp]; - -tmp = AddDeps[tmp]; -(* at this point tmp[[1,1,1,2]] yields dyAxxx[x,y] *) - -rhs = OD[AffineG[ue,lf,lg],lh]; -rhs = AffineToMetric[rhs]; -rhs = Tsimplify[rhs]; - -fd = OpenWrite["dAf.h"]; -Iter[derivAf[ua,lb,lc,ld], - (* NeedsIt only returns True if the derivative - * symbol was found in rhs in the call to - * AddToNeedsIt above. - *) - If[NeedsIt[ tmp[[ua,-lb,-lc,-ld]] ], - fwri[fd,tmp[[ua,-lb,-lc,-ld]], - EvalMT[rhs,{ue->ua,lf->lb,lg->lc,lh->ld}] - ] - ] -] -Close[fd]; -\end{verbatim} -You can now include the files ``dAf.h'' and ``rscal.h'' in in your Fortran code, -first ``dAf.h'' to set the Affine connection derivatives, then ``rscal.h'' which -uses them. - -Note that {\tt AddToNeedsIt} applies {\tt DerivRule} to its -argument and then detects the functions with the default -argument list. In the opinion of {\tt AddToNeedsIt}, you only -``need'' functions that have the default argument list. (In this -example, the default arguments are ``x,y''. This was explicitly set using {\tt -DefaultDepString} above. If it had not been set explicitly, the default -arguments would've been ``x,y,z''.) - -For reference, the file ``dAf.h'' contains the following: -\begin{verbatim} - dxAxzz = 5.d-1*dxf1*dxf3/f1**2 - 5.d-1*dxxf3/f1 - dxAxyy = 5.d-1*dxf1*dxf2/f1**2 - 5.d-1*dxxf2/f1 - dyAxxy = -5.d-1*dyf1**2/f1**2 + 5.d-1*dyyf1/f1 - dyAyzz = 5.d-1*dyf2*dyf3/f2**2 - 5.d-1*dyyf3/f2 - dxAyxy = -5.d-1*dxf2**2/f2**2 + 5.d-1*dxxf2/f2 - dyAyxx = 5.d-1*dyf1*dyf2/f2**2 - 5.d-1*dyyf1/f2 - dyAzyz = -5.d-1*dyf3**2/f3**2 + 5.d-1*dyyf3/f3 - dxAzxz = -5.d-1*dxf3**2/f3**2 + 5.d-1*dxxf3/f3 -\end{verbatim} -and the file ``rscal.h'' contains: -\begin{verbatim} - t1 = -(Axxy*Ayxx/f1) + Axxx*Ayxy/f1 - Ayxy**2/f1 + Ayxx*Ayyy/f1 - & - Axxz*Azxx/f1 + Ayyz*Azxx/f1 - 2.d0*Ayxz*Azxy/f1 + Axxx*Azxz/f1 - & - Azxz**2/f1 + Ayxx*Azyz/f1 + Azxx*Azzz/f1 - dxAyxy/f1 - dxAzxz - & /f1 + dyAyxx/f1 - Axxy**2/f2 + Axxx*Axyy/f2 - Axyy*Ayxy/f2 + Axx - & y*Ayyy/f2 - 2.d0*Axyz*Azxy/f2 + Axyy*Azxz/f2 - t2 = Axxz*Azyy/f2 - Ayyz*Azyy/f2 + Ayyy*Azyz/f2 - Azyz**2/f2 + A - & zyy*Azzz/f2 + dxAxyy/f2 - dyAxxy/f2 - dyAzyz/f2 - Axxz**2/f3 + A - & xxx*Axzz/f3 + Axzz*Ayxy/f3 - 2.d0*Axyz*Ayxz/f3 - Ayyz**2/f3 + Ax - & xy*Ayzz/f3 + Ayyy*Ayzz/f3 - Axzz*Azxz/f3 - Ayzz*Azyz/f3 + Axxz*A - & zzz/f3 + Ayyz*Azzz/f3 + dxAxzz/f3 + dyAyzz/f3 - rsc = t1 + t2 -\end{verbatim} - -\section{Optimization} - -It is always desirable to reduce the number of quantities you need -to calculate, and the number of indices you need to contract. Some -of this has been taken account for you, by assuming that you always -want the affine connections. The command -\begin{verbatim} -EvalMT[RicciRVal[li,lj],AffineToMetric[RicciToAffine[RicciR[li,lj]]] ]; -\end{verbatim} -will take much longer to evaluate than -\begin{verbatim} -EvalMT[RicciRVal[li,lj],RicciToAffine[RicciR[li,lj]] ]; -\end{verbatim} -simply because the affine connections have already been calculated -and one level of summation has been removed. If the affine connections -have been simplified, this helps speed things up all the more. - -When calculating the Riemann invariants, for another example, it is much -more efficient to evaluate this -\begin{verbatim} -sym=Symmetries[RiemannR[la,lb,lc,ld]]; -DefineTensor[riem,"r",sym]; -SetTensor[riem[ua,ub,lc,ld],RiemannToAffine[RiemannR[ua,ub,lc,ld]]]; -EvalMT[riem[ua,ub,lc,ld] riem[uc,ud,la,lb]] -\end{verbatim} -than it is to do this -\begin{verbatim} -sym=Symmetries[RiemannR[la,lb,lc,ld]]; -DefineTensor[riem,"r",sym]; -SetTensor[riem[ua,ub,uc,ud],RiemannToAffine[RiemannR[ua,ub,uc,ud]]]; -SetTensor[riem[la,lb,lc,ld],RiemannToAffine[RiemannR[la,lb,lc,ld]]]; -EvalMT[riem[ua,ub,uc,ud] riem[lc,ld,la,lb]] -\end{verbatim} - -It also helps to apply {\tt Simplify} to the components -of {\tt RiemannR}. - -\section{Timings} - -\begin{verbatim} -Needs["SetTensor`"]; -(* the next file defines g00,g11,g22,g33,b3 *) -<<../BasicKerr.m; - -Dimension = 4; -(* q is theta, p is phi *) -x[2] = r; x[3] = q; x[4] = p; x[1] = t; -metdn = { - {g00,0,0,b3}, - {0,g11,0,0}, - {0,0,g22,0}, - {b3,0,0,g33}}; -dtg = g00 g33-b3\^{}2; -metup = { - {g33/dtg,0,0,-b3/dtg}, - {0,1/g11,0,0}, - {0,0,1/g22,0}, - {-b3/dtg,0,0,g00/dtg}}; - -On[EvalMT::PrintIndex]; - -sym=Symmetries[RiemannR[la,lb,lc,ld]; -DefineTensor[riem,"r",sym]; - -Timing[ - InitializeMetric[metdn,metup,Simplify]; - SetTensor[riem[ua,ub,lc,ld], - RiemannToAffine[RiemannR[ua,ub,lc,ld]],Simplify]; - Print["EvalMT..."]; - tmp=EvalMT[riem[ua,ub,lc,ld] riem[uc,ud,la,lb]]; - stmp=Simplify[tmp]; -] -\end{verbatim} -The above calculation took 3341.04 seconds on jean-luc, -an RS6000. Making the substitution $u = a\,\cos\theta$ to -remove the trigonmetric functions reduced the time to -549.81 seconds. By substituting {\tt FactorSquareFree} for -{\tt Simplify} the time was reduced to 285.84 seconds. Setting -the variable $m$ to unity (which merely involves a rescaling of -$r$ and $a$), because it reduces the number of variables the -simplification routines need to deal with, further reduced the -run time of this calculation to 251.05 seconds. - - -\section{Acknowledgements, Etc.} - -Much credit is due to Peter Musgrave (actually, almost everything I say -in the optimization section I learned from him). -I also want to acknowledge -helpful conversations with the people of Wolfram Research. -Unfortunately, this package is still an order of magnitude {\em slower} -than the equivalent packages in {\it grtensor} as composed by Peter. -I cannot imagine how he does it. - -\end{document} |