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?

----------------------------------------------------------------------------------

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

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

SpecificRules = {d[x_, x_] :> 1, d[(f_)[x_], x_] :> D[f[x], 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/Derivative[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_] :> (D[f[x], x] /. x -> g)*d[g, x],
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.




I have improved J. M.'s version of walkD by adding error handling. I have also added walkInt that works like walkD except for integration. Code:

Format[d[f_, x_], TraditionalForm] := Module[{paren, boxes},
paren = MatchQ[f,Plus[_,__]];
boxes = RowBox[{f}];If[paren,
boxes = RowBox[{"(", boxes, ")"}]];
boxes = RowBox[{FractionBox["\[DifferentialD]", RowBox[{"\[DifferentialD]", x}]], boxes}];DisplayForm[boxes]]; dSpecificRules = {d[x_, x_] :> 1, d[(f_)[x_], x_] :> D[f[x], x],
d[(a_)^(x_), x_] :> D[a^x, x] /; FreeQ[a, x]}; dConstantRule = d[c_, x_] :> 0 /; FreeQ[c, x]; dLinearityRule = {d[f_ + g_, x_] :> d[f, x] + d[g, x],
d[c_ f_, x_] :> c d[f, x] /; FreeQ[c, x]}; dPowerRule = {d[x_, x_] :> 1, d[(x_)^(a_), x_] :> a*x^(a - 1) /; FreeQ[a, x]}; dProductRule = d[f_ g_, x_] :> d[f, x] g + f d[g, x]; dQuotientRule = d[(f_)/(g_), x_] :> (d[f, x]*g - f*d[g, x])/g^2; dInverseFunctionRule := d[InverseFunction[f_][x_], x_] :>1/Derivative[1][f][InverseFunction[f][x]]; dChainRule = {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_] :> (D[f[x], x] /. x -> g)*d[g, x],
d[(f_)^(g_), x_] :> f^g*d[g*Log[f], x]}; $dRuleNames = {"Specific Rules", "Constant Rule", "Linearity Rule", "Power Rule","Quotient Rule", "Product 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]}], "Differentation: " <> $dRuleNames[[k]],LabelStyle -> "TextStyling"]], "Output", Evaluatable -> False,CellMargins -> {{Inherited, Inherited}, {10, 10}},CellFrame -> False, CellEditDuplicate -> False]];walkD::differentationError = "Failed to differentiate expression!"; 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++;If[k > Length@$dRuleNames,Message[walkD::differentationError];Return[D[f, x]];];
derivative = derivative /. ToExpression["d" <> StringReplace[$dRuleNames[[k]], " " -> ""]]];
displayDerivative[derivative, k]];D[f, x]];Format[int[f_,x_],TraditionalForm]:= (
paren = MatchQ[f,Plus[_,__]];
boxes = RowBox[{f}];If[paren,
boxes = RowBox[{"(", boxes, ")"}]];
boxes = RowBox[{boxes, "\[DifferentialD]", x}];
boxes = RowBox[{"\[Integral]", boxes}];DisplayForm[boxes]); intSpecificRules = {int[(f_)[x_], x_] :> Integrate[f[x], x],
int[(a_)^(x_), x_] :> Integrate[a^x, x] /; FreeQ[a, x]}; intConstantRule = int[c_, x_] :> c*x /; FreeQ[c, x]; intLinearityRule = {int[f_ + g_, x_] :> int[f, x] + int[g, x],
int[c_ f_, x_] :> c int[f, x] /; FreeQ[c, x]}; intPowerRule = {int[x_, x_] :> x^2 / 2, int[1/x_, x_] :> Log[x], int[(x_)^(a_), x_] :> x^(a + 1)/(a + 1) /; FreeQ[a, x]}; intSubstitutionRule = {
int[(f_)^(a_), x_] :> ((Integrate[u^a, u] / d[f, x]) /. u -> f) /; FreeQ[a, x] && FreeQ[D[f, x], x],
int[(f_)^(a_) g_, x_] :> ((Integrate[u^a, u] / d[f, x]) * g /. u -> f) /; FreeQ[a, x] && FreeQ[FullSimplify[D[f, x] / g], x],
int[(a_)^(f_), x_] :> (a ^ f)/(d[f, x] * Log[a]) /; FreeQ[a, x] && FreeQ[D[f, x], x],
int[(a_)^(f_) g_, x_] :> (a ^ f)/(d[f, x] * Log[a]) * g /; FreeQ[a, x] && FreeQ[FullSimplify[D[f, x] / g], x],
int[(f_)[g_], x_] :> (Integrate[f[u], u] /. u -> g) / d[g, x] /; FreeQ[D[g, x], x],
int[(f_)[g_] h_, x_] :> (Integrate[f[u], u] /. u -> g) / d[g, x] * h /; FreeQ[FullSimplify[D[g, x] / h], x]}; intProductRule = int[f_ g_, x_] :> int[f, x] g - int[int[f, x] * d[g, x], x]; $intRuleNames = {"Specific Rules", "Constant Rule", "Linearity Rule", "Power Rule", "Substitution Rule", "Product Rule"}; displayIntegral[expr_, k_Integer] := CellPrint[Cell[BoxData[TooltipBox[RowBox[{InterpretationBox["=", Sequence[]], " ",MakeBoxes[HoldForm[expr], TraditionalForm]}], "Integration: " <> $intRuleNames[[k]],LabelStyle -> "TextStyling"]], "Output", Evaluatable -> False,CellMargins -> {{Inherited, Inherited}, {10, 10}},CellFrame -> False, CellEditDuplicate -> False]];walkInt::integrationError = "Failed to integrate expression!";walkInt::differentationError = "Failed to differentiate expression!"; walkInt[f_, x_] := Module[{integral, oldintegral, k, leafcounts, ruleused},
integral = int[f, x]; displayStart[integral];
leafcounts = {};
ruleused = "";While[! FreeQ[integral, int],If[ruleused == "Product Rule",AppendTo[leafcounts, LeafCount @ integral];If[Length @ leafcounts >= 5 && OrderedQ @ Take[leafcounts, -5],Message[walkInt::integrationError];Return[Integrate[f, x]];];];
oldintegral = integral; k = 0;While[oldintegral == integral,
k++;If[k > Length@$intRuleNames,Message[walkInt::integrationError];Return[Integrate[f, x]];];
integral = integral /. ToExpression["int" <> StringReplace[$intRuleNames[[k]], " " -> ""]]];
ruleused = $intRuleNames[[k]];
displayIntegral[integral, k];While[! FreeQ[integral, d],
oldintegral = integral; k = 0;While[oldintegral == integral,
k++;If[k > Length@$dRuleNames,Message[walkInt::differentationError];Return[Integrate[f, x]];];
integral = integral /. ToExpression["d" <> StringReplace[$dRuleNames[[k]], " " -> ""]]];
displayDerivative[integral, k]];];Integrate[f, x]];

