(*******************************************************************
This file was generated automatically by the Mathematica front end.
It contains Initialization cells from a Notebook file, which
typically will have the same name as this file except ending in
".nb" instead of ".m".
This file is intended to be loaded into the Mathematica kernel using
the package loading commands Get or Needs. Doing so is equivalent
to using the Evaluate Initialization Cells menu command in the front
end.
DO NOT EDIT THIS FILE. This entire file is regenerated
automatically each time the parent Notebook file is saved in the
Mathematica front end. Any changes you make to this file will be
overwritten.
***********************************************************************)
(* :Title: PushThrough *)
(* :Context: Algebra`PushThrough` *)
(* :Author: David J. M. Park Jr. djmp@earthlink.net *)
(* :Summary:
Supplements the Through command so all functions are pushed through,
but constants are not. Allows finer control than Through. *)
(* :Copyright: \[Copyright] 1999, 2000, 2002 by David J. M. Park Jr. *)
(* :Package Version: 2.0 *)
(* :Mathematica Version: 4.0 *)
(* :Keywords: Through, Operators *)
(* :Requirements: None *)
BeginPackage["Algebra`PushThrough`"]
Algebra`PushThrough::usage=
"Adds a command, PushThrough, which supplements the regular Mathematica Through command. It allows much greater control as to what will be pushed through and how it will be pushed through. PushOnto pushes onto specifically named expressions. PushOut will factor arguments out of an expression."
PushDerivative::usage="PushDerivative[f, g,...][expr] will simplify linear derivative expressions such as (a f + b g)'[t] where f and g are function names, which must be supplied as arguments. Partial derivatives on multiple arguments are also handled.";
LinearPushOut::usage="LinearPushOut[f1, f2,...][v1, v2,...][expr] will break out the linear terms of any expressions within expr that have heads matching the patterns fi over variables matching the patterns vj. Example:\n f[a x + b y]//LinearPushOut[f][x,y] \[Rule] a f[x] + b f[y]";
PushOnto::usage=
"PushOnto[argslist, ontolist][expr] is a form of the Through command that pushes arguments only onto forms given in the ontolist.\nPushOnto[ontolist][(head)[args]] pushes args onto forms given in the ontolist"
PushOut::usage="PushOut[args][expr] will factor out the [args] in expr to produce the form (opexpr)[args]. It will work on nested sums, products and powers.";
PushThrough::usage=
"PushThrough[argslist, opts...] is a pure function which applies Through to subexpressions of the form a_. (h_)[args], within a larger expression, where arglist is a list of the arguments to be pushed through. Through is applied repeatedly by an internal rule until a fixed point is reached or until it has been applied depth times. The depth is set by the option PushThroughDepth and has a default of 20. The option, Constants, can be used to specify a list of symbols or expressions which will be taken as constant. Numbers and Mathematica constants such as \[Pi], True, etc. will automatically be treated as constants. The option StopPatterns gives a list of patterns which will not be pushed through. Derivative[__][__] is a pattern which is never pushed through. The option PushThroughRules specifies whether rules should be pushed. The default is False.\nExample:\n(a x - 2 y)[1,2]//PushThrough[{1,2},Constants\[Rule]{a}] \[Implies] a x[1,2]- 2 y[1,2].\nPushThrough[opts...][(head)[args...]] will push through args if head is free of args, a shorthand for common cases."
PushThroughDepth::usage="PushThroughDepth is an option for PushThrough which tells the maximum depth to push through the arguments. The default value is 20.";
PushThroughRules::usage="PushThroughRules is an option for PushThrough which tells whether Rules should be pushed through. The default value is False.";
StopPatterns::usage="StopPatterns is an option for PushThrough which gives a list of patterns that will not be pushed through. The default value is {}. However Derivative[__][__] is never pushed through.";
$NewMessage[Constants,"usage"];
Constants::usage=Constants::usage<>" For the PushThrough routine, Constants specifies a list of symbols which will be treated as constants and not pushed through.";
Begin["`Private`"]
PushDerivative[functions__][expr_]:=
Module[{temp},
temp=expr//.Derivative[args__][a_+b_]\[RuleDelayed]
Derivative[args][a]+Derivative[args][b];
temp=temp//PushThrough[];
temp//.Derivative[args__][
a_?(FreeQ[#,
Alternatives@@{functions}]&) f_?(MemberQ[{functions}, \
#]&)]\[RuleDelayed]Derivative[args][
Evaluate[a f@@Array[Slot,Length[{args}]]]&]
]
LinearPushOut[f__][vars__][expr_]:=
expr//.{(g:Alternatives@@{f})[p1___,a_+b__,p2___]\[RuleDelayed]
g[p1,a,p2]+g[p1,Plus[b],p2],(g:Alternatives@@{f})[p1___,
a_ b:Alternatives@@{vars},p2___]\[RuleDelayed]a g[p1,b,p2]}
PushOnto[argslist_List,ontolist_List][expr_]:=
Module[{onto=Alternatives@@ontolist},
expr/.(h_/;\[Not]FreeQ[h,onto])@@
argslist\[RuleDelayed](h/.a_/;MatchQ[a,onto]\[Rule]a@@argslist)
]
PushOnto[ontolist_List][(head_)[arglist___]]:=
Module[{onto=Alternatives@@ontolist},
head/.a_/;MatchQ[a,onto]\[RuleDelayed]a[arglist]
]
\!\(\(PushOut[args___]\)[expr_] := \[IndentingNewLine]expr //. {a1_. g_[args]\^n1_. /; FreeQ[{a1, g}, \ Alternatives[args]] \[Rule] \((a1\ g\^n1\ )\)[args], \[IndentingNewLine]a1_. \(g_[args]\^n1_. \) h_[args]\^n2_. /; FreeQ[{g, h}, \ Alternatives[args]] \[Rule] a1\ \((g\^n1\ h\^n2)\)[args], \[IndentingNewLine]c_. + a1_. a_[args] + b1_. b_[args] /; FreeQ[{a1, a, b1, b}, \ Alternatives[args]] \[Rule] c + \((a1\ a + b1\ b)\)[args], \[IndentingNewLine]c_. + a1_. a_[args] /; FreeQ[{c, a1, a}, \ Alternatives[args]] \[Rule] \((c + a1\ a)\)[args]}\)
Options[PushThrough]={PushThroughDepth\[Rule]20,StopPatterns\[Rule]{},
PushThroughRules\[Rule]False,Constants\[Rule]{}};
\!\(\*
RowBox[{
RowBox[{
RowBox[{\(PushThrough[{args___}, opts___?OptionQ]\), ":=",
RowBox[{
RowBox[{"Module", "[",
RowBox[{\({depth, rule, stoppatterns, pushrules, constnants, mathconstants}\), ",",
RowBox[{\(depth = \(PushThroughDepth /. \[InvisibleSpace]{opts}\) /. \[InvisibleSpace]Options[PushThrough]\), ";", \(stoppatterns = \(StopPatterns /. \[InvisibleSpace]{opts}\) /. \[InvisibleSpace]Options[PushThrough]\), ";", \(pushrules = \(PushThroughRules /. \[InvisibleSpace]{opts}\) /. \[InvisibleSpace]Options[PushThrough]\), ";", \(constants = \(Constants /. \[InvisibleSpace]{opts}\) /. \[InvisibleSpace]Options[PushThrough]\), ";",
RowBox[{"stoppatterns", "=",
RowBox[{"Join", "[",
RowBox[{"stoppatterns", ",",
RowBox[{"{",
SuperscriptBox["__",
TagBox[\((__)\),
Derivative],
MultilineFunction->None], "}"}]}], "]"}]}], ";", \(mathconstants = Join[Alternatives @@ constants, \[ImaginaryI] | Root[_, __] | C[_] | $Aborted | $Failed | True | False | DirectedInfinity | Indeterminate | Null | \((_ \[Rule] _)\) | \((_ \[RuleDelayed] _)\)]\), ";", \(If[pushrules, mathconstants = Drop[mathconstants, \(-2\)]]\), ";", \(rule := a_. \ \((h_ /; \(! AtomQ[h]\) && \(! Or @@ \(\((MatchQ[h, #1] &)\) /@ stoppatterns\)\))\)[args] \[RuleDelayed] \((\(a\ Through[h[args], Head[h]] /. \[InvisibleSpace]g_[___] /; NumberQ[g] || Head[g] === Symbol && MemberQ[Attributes[g], Constant] \[RuleDelayed] g\) /. \[InvisibleSpace]\((g : mathconstants)\)[___] \[RuleDelayed] g)\)\), ";", \(FixedPoint[#1 /. \[InvisibleSpace]rule &, #1, depth]\)}]}], "]"}], "&"}]}], ";"}], "\n"}]\)
PushThrough[opts___?OptionQ][(head_)[args___]]/;
FreeQ[head, Alternatives[args],\[Infinity]]:=
PushThrough[{args},opts][head[args]]
End[]
Protect[Evaluate[Context[]<>"*"]]
EndPackage[]