# HG changeset patch
# User Eike Welk
# Date 1311418009 7200
# Node ID 9e754ac209f868969117a12a7338bfa8043ef136
# Parent 0b3af5b6f2c45edf15af5c9607f3832da2770762
Expanded README.rst.
diff git a/README.rst b/README.rst
 a/README.rst
+++ b/README.rst
@@ 5,20 +5,20 @@
This project contains a very simple, and incomplete, symbolic math library in
Scala. It can *differentiate* and *evaluate* simple mathematical expressions.
The library also contains some aspects of an internal DSL: The expressions can
be entered like regular math with ``Int`` or ``Double`` objects, and there is
+be entered like regular math with ``Int`` or ``Double`` numbers, and there is
a ML style *"let" expression*. Here is a short example that demonstrates the
differentiation feature::
import symathm.Expression._
import symathm.ExprOps._
 //Create some symbols (unknown variables)
+ //Create some symbols (unknown variables).
val (a, x) = (Sym("a"), Sym("x"))
//Create an expression. `~^` denotes exponentiation (power).
val expr1 = a * x~^4 + 5 * x~^2 + x~^0.5
 //Differentiate the expression with respect to `x`
+ //Differentiate the expression with respect to `x`.
val dexpr1 = diff(expr1, x)
//Print the expression in human readable form.
@@ 26,7 +26,7 @@
pprintln(dexpr1)
The library is not intended to be used seriously. Instead it should demonstrate
features of Scala that are interesting for programmers that come form
+simple features of Scala that are interesting for programmers that come form
traditional object oriented languages; such as: C++, Java, Python, Ruby.
The project should especially demonstrate the usefulness of pattern matching.
Therefore this library is implemented three times with different programming
@@ 38,6 +38,13 @@
Package ``symathoo``: Classical object oriented.
===================== =====================================
+The three libraries are big enough (500 to 700 lines) to give an impression
+how working with a real program would be. But they are small and simple
+enough, to be easily understood. To write the algorithms, and to judge their
+correctness, only high school math is necessary. In principle the algorithms
+can be looked up in Wikipedia
+(http://en.wikipedia.org/wiki/Table_of_derivatives).
+
Repository Contents
===================
@@ 153,18 +160,86 @@
* Add derivation of the ``Log`` node.
* Add new nodes, for example ``sin``, ``cos`` and ``tan``.
+
* Add function call node. Maybe this makes an inert ``diff`` node superfluous.
(See point below.)
+
* Add ``lambda`` (function body) node.
* Implement an inert ``diff`` node. The "a$x" notation is a hack.
+* Implement a node for a ``for`` loop. Write evaluation and differentiation
+ algorithms for it. (I believe differentiating a ``for`` loop is possible,
+ because older versions of *Maple* could do it.)
+
* Implement an algorithm to distribute factors over sums, and distribute
powers over products. For example: ``(a + b) * c`` > ``a*c + b*c``.

This is interesting for ``eval``: more operators with only numeric arguments
can be found, and evaluated.
* Implement an algorithm to collect factors and powers. (The opposite of the
algorithm above.) It makes formulas look good.
+
* Maybe add a separate ``simplify`` function.
* Implement some of the TODOs in the code.
+
+
+Architecture
+============
+
+Data Format
+
+
+Mathematical formulas are internally represented as nested trees of nodes.
+They are implemented as *case classes*, syntactical sugar for simple classes
+that are intended to work with the ``match`` statement.
+(http://www.artima.com/pins1ed/caseclassesandpatternmatching.html)
+
+* ``Num(num: Double)`` : A number (floating point)
+* ``Sym(name: String)`` : A variable (symbol)
+* ``Add(summands: List[Expr])`` : Addition (nary)
+* ``Mul(factors: List[Expr])`` : Multiplication (nary)
+* ``Pow(base: Expr, exponent: Expr)``: Exponentiation
+* ``Log(base: Expr, power: Expr)`` : Logarithm
+* ``Let(name: String, value: Expr, exprNext: Expr)``: Bind a value to a
+ variable, and put a single expression into the environment, where the new
+ variables are visible.
+
+There are no nodes for subtraction and division. Subtraction is represented
+as multiplication with ``1`` (``a = 1 * a``), division is expressed as a
+power of ``1`` (``1/a = a~^(1)``). Addition and multiplication are also
+*nary*, they take an arbitrary number of arguments.
+
+This idea was taken from the computer algebra program *Maxima*, it is intended
+to reduce the complexity of the algorithms.
+
+``1 + a`` is expressed as::
+
+ Add(List(Num(1.0), Sym("a")))
+
+``1 + a * 2`` is expressed as::
+
+ Add(List(Num(1.0), Mul(List(Sym("a"), Num(2.0)))))
+
+Addition and multiplication are nary, they can have an arbitrary number of
+arguments. ``1 + a + 2 + 3`` and ``1 * a * 2 * 3`` are respectively
+expressed as::
+
+ Add(List(Num(1.0), Sym("a"), Num(2.0), Num(3.0)))
+ Mul(List(Num(1.0), Sym("a"), Num(2.0), Num(3.0)))
+
+As there are no subtraction or division operators, ``ax`` and ``a/x`` are
+respectively expressed as::
+
+ Add(List(Sym("a"), Mul(List(Num(1.0), Sym("x")))))
+ Mul(List(Sym("a"), Pow(Sym("x"), Num(1.0))))
+
+The ``let`` expression is created by a little abuse of Scala's liberal syntax
+(the DSL). ``let (a:=2) in a * a`` results in::
+
+ Let("a", Num(2.0), Mul(List(Sym("a"), Sym("a"))))
+
+Algorithms
+
+
+Algorithms traverse a tree of nodes in a recursive way, and create a
+new tree as the result.
diff git a/src/symathm/SymbolicMainM.scala b/src/symathm/SymbolicMainM.scala
 a/src/symathm/SymbolicMainM.scala
+++ b/src/symathm/SymbolicMainM.scala
@@ 459,9 +459,10 @@
expo * simplifyPow(base ~^ (expo1))
//General case (from Maple):
// diff(u(x)~^v(x), x) =
 // u(x)~^v(x) * (diff(v(x),x)*ln(u(x))+v(x)*diff(u(x),x)/u(x))
+ // u(x)~^v(x) * (diff(v(x),x)*ln(u(x)) + diff(u(x),x)*v(x)/u(x))
case Pow(u, v) =>
 eval((u~^v) * (diff(v, x, env)*Log(E, u) + v*diff(u, x)/u), Environment()) //eval to simplify
+ eval((u~^v) * (diff(v, x, env)*Log(E, u) + diff(u, x, env)*v/u),
+ Environment()) //eval for simplification
//TODO: Differentiate logarithms
//Differentiate `let name = value in nextExpr`.
case Let(name, value, nextExpr) => {