Sample output:

Get a “step-by-step” evaluation in Mathematica的更多相关文章

  1. Step by step Dynamics CRM 2011升级到Dynamics CRM 2013

    原创地址:http://www.cnblogs.com/jfzhu/p/4018153.html 转载请注明出处 (一)检查Customizations 从2011升级到2013有一些legacy f ...

  2. Step by Step 创建一个新的Dynamics CRM Organization

    原创地址:http://www.cnblogs.com/jfzhu/p/4012833.html 转载请注明出处 前面演示过如何安装Dynamics CRM 2013,参见<Step by st ...

  3. Step by step Install a Local Report Server and Remote Report Server Database

    原创地址:http://www.cnblogs.com/jfzhu/p/4012097.html 转载请注明出处 前面的文章<Step by step SQL Server 2012的安装 &g ...

  4. Step by step Dynamics CRM 2013安装

    原创地址:http://www.cnblogs.com/jfzhu/p/4008391.html 转载请注明出处   SQL Server可以与CRM装在同一台计算机上,也可安装在不同的计算机上.演示 ...

  5. Step by step 活动目录中添加一个子域

    原创地址:http://www.cnblogs.com/jfzhu/p/4006545.html 转载请注明出处 前面介绍过如何创建一个域,下面再介绍一下如何在该父域中添加一个子域. 活动目录中的森林 ...

  6. SQL Server 维护计划实现数据库备份(Step by Step)(转)

    SQL Server 维护计划实现数据库备份(Step by Step) 一.前言 SQL Server 备份和还原全攻略,里面包括了通过SSMS操作还原各种备份文件的图形指导,SQL Server  ...

  7. 转:eclipse以及step into step over step return的区别

    首先来讲一下step into step over step return的区别: step into就是单步执行,遇到子函数就进入并且继续单步执行:(F5) step over是在单步执行时,在函数 ...

  8. [转]Bootstrap 3.0.0 with ASP.NET Web Forms – Step by Step – Without NuGet Package

    本文转自:http://www.mytecbits.com/microsoft/dot-net/bootstrap-3-0-0-with-asp-net-web-forms In my earlier ...

  9. EF框架step by step(7)—Code First DataAnnotations(2)

    上一篇EF框架step by step(7)—Code First DataAnnotations(1)描述了实体内部的采用数据特性描述与表的关系.这一篇将用DataAnnotations描述一下实体 ...

  10. EF框架step by step(6)—处理实体complex属性

    上一篇的中介绍过了对于EF4.1框架中,实体的简单属性的处理 这一篇介绍一下Code First方法中,实体Complex属性的处理.Complex属性是将一个对象做为另一个对象的属性.映射到数据库中 ...

