(* File PDE3HOPE.M: all pieces for 3D continuous homotopy operator in a file!*) (* WH 10/16/2003 at home in Boulder, at 19:20 *) (* Based on code of 10/01/2003 *) (* ************************* BEGIN of all ***************************** *) (* *************** BEGIN loadMultiDHomotopyFunctions.m ********** *) (* Time-stamp: *) (************************************************************************) (* loadMultiDHomotopyOperator *) (* Purpose: Loads all necessary functions for the multidimensional *) (* homotopy operator *) (* Authors: Ingo Kabirschke, Frances Martin *) (* Input: None *) (* Output: None *) (* Created: June 3, 2003 @ CSM *) (* Last Modified: June 5 @ 2:29 PM @ CSM *) (************************************************************************) (* (* Load functions *) << orderMultiD.m; << partialDArray.m; << zerothEulerMultiD.m; << eulerMultiD.m; << eulerArray.m; << interiorProductMD.m; << lambdaReplaceMD.m; < *) (************************************************************************) (* orderMultiD[expression, dependVarHead, *) (* independVarList_List, independVar] *) (* Purpose: To find the maximum number of derivatives of dependVarHead *) (* with respect to independVar *) (* Authors: Ryan Sayers, Ingo Kabirschke, Kara Namanny *) (* Input: An expression: expression, *) (* a dependent variable head: dependVarHead, *) (* (Example: for u[1], u[2], u[3], the head would be u) *) (* a list of indpendent variables: independVarList, *) (* the independent variable: independVar *) (* Output: The maximum derivative of dependVarHead with respect to *) (* independVar *) (* Created: June 02, 2003, *) (* Last Modified: June 06, 2003 at 2:39 PM at CSM *) (************************************************************************) (* Debug Flags for orderMultiD*) debugOrderMDInput = False; debugDerivCases = False; debugDerivList = False; debugOrderMDResult = False; orderMultiD[expression_, dependVarHead_, independVarList_List, independVar_] := Module[ {i, derivCasesList, derivRule, derivList, orderMDresult, xIndex}, (* Debug input to orderMultiD *) If[debugOrderMDInput, Print["Input to orderMultiD is "]; Print[expression]; ]; (* Checks that the independent variable given is in the *) (* independent variable list, if not it returns False *) (* If the variable is in the list, the xIndex is set to *) (* the position of the variable in the list *) If[Position[independVarList, independVar] =!= {}, xIndex = Position[independVarList, independVar][[1, 1]], (* Else *) Print["The independent variable ", independVar, " given to orderMultiD is not in the variable list: "]; Print[independVarList]; Return[False]; ]; (* Extract the cases of dependVar and its derivatives *) (* in the expression, and put them in a list *) derivCasesList = Union[ Cases[expression, Derivative[listOfDerivs_List, 0][dependVarHead[i_]] [independVarList, t], {0, Infinity} ], Cases[expression, dependVarHead[i_][independVarList, t], {0, Infinity} ] ]; (* Debug list of cases of dependVar and its derivatives *) If[debugDerivCases, Print["derivCasesList is "]; Print[derivCasesList] ]; (* Turn off the error message encountered since listOfDerivs *) (* hasn't been defined *) Off[Part::partd]; (* Define replacement rule: *) (* Replace derivatives with their order with respect to the given *) (* independent variable; *) (* Replace dependent variable with 0 if it has no derivatives *) derivRule = {Derivative[listOfDerivs_List, 0][dependVarHead[i_]] [independVarList, t] -> listOfDerivs[[xIndex]], dependVarHead[i_][independVarList, t] -> 0}; (* Turn error message back on *) On[Part::partd]; (* Apply replacement rule *) (* Create list of derivative orders *) derivList = derivCasesList /. derivRule; (* Debug list of derivatives *) If[debugDerivList, Print["The list of derivative orders for the ", independVar, " variable is "]; Print[derivList]; ]; (* Find maximum derivative order *) orderMDresult = Max[derivList]; (* Debug result of orderMultiD *) If[debugOrderMDResult, Print["The maximum order with respect to ", xIndex, " is "]; Print[orderMDresult]; ]; (* Return the order of the expression with respect to the given *) (* independent variable *) Return[orderMDresult]; ]; (* Print["orderMultiD loaded successfully."]; *) (* *************** END orderMultiD.m ********** *) (* *************** BEGIN partialDArray.m ********** *) (* Time-stamp: *) (************************************************************************) (* partialDArray[expression, dependVar, *) (* independVarList_List, expressionOrderList_List] *) (* Purpose: To produce an array of partial derivatives of expression *) (* with respect to derivatives of dependVar with respect to *) (* independVarList variables *) (* Authors: Ryan Sayers, Frances Martin and Adam Ringler *) (* Input: An expression: expression, *) (* a dependent variable: dependVar, *) (* a list of independent variables: independVarList_List, *) (* upper bounds for the array: expressionOrderList_List *) (* Output: A multi-dimensional array of partial derivatives *) (* ranging from 0 to expressionOrderList *) (* Created: June 03, 2003, at CSM *) (* Last Modified: June 6, 2003 at 2:16 PM at CSM *) (************************************************************************) (* Debug Flags for the partialDArray *) debugPartialDInput = False; debugPartialDResult = False; partialDArray[expression_, dependVar_, independVarList_List, expressionOrderList_List] := Module[ {zeroList, partialDResultArray}, (* Debug input to partialDArray *) If[debugPartialDInput, Print["Calculating an array of partial derivatives of the", " expression: "]; Print[expression]; Print["The dependent variable input is ", dependVar]; ]; (* Returns False if the lengths of the input lists are not equal, *) (* because the function needs an order for each independent variable *) If[Length[independVarList] =!= Length[expressionOrderList], Print["In partialDArray: The length of independVarList ", "is not equal to the length of expressionOrderList."]; Print["Aborting calculations."]; Return[False] ]; (* Returns an empty set if exprnOrderList contains negative numbers *) (* because you cannot have a negative order derivative. The expression *) (* order list will only contain a negative value if the original *) (* expression did not contain the dependent variable. Thus, returning *) (* {} gives the correct partial derivative array. *) If[Min[expressionOrderList] < 0, Print["In partialDArray: expressionOrderList contains ", "at least one negative number."]; Return[{}]; ]; (* Creates a list of zeroes of the same length as independVarList, for *) (* use as the lower limits (array origin) of the array of partials *) zeroList = Array[0 &, Length[independVarList]]; (* Creates the array of partial derivatives: *) (* ## will give the internal independent variables *) (* that Array[] iterates over *) (* Sequence@@Transpose[List[...]] puts the derivatives in the form *) (* that D[] needs for its derivative arguments *) (* and expressionOrderList + 1 provides the number of entries in *) (* each dimension *) partialDResultArray = Array[D[expression, D[dependVar[independVarList, t], Sequence@@Transpose[List[independVarList, {##}]]]] &, expressionOrderList + 1, zeroList ]; (* Debug result of partialDArray*) If[debugPartialDResult, Print["The array of partial derivatives for the expression, "]; Print[expression]; Print["is"]; Print[partialDResultArray] ]; (* Return partial derivative array *) Return[Expand[partialDResultArray]]; ]; (* End of partialDArray Module *) (* Print["partialDArray loaded successfully."]; *) (* *************** END partialDArray.m ********** *) (* *************** BEGIN zerothEulerMultiD.m ********** *) (* Time-stamp: *) (************************************************************************) (* zerothEulerMultiD[expression, dependVar, independVarList_List] *) (* Purpose: To find the zeroth-order Euler operator of expression *) (* Authors: Kara Namanny and Ryan Sayers *) (* Input: An expression: expression, *) (* a dependent variable: dependVar, *) (* a list of independent variables: independVarList *) (* Output: The zeroth-order Euler operator of expression with respect *) (* to the dependent variable using independent variables given *) (* in independVarList *) (* Created: June 5, 2003 at CSM *) (* Last Modified: June 6, 2003 at 11:44 AM at CSM *) (************************************************************************) (* Debug Flags *) debugZEulerMDInput = False; debugZEulerMDOrder = False; debugZEulerMDResult = False; zerothEulerMultiD[expression_, dependVar_, independVarList_List] := Module[{zeroList, orderList, partialsArray, zerothEulerMDResult}, (* Debug input *) If[debugZEulerMDInput, Print["The expression input to zerothEulerMultiD is"]; Print[expression]; ]; (* Create an array of zeroes of length equal to that of independVarList *) (* This is used as the order of the expression *) zeroList = Array[0 &, Length[independVarList]]; (* Create a list of the orders of the independent variables in *) (* the expression *) orderList = Table[orderMultiD[expression, Head[dependVar], independVarList, independVarList[[i]] ], {i, 1, Length[independVarList]} ]; (* Debug order list *) If[debugZEulerMDOrder, Print["The order list from zerothEulerMultiD is "]; Print[orderList]; ]; (* Create an array of partial derivatives of the expression *) (* with respect to partials of the dependent variable with *) (* respect to the independent variables *) partialsArray = partialDArray[expression, dependVar, independVarList, orderList]; (* Calculate the zeroth-order Euler operator *) zerothEulerMDResult = Expand[ eulerMultiD[partialsArray, independVarList, orderList, zeroList] ]; (* Debug result *) If[debugZEulerMDResult, Print["The result of applying the zeroth-order Euler operator to "]; Print[expression]; Print["with respect to the dependent variable ", dependVar, " is"]; Print[zerothEulerMDResult]; ]; (* Return result of zeroth order euler operator *) Return[zerothEulerMDResult]; ]; (* Print["zerothEulerMultiD loaded successfully."]; *) (* *************** BEGIN zerothEulerMultiD.m ********** *) (* *************** BEGIN eulerMultiD.m ********** *) (* Time-stamp: *) (************************************************************************) (* eulerMultiD[partialsArray_List, independVarList_List, *) (* exprnOrderList_List, operatorOrderList_List] *) (* Purpose: To compute the higher-order Euler operator of an expression *) (* whose partial derivatives are given *) (* Authors: Ingo Kabirschke, Kara Namanny, Ryan Sayers *) (* Input: An array of partial derivatives of *) (* an expression: partialsArray, *) (* the list of independent variables: independVarList, *) (* the list of the order of the independent variables in the *) (* original expression: exprnOrderList, *) (* the order of the operator in a list: operatorOrderList *) (* Example: for independent variables {x, y, z}, and *) (* the operator E^{xxyyyz}, the operatorOrderList *) (* would be {2, 3, 1} *) (* Output: The operatorOrderList-order Euler operator acting on the *) (* expression with partial derivatives given by partialsArray *) (* Created: June 04, 2003 at CSM *) (* Last Modified: June 6, 2003 at 1:52 AM at CSM *) (************************************************************************) (* Debug Flags for eulerMultiD *) debugEulerMDInput = False; debugEulerMDTerms = False; debugEulerMDOutput = False; eulerMultiD[partialsArray_List, independVarList_List, exprnOrderList_List, operatorOrderList_List] := Module[ {i, sumVarsList, sumVar, eulerMDResult}, (* Debugging input to eulerMultiD *) If[debugEulerMDInput, Print["The partial derivatives given to eulerMultiD are: "]; Print[partialsArray] ]; (* Returns 0 if exprnOrderList contains negative numbers because *) (* you cannot have a negative order derivative. The expression *) (* order list will only contain a negative value if the original *) (* expression was defined as 0 or a constant. Thus, returning 0 *) (* gives the correct Euler operator. *) If[Min[exprnOrderList] < 0, Print["eulerMultiD called with negative order numbers."]; Print["Returning 0."]; Return[0] ]; (* Creates variables to sum over: one for each independent variable *) sumVarsList = Array[sumVar, Length[independVarList]]; (* Using the formula given in Ryan's paper for higher-order *) (* multi-dimensional Euler operators: *) (* We have nested sums from the order of the operator *) (* to the order of the expression; *) (* The sign of the term is computed in terms of the *) (* sum variables and the order of the expression; *) (* The coefficients are computed by multiplying the individual *) (* binomial coefficients (Product[Binomial[...]]) *) (* The total derivatives are taken in terms of the *) (* sum variables and the order of the expression; *) (* The correct partial derivatives are extracted from the *) (* partialsArray by using the (sumVarsList + 1) location - *) (* 1 must be added because the partialsArray starts at 1, *) (* while the operatorOrderList could start at 0. *) eulerMDResult = Expand[ Sum[ (-1)^(Tr[sumVarsList - operatorOrderList]) * Product[ Binomial[sumVarsList[[i]], operatorOrderList[[i]]], {i, 1, Length[independVarList]} ] * D[partialsArray[[Sequence@@Flatten[sumVarsList + 1]]], Sequence@@Transpose[List[independVarList, sumVarsList - operatorOrderList]] ], Evaluate[ Sequence@@Transpose[List[sumVarsList, operatorOrderList, exprnOrderList] ] ] ] ]; (* Debugging Terms produced by applying the Multi-Dimensional *) (* Euler Operator *) If[debugEulerMDTerms, Print["The terms produced by eulerMultiD are: "]; Print[ Table[ (-1)^(Tr[sumVarsList - operatorOrderList]) * Product[ Binomial[sumVarsList[[i]], operatorOrderList[[i]]], {i, 1, Length[independVarList]} ] * D[partialsArray[[Sequence@@Flatten[sumVarsList + 1]]], Sequence@@Transpose[List[independVarList, sumVarsList - operatorOrderList]] ], Evaluate[ Sequence@@Transpose[List[sumVarsList, operatorOrderList, exprnOrderList] ] ] ] ] ]; (* Debugging eulerMultiD Output *) If[debugEulerMDOutput, Print["The result of applying the ", operatorOrderList, " order Euler operator is "]; Print[eulerMDResult] ]; (* Return result of eulerMultiD *) Return[eulerMDResult]; ]; (* End of Module *) (* Print["eulerMultiD loaded successfully."]; *) (* *************** END eulerMultiD.m ********** *) (* *************** BEGIN eulerArray.m ********** *) (* Time-stamp: *) (************************************************************************) (* eulerArray[partialsArray, independVarList_List, *) (* expressionOrderList_List] *) (* Purpose: To produce an array of the results of Euler operators *) (* acting on an expression with partial derivatives given by *) (* partialsArray *) (* Authors: Frances Martin, Adam Ringler, Ryan Sayers *) (* Input: An array of partial derivatives: partialsArray, *) (* a list of independent variables: independVarList_List, *) (* upper bounds for the array: expressionOrderList_List *) (* Output: An array of the results of Euler operators using partial *) (* derivatives given in partialsArray *) (* Created: June 03, 2003 *) (* Last Modified: June 6, 2003 @ 1:17 AM @ CSM *) (************************************************************************) (* Debug Flags for eulerArray *) debugEulerArrayInput = False; debugEulerArrayResult = False; eulerArray[partialsArray_List, independVarList_List, expressionOrderList_List] := Module[ {zeroList, eulerArrayResult}, (* Debug input to eulerArray *) If[debugEulerArrayInput, Print["The array of partial derivatives input to eulerArray is: "]; Print[partialsArray] ]; (* Returns False, aborting calculations, if the lengths of the input *) (* lists are not equal, because need an order for each independent *) (* variable *) If[Length[independVarList] =!= Length[expressionOrderList], Print["In eulerArray: The length of independent variable list ", "is not equal to the length of the expression order list."]; Print["Aborting calculations."]; Return[False] ]; (* Returns an empty set if expressionOrderList contains negative *) (* numbers. The order list will only contain negative values if *) (* the original expression was defined as 0 or a constant. Thus, *) (* returning the empty set gives the correct array of Euler *) (* operators. *) If[Min[expressionOrderList] < 0, Print["In eulerArray: expressionOrderList contains ", "at least one negative number."]; Print["Returning an empty set for the array of Euler operators."]; Return[{}]; ]; (* Create a list of zeros of the same length as independVarList, for *) (* use as the lower limits (index origin) of the array. *) zeroList = Array[0 &, Length[independVarList]]; (* Creates an array of Euler operators using eulerMultiD[...] to *) (* calculate the individual Euler Operators *) (* {##} are the internal array variables *) eulerArrayResult = Array[ eulerMultiD[ partialsArray, independVarList, expressionOrderList, {##}] &, (* Limits of the array in the form: dimensions, index origin *) expressionOrderList + 1, zeroList ]; (* Debug eulerArray result *) If[debugEulerArrayResult, Print["The array of euler operators is: "]; Print[eulerArrayResult] ]; (* Return the array of Euler operators *) Return[eulerArrayResult]; ]; (* Print["eulerArray loaded successfully."]; *) (* *************** END eulerArray.m ********** *) (* *************** BEGIN interiorProductMD.m ********** *) (* Time-stamp: *) (************************************************************************) (* interiorProductMD[eulerInputArray_List, dependVar, *) (* independVarList_List, orderList_List, independVar] *) (* Purpose: To produce the interior product given an Euler operator *) (* array of an expression *) (* Authors: Ryan Sayers and Ingo Kabirschke *) (* Input: An Euler operator array of an expresion: eulerInputArray, *) (* a dependent variable: dependVar, *) (* a list of independent variables: independVarList, *) (* a list of the order of the independent variables in *) (* the original expression: orderList, *) (* the independent variable: independVar *) (* Output: The interior product of the original expression with *) (* respect to the independent variable and dependent variable *) (* Created: June 5, 2003 at CSM *) (* Last Modified: June 06, 2003 at 12:54 PM at CSM *) (************************************************************************) (* Debug Flags *) debugIntProdMDInput = False; debugIntProdMDSumVar = False; debugIntProdMDIndexList = False; debugIntProdMDTerms = False; debugIntProdMDResult = False; interiorProductMD[eulerInputArray_List, dependVar_, independVarList_List, orderList_List, independVar_] := Module[ {independVarPosition, indVarIndexList, zeroList, sumVarList, sumVar, intProdMDResult}, (* Debug interiorProductMD input *) If[debugIntProdMDInput, Print["The Euler array input to interiorProductMD is "]; Print[eulerInputArray]; Print["Calculating the Interior Product with respect to the", " dependent variable, ", dependVar, ", and the independent", " variable, ", independVar, "."]; ]; (* Return 0 if orderList contains a negative number, because you *) (* cannot have a negative order derivative. There will only be a *) (* negative value in orderList if the original expression was 0 or a *) (* constant. Thus, returning 0 gives the correct interior product. *) If[Min[orderList] < 0, Print["In interiorProductMD: orderList contains a negative number."]; Print["Returning zero."]; Return[0] ]; (* Find the position of independVar in independVarList *) independVarPosition = Position[independVarList, independVar][[1, 1]]; (* Create a list of all zeroes except at independVarPosition *) indVarIndexList = independVarList /. independVar -> 1 /. Thread[independVarList -> 0]; (* Debug index list *) If[debugIntProdMDIndexList, Print["For independent variable list "]; Print[independVarList]; Print["And independent variable ", independVar, ", indVarIndexList is"]; Print[indVarIndexList]; ]; (* Create a list of zeroes of the same length as independVarList. *) (* The zeroes are used as the lower limits of the summing variables. *) zeroList = Array[0 &, Length[independVarList]]; (* Create variables to sum over - one for each independent variable. *) sumVarList = Array[sumVar, Length[independVarList]]; (* Debug list of summing variables *) If[debugIntProdMDSumVar, Print["The summing variable list is ", sumVarList] ]; (* Using Eq. 43 from Ryan's paper, we sum over the independent *) (* variables from 0 to the order, except for the independent *) (* variable which goes from 0 to the order - 1 and is identified *) (* by its position in the list of independent variables. *) (* We calculate the fraction, (i_k + 1)/(#I + 1), in terms *) (* of the summing variables. *) intProdMDResult = Expand[ Sum[ ((sumVarList[[independVarPosition]] + 1) / (Tr[sumVarList] + 1)) * D[ dependVar[independVarList, t] * eulerInputArray[[Sequence@@(sumVarList + 1 + indVarIndexList)]], Sequence@@Transpose[List[independVarList, sumVarList]] ], (* The following lines create the list of limits for the *) (* summing variables *) Evaluate[ Sequence@@Transpose[List[ sumVarList, zeroList, orderList - indVarIndexList ] ] ] ] ]; (* Debug the terms in the sum *) If[debugIntProdMDTerms, Print["The terms in interiorProductMD are "]; Print[ Table[ ((sumVarList[[independVarPosition]] + 1) / (Tr[sumVarList] + 1)) * D[ dependVar * eulerInputArray[[Sequence@@(sumVarList + 1 + indVarIndexList)]], Sequence@@Transpose[List[independVarList, sumVarList]] ], Evaluate[ Sequence@@Transpose[List[ sumVarList, zeroList, orderList - indVarIndexList ] ] ] ] ] ]; (* Debug result of Interior Product in Multiple Dimensions *) If[debugIntProdMDResult, Print["The result of applying interiorProductMD using the Euler array "]; Print[eulerInputArray]; Print[" with respect to independent variable ", independVar]; Print[" from independent variable list "]; Print[independVarList]; Print[" using dependent variable ", dependVar, " is "]; Print[intProdMDResult]; ]; (* Return interior product *) Return[intProdMDResult]; ];(* End module *) (* Print["interiorProductMD loaded successfully."]; *) (* *************** END interiorProductMD.m ********** *) (* *************** BEGIN lambdaReplaceMD.m ********** *) (* Time-stamp: *) (************************************************************************) (* lambdaReplaceMD[expression_, dependVarHead_, independVarList_] *) (* Purpose: To replace the dependent variable with lambda * dependVar *) (* Authors: Kara Namanny and Ingo Kabirschke *) (* Input: An expression: expression, *) (* a dependent variable head: dependVarHead, *) (* (For example, for u[1], u[2], and u[3] the head would be u) *) (* and an independent variable list: independVarList *) (* Output: The expression with the dependent variable replaced *) (* by lambda * dependent variable *) (* Created: June 5, 2003 @ 11:41 AM @ CSM *) (* Last Modified: June 6, 2003 @ 11:51 AM @ CSM *) (************************************************************************) (* Debug Flags for lambdaReplaceMD *) debugLambdaReplaceMDInput = False; debugLambdaReplaceMDResult = False; lambdaReplaceMD[expression_, dependVarHead_, independVarList_List] := Module[{i, j, lambdaReplaceMDRule, lambdaReplaceMDResult}, (* Debugging Lambda Replacement input *) If[debugLambdaReplaceMDInput, Print["Replacing the dependent variables, ", dependVarHead, "[i], in the expression, "]; Print[expression]; Print[", with lambda * ", dependVarHead, "[i]"]; ]; (* Defining replacement rules: multiplies every occurance of the *) (* dependent variable and its derivatives by lambda *) lambdaReplaceMDRule = { dependVarHead[i_][independVarList, t] -> lambda * dependVarHead[i][independVarList, t], Derivative[i_, j_][dependVarHead[k_]][independVarList, t] -> lambda * Derivative[i, j][dependVarHead[k]][independVarList, t]}; (* Apply replacement rule to expression *) lambdaReplaceMDResult = Expand[expression /. lambdaReplaceMDRule]; (* Debugging result of Lambda Replacement *) If[debugLambdaReplaceMDResult, Print["The result of replacement is: "]; Print[lambdaReplaceMDResult]; ]; (* Return expression with lambda replacement *) Return[lambdaReplaceMDResult]; ]; (* Print["lambdaReplaceMD loaded successfully."]; *) (* *************** END lambdaReplaceMD.m ********** *) (* *************** BEGIN homotopyOperatorMD.m ********** *) (* Time-stamp: *) (************************************************************************) (* homotopyOperatorMD[expression_, dependVarHead_, numDependVar_ , *) (* independVarList_List] *) (* Purpose: To calculate the Total Homotopoy Operator of an expression *) (* in n dimensions *) (* Authors: Ingo Kabirschke, Frances Martin, Kara Namanny, Adam Ringler *) (* Ryan Sayers *) (* Input: An expression: expression, *) (* a dependent variable head: dependVarHead, *) (* (For example, for u[1], u[2], and u[3] the head would be u) *) (* the number of elements (dependent variables) in the vector: *) (* numDependVar, *) (* an independent variable list: independVarList *) (* Output: A list of the results of applying the homotopy operator to *) (* the expression with respect to each independent variable *) (* Created: June 5, 2003 at CSM *) (* Last Modified: June 6, 2003, at 12:10 PM at CSM *) (************************************************************************) (* Debug Flags for homotopyOperatorMD *) debugHomotopyOpInput = True; debugHomotopyOpResult = True; homotopyOperatorMD[expression_, dependVarHead_, numDependVar_, independVarList_List] := Module[ {i, k, orderList, partialsArrayTable, eulerArrayTable, fullMDIntProductTable, lambdaExpressionMDTable, integrandMDTable, homotopyOpResultMDTable}, (* Debug input to the Homotopy Operator *) If[debugHomotopyOpInput, Print["Applying the Total Homotopy Operator to "]; Print[expression]; Print["with independent variable list, ", independVarList]; ]; (* Check if the expression is integrable (Zeroth Euler Operator = 0) *) (* eg. If the expression is closed *) For[i = 1, i <= numDependVar, i++, If[zerothEulerMultiD[expression, dependVarHead[i], independVarList] != 0, (* Then (if not integrable) *) Print["The expression input, "]; Print[expression]; Print[" is not integrable."]; Print["Aborting calculations."]; Return[False]; ]; ]; (* Create a list of the order of the independent variables in the *) (* expression. Example: for u_xxxy + u_zz, the orderList would be *) (* {3, 1, 2} *) orderList = Table[orderMultiD[expression, dependVarHead, independVarList, independVarList[[i]]], {i, 1, Length[independVarList]} ]; (*******************************************************************) (* *) (* Steps below taken from Ryan Sayers' Paper, "The Total Homotopy *) (* Method of Integration," draft 5/21/03 *) (* *) (*******************************************************************) (* Create a table of partial derivative arrays. This allows for *) (* one-time calculation of the partial derivatives, which will be *) (* used in the calculation of each of the Euler operators. *) partialsArrayTable = Table[partialDArray[expression, dependVarHead[i], independVarList, orderList], {i, 1, numDependVar} ]; (* Create a table of Euler Operators arrays, allowing for one-time *) (* calculation of the Euler Operators, which will be used in the *) (* calculation of each of the interior products. *) eulerArrayTable = Table[eulerArray[partialsArrayTable[[i]], independVarList, orderList], {i, 1, numDependVar} ]; (* Calculate the interior product (called the integrand in Ryan's *) (* paper) of the given expression for each independent variable, *) (* summing over all of the dependent variables. *) fullMDIntProductTable = Table[Sum[ interiorProductMD[eulerArrayTable[[i]], dependVarHead[i], independVarList, orderList, independVarList[[k]]], {i, 1, numDependVar} ], {k, 1, Length[independVarList]} ]; (* Replace the dependent variable with lambda * dependent variable for *) (* each expression in the table of interior products. *) lambdaExpressionMDTable = lambdaReplaceMD[fullMDIntProductTable, dependVarHead, independVarList]; (* Divide each expression in the table by lambda *) integrandMDTable = Expand[lambdaExpressionMDTable / lambda]; (* Integrate each expression in the table with respect to lambda to *) (* find the flux (the anti-divergence). This is given in tabular form *) (* sorted by independent variable. *) homotopyOpResultMDTable = Expand[Integrate[integrandMDTable, {lambda, 0, 1}]]; (* Debug the result of homotopyOperatorMD *) If[debugHomotopyOpResult, Print["The result of applying the Total Homotopy Operator is "]; Print[homotopyOpResultMDTable]; ]; (* Return the final result of applying the PDE Homotopy Operator *) Return[homotopyOpResultMDTable]; ]; (* End of Module *) (* Print["homotopyOperatorMD loaded successfully."]; *) Print["Multi-Dimensional Continuous Homotopy Operator loaded successfully."]; (* *************** END homotopyOperatorMD.m ********** *) (* ********************************** end of all ************************ *)