Skip to main content

interactive - Get a "step-by-step" evaluation in Mathematica


Is it possible in Mathematica to get a step-by-step evaluation of some functions; that's to say, outputting not only the result but all the stages that have led to it? If so, how does one do it?


Example : Let's say I want to know the steps to get the derivative of $\cos x\times\exp x$; it should first tell me that it's equal to $\frac{d}{dx}(\exp x)\times\cos x+\exp x \times \frac{d}{dx}(\cos x)$ and then render the result to say $\exp{x}\times(\cos x-\sin x)$.



Answer




For differentiation at least, old versions of Mathematica had a demonstration function called WalkD[] that holds your hand and shows what is done at each stage up until the final answer.


In general, however...



You should realize at the outset that while knowing about the internals of Mathematica may be of intellectual interest, it is usually much less important in practice than you might at first suppose.


Indeed, one of the main points of Mathematica is that it provides an environment where you can perform mathematical and other operations without having to think in detail about how these operations are actually carried out inside your computer.


...


Particularly in more advanced applications of Mathematica, it may sometimes seem worthwhile to try to analyze internal algorithms in order to predict which way of doing a given computation will be the most efficient. And there are indeed occasionally major improvements that you will be able to make in specific computations as a result of such analyses.


But most often the analyses will not be worthwhile. For the internals of Mathematica are quite complicated, and even given a basic description of the algorithm used for a particular purpose, it is usually extremely difficult to reach a reliable conclusion about how the detailed implementation of this algorithm will actually behave in particular circumstances.


A typical problem is that Mathematica has many internal optimizations, and the efficiency of a computation can be greatly affected by whether the details of the computation do or do not allow a given internal optimization to be used.




Put another way: how Mathematica does things doesn't necessarily correspond to "manual" methods.




Here's my modest attempt to (somewhat) modernize WalkD[]:


Format[d[f_, x_], TraditionalForm] := DisplayForm[RowBox[{FractionBox["\[DifferentialD]",
RowBox[{"\[DifferentialD]", x}]], f}]];

SpecificRules = {d[(f_)[u___, x_, v___], x_] /;
FreeQ[{u}, x] && FreeQ[{v}, x] :> D[f[u, x, v], x],
d[(a_)^(x_), x_] :> D[a^x, x] /; FreeQ[a, x]};


ConstantRule = d[c_, x_] :> 0 /; FreeQ[c, x];

LinearityRule = {d[f_ + g_, x_] :> d[f, x] + d[g, x],
d[c_ f_, x_] :> c d[f, x] /; FreeQ[c, x]};

PowerRule = {d[x_, x_] :> 1, d[(x_)^(a_), x_] :> a*x^(a - 1) /; FreeQ[a, x]};

ProductRule = d[f_ g_, x_] :> d[f, x] g + f d[g, x];

QuotientRule = d[(f_)/(g_), x_] :> (d[f, x]*g - f*d[g, x])/g^2;


InverseFunctionRule = d[InverseFunction[f_][x_], x_] :>
1/f'[InverseFunction[f][x]];

ChainRule = {d[(f_)^(a_), x_] :> a*f^(a - 1)*d[f, x] /; FreeQ[a, x],
d[(a_)^(f_), x_] :> Log[a]*a^f*d[f, x] /; FreeQ[a, x],
d[(f_)[g__], x_] /; ! FreeQ[{g}, x] :>
(Derivative[##][f][g] & @@@ IdentityMatrix[Length[{g}]]).(d[#, x] & /@ {g}),
d[(f_)^(g_), x_] :> f^g*d[g*Log[f], x]};


$RuleNames = {"Specific Rules", "Constant Rule", "Linearity Rule", "Power Rule",
"Product Rule", "Quotient Rule", "Inverse Function Rule", "Chain Rule"};

displayStart[expr_] := CellPrint[
Cell[BoxData[MakeBoxes[HoldForm[expr], TraditionalForm]], "Output",
Evaluatable -> False, CellMargins -> {{Inherited, Inherited}, {10, 10}},
CellFrame -> False, CellEditDuplicate -> False]]

displayDerivative[expr_, k_Integer] := CellPrint[
Cell[BoxData[TooltipBox[RowBox[{InterpretationBox["=", Sequence[]], " ",

MakeBoxes[HoldForm[expr], TraditionalForm]}], $RuleNames[[k]],
LabelStyle -> "TextStyling"]], "Output", Evaluatable -> False,
CellMargins -> {{Inherited, Inherited}, {10, 10}},
CellFrame -> False, CellEditDuplicate -> False]]

WalkD[f_, x_] := Module[{derivative, oldderivative, k},
derivative = d[f, x]; displayStart[derivative];
While[! FreeQ[derivative, d],
oldderivative = derivative; k = 0;
While[oldderivative == derivative,

k++;
derivative = derivative /.
ToExpression[StringReplace[$RuleNames[[k]], " " -> ""]]];
displayDerivative[derivative, k]];
D[f, x]]

I've tried to make the formatting of the derivative look a bit more traditional, as well as having the differentiation rule used be a tooltip instead of an explicitly generated cell (thus combining the best features of WalkD[] and RunD[]); you'll only see the name of the differentiation rule used if you mouseover the corresponding expression.


WalkD[] demonstration


Comments

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...