随机推荐

  1. Java将\替换成/

    public static void main(String[] args) { String str="upload\\media\\201904\\i4Qjz8E40xGQovUq-2C ...

  2. 【HNOI2019】部分题简要题解

    题意懒得写了 LOJ Day 1 T1 鱼 个人做法比较猎奇,如果有哪位大佬会证明能分享一下的话感激不尽. 题解:枚举鱼尾和鱼身的交点D,将所有其他点按照到D的距离排序,距离相同的分一组. 感性的理解 ...

  3. Mac 10.12为打开终端增加快捷键(转)

    1.在实用工具中打开Automator.app 2.选择新建,然后选择服务 3.服务收到选择为没有输入 然后在左边侧栏中双击Run AppleScript(有些系统会显示运行 AppleScript) ...

  4. C# 数组基础

    一.数组的基础知识 1.数组有什么用? 如果需要同一个类型的多个对象,就可以使用数组.数组是一种数组结构,它可以包含同一个类型的多个元素. 2.数组的初始化方式 第一种:先声明后赋值 ]; array ...

  5. javac符号名字的管理

    在符号表中,很重要的一项内容就是符号的名字.名字的管理,要解决的主要问题就是名字的变长问题.在javac中,所有的符号名字放到了一个公用字符池中,对于相同的名字只保存一个. 其中涉及到的主要类及关系如 ...

  6. linux mint 18.2 安装wireshark

    Method 1: Via PPA Step 1: Add the official PPA sudo add-apt-repository ppa:wireshark-dev/stable Step ...

  7. Redis之hiredis API (String)

    String // // Created by zhangrongxiang on 2018/3/7 13:48 // File string2 // #include <hiredis/hir ...

  8. 从零开始学JAVA(08)-使用SpringMVC4 Restful 风格引用静态文件 css/js/png

    在写完helloworld后想给网页加点样式(*.css),结果怎么也显示不了,百度了很多种方法后试行尝试,试验成功并记录下来,方便以后查看. 时隔两年,继续学习JAVA,太久没学了,忘记得差不多,还 ...

  9. [转]log4net 发布到生产环境不写日志的解决方法--使用 NLog日志

    本文转自:http://www.cnblogs.com/weiweictgu/p/5848805.html 1.升级到log4net的最新版 PM下执行 Install-Package log4net ...

  10. PHP项目学习2

    通过<PHP项目学习1>基本上可以了解项目的大致结构.内容,现在直接从代码入手,开始coding吧. 现在部署环境中建立一个myonline的文件夹,便于放置我们的项目