Difference between revisions of "Calculate a derivative"

From CodeCodex

(Common Lisp)
(Ruby)
 
Line 2: Line 2:
 
Compute and print a derivative of the symbolic expression a x^2 + b x + c in Mathematica syntax, preferably with simplification.
 
Compute and print a derivative of the symbolic expression a x^2 + b x + c in Mathematica syntax, preferably with simplification.
  
==C++==
+
==Implementations==
 +
 
 +
 
 +
===C++===
  
 
<pre class="c++">
 
<pre class="c++">
Line 85: Line 88:
 
</pre>
 
</pre>
  
==Common Lisp==
+
===Common Lisp===
  
 
Lisp benefits from the use of the built-in s-expression type:
 
Lisp benefits from the use of the built-in s-expression type:
Line 106: Line 109:
 
<pre>(+ (+ (+ (* A (+ (* X 1) (* X 1))) (* (* X X) 0)) (+ (* B 1) (* X 0))) 0)</pre>
 
<pre>(+ (+ (+ (* A (+ (* X 1) (* X 1))) (* (* X X) 0)) (+ (* B 1) (* X 0))) 0)</pre>
  
==F#==
+
===F#===
  
 
In F#, the + and * operators can be overloaded to work with the user-defined <tt>expr</tt> type:
 
In F#, the + and * operators can be overloaded to work with the user-defined <tt>expr</tt> type:
Line 139: Line 142:
 
</pre>
 
</pre>
  
==Java==
+
===Java===
  
 
<pre class="java">
 
<pre class="java">
Line 187: Line 190:
 
</pre>
 
</pre>
  
==OCaml==
+
===OCaml===
  
 
Note that this implementation performs simple simplifications as expressions are constructed and pretty prints expressions with minimal bracketing (only sums inside products are bracketed).
 
Note that this implementation performs simple simplifications as expressions are constructed and pretty prints expressions with minimal bracketing (only sums inside products are bracketed).
Line 245: Line 248:
 
<pre>d (a x x + b x + c) x = a x + x a + b</pre>
 
<pre>d (a x x + b x + c) x = a x + x a + b</pre>
  
==Perl==
+
===Perl===
 
<pre class="perl">
 
<pre class="perl">
 
use Math::Symbolic qw();
 
use Math::Symbolic qw();
Line 254: Line 257:
 
</pre>
 
</pre>
  
==Python==
+
===Python===
  
 
<pre class="python">
 
<pre class="python">
Line 306: Line 309:
 
</pre>
 
</pre>
  
 +
===Ruby===
 +
<pre class="ruby">
 +
class Expr
 +
  def +(other) Plus.new(self, other) end
 +
  def *(other) Times.new(self, other) end
 +
end
 +
 +
class Int < Expr
 +
  def initialize(n) @n = n end
 +
  def d(var) Int.new(0) end
 +
  def to_s() @n.to_s end
 +
end
 +
 +
class Var < Expr
 +
  def initialize(var) @var = var end
 +
  def d(var) Int.new(@var==var ? 1 : 0) end
 +
  def to_s() @var end
 +
end
 +
 +
class Plus < Expr
 +
  def initialize(a, b) @e1 = a; @e2 = b end
 +
  def d(var) Plus.new(@e1.d(var), @e2.d(var)) end
 +
  def to_s() "(#@e1 + #@e2)" end
 +
end
 +
 +
class Times < Expr
 +
  def initialize(a, b) @e1 = a; @e2 = b end
 +
  def d(var) Plus.new(Times.new(@e1, @e2.d(var)), Times.new(@e1.d(var), @e2)) end
 +
  def to_s() "(#@e1 * #@e2)" end
 +
end
 +
 +
x = Var.new("x")
 +
a = Var.new("a")
 +
b = Var.new("b")
 +
c = Var.new("c")
 +
e = a * x * x + b * x + c
 +
puts "d(#{e}, x) = #{e.d("x")}"
 +
</pre>
  
 
[[Category:C++]]
 
[[Category:C++]]
Line 314: Line 355:
 
[[Category:Perl]]
 
[[Category:Perl]]
 
[[Category:Python]]
 
[[Category:Python]]
 +
[[Category:Ruby]]
 
[[Category:Math]]
 
[[Category:Math]]

Latest revision as of 03:02, 7 March 2011

Related content:

Compute and print a derivative of the symbolic expression a x^2 + b x + c in Mathematica syntax, preferably with simplification.

Implementations[edit]

C++[edit]

#include <iostream>

using namespace std;

class Var;

class Base {
public:
  virtual ~Base() {};
  virtual const Base *clone() = 0;
  virtual const Base *d(const string &v) const = 0;
  virtual ostream &print(ostream &o) const = 0;
};

ostream &operator<<(ostream &o, const Base &e) { e.print(o); return o; }

class Int : public Base {
  const int n;
public:
  Int(int m) : n(m) {}
  ~Int() {}
  const Base *clone() { return new Int(n); }
  const Base *d(const string &v) const { return new Int(0); }
  ostream &print(ostream &o) const { return o << n; }
};

class Var : public Base {
  const string var;
public:
  Var(string v) : var(v) {}
  ~Var() {}
  const Base *clone() { return new Var(var); }
  const Base *d(const string &v) const { return new Int(var == v ? 1 : 0); }
  ostream &print(ostream &o) const { return o << var; }
};

class Plus : public Base {
  const Base *e1, *e2;
public:
  Plus(const Base *a, const Base *b) : e1(a), e2(b) {}
  ~Plus() { delete e1; delete e2; }
  const Base *clone() { return new Plus(e1, e2); }
  const Base *d(const string &v) const { return new Plus(e1->d(v), e2->d(v)); }
  ostream &print(ostream &o) const
  { return o << "(" << *e1 << " + " << *e2 << ")"; }
};

class Times : public Base {
  const Base *e1, *e2;
public:
  Times(const Base *a, const Base *b) : e1(a), e2(b) {}
  ~Times() { delete e1; delete e2; }
  const Base *clone() { return new Times(e1, e2); }
  const Base *d(const string &v) const
  { return new Plus(new Times(e1, e2->d(v)), new Times(e1->d(v), e2)); }
  ostream &print(ostream &o) const { return o << "(" << *e1 << " * " << *e2 << ")"; }
};

class Expr {
public:
  Base *e;
  Expr(Base *a) : e(a) {}
};

const Expr operator+(const Expr e1, const Expr e2)
{ return Expr(new Plus(e1.e->clone(), e2.e->clone())); }
const Expr operator*(const Expr e1, const Expr e2)
{ return Expr(new Times(e1.e->clone(), e2.e->clone())); }

ostream &operator<<(ostream &o, const Expr e) { return o << e.e; }

int main() {
  Var vx("x"), va("a"), vb("b"), vc("c");
  Expr x(&vx), a(&va), b(&vb), c(&vc);
  Expr e = a*x*x + b*x + c;
  cout << "d(" << *(e.e) << ", x) = " << *(e.e->d("x")) << endl;
  return 0;
}

Common Lisp[edit]

Lisp benefits from the use of the built-in s-expression type:

(defun d (e x)
  (cond
   ((atom e) (if (eq e x) 1 0))
   ((eq (car e) '+) `(+ ,(d (cadr e) x) ,(d (caddr e) x)))
   ((eq (car e) '*) `(+ (* ,(cadr e) ,(d (caddr e) x))
                        (* ,(caddr e) ,(d (cadr e) x))))))

(defvar *e* '(+ (+ (* a (* x x)) (* b x)) c))

(d *e* 'x)

The result is printed as:

(+ (+ (+ (* A (+ (* X 1) (* X 1))) (* (* X X) 0)) (+ (* B 1) (* X 0))) 0)

F#[edit]

In F#, the + and * operators can be overloaded to work with the user-defined expr type:

type expr =
  | Int of int
  | Add of expr * expr
  | Mul of expr * expr
  | Var of string with
    static member ( + ) (f, g) = Add(f, g)
    static member ( * ) (f, g) = Mul(f, g)
  end

let rec d e x = match e with
  | Int n -> Int 0
  | Add(f, g) -> d f x + d g x
  | Mul(f, g) -> f * d g x + g * d f x
  | Var v -> Int (if v=x then 1 else 0)

let rec string_of = function
  | Int n -> string_of_int n
  | Var v -> v
  | Add(f, g) -> "("^string_of f^" + "^string_of g^")"
  | Mul(f, g) -> "("^string_of f^" * "^string_of g^")"

let x = Var "x" and a = Var "a" and b = Var "b" and c = Var "c"

let e = a * x * x + b * x + c

let () = Printf.printf "d %s x = %s\n" (string_of e) (string_of (d e "x"))

Java[edit]

abstract class Expr {
  public abstract Expr d(String v);
  public Expr plus(Expr e2) { return new Plus(this, e2); }
  public Expr times(Expr e2) { return new Times(this, e2); }
}

class Int extends Expr {
  private final int n;
  public Int(int m) { n = m; }
  public Expr d(String v) { return new Int(0); }
  public String toString() { return Integer.toString(n); }
}

class Var extends Expr {
  private final String var;
  public Var(String v) { var = v; }
  public Expr d(String v) { return new Int(var.equals(v) ? 1 : 0); }
  public String toString() { return var; }
}

class Plus extends Expr {
  private final Expr e1, e2;
  public Plus(Expr a, Expr b) { e1 = a; e2 = b; }
  public Expr d(String v) { return new Plus(e1.d(v), e2.d(v)); }
  public String toString() { return "(" + e1 + " + " + e2 + ")"; }
}

class Times extends Expr {
  private final Expr e1, e2;
  public Times(Expr a, Expr b) { e1 = a; e2 = b; }
  public Expr d(String v)
  { return new Plus(new Times(e1, e2.d(v)), new Times(e1.d(v), e2)); }
  public String toString() { return "(" + e1 + " * " + e2 + ")"; }
}

public class Derivative {
  public static void main(String[] args) {
    Expr x = new Var("x"), a = new Var("a"),
         b = new Var("b"), c = new Var("c");
    Expr e = a.times(x).times(x).plus(b.times(x)).plus(c);
    System.out.println("d(" + e + ", x) = " + e.d("x"));
  }
}

OCaml[edit]

Note that this implementation performs simple simplifications as expressions are constructed and pretty prints expressions with minimal bracketing (only sums inside products are bracketed).

type expr =
  | Int of int
  | Var of string
  | Add of expr * expr
  | Mul of expr * expr

let ( +: ) f g = match f, g with
  | Int n, Int m -> Int (n + m)
  | Int 0, f
  | f, Int 0 -> f
  | f, g -> Add(f, g)

let ( *: ) f g = match f, g with
  | Int n, Int m -> Int (n * m)
  | Int 0, _
  | _, Int 0 -> Int 0
  | Int 1, f
  | f, Int 1 -> f
  | f, g -> Mul (f, g)

let rec d e x = match e with
  | Int _ -> Int 0
  | Add (f, g) -> d f x +: d g x
  | Mul (f, g) -> f *: d g x +: g *: d f x
  | Var v -> Int (if v=x then 1 else 0)

open Printf

let rec print ff = function
  | Int n -> fprintf ff "%d" n
  | Var v -> fprintf ff "%s" v
  | Add (f, g) -> fprintf ff "%a + %a" print f print g
  | Mul (f, g) ->
      let product ff = function
        | Add _ as expr -> fprintf ff "(%a)" print expr
        | expr -> print ff expr
      in
      fprintf ff "%a %a" product f product g

let x = Var "x"
and a = Var "a"
and b = Var "b"
and c = Var "c"

let e = a *: x *: x +: b *: x +: c

let () = Printf.printf "d (%a) x = %a\n" print e print (d e "x")

The result is printed as:

d (a x x + b x + c) x = a x + x a + b

Perl[edit]

use Math::Symbolic qw();
my $tree = Math::Symbolic->parse_from_string('a x^2 + b x + c');
$tree->new(
    'partial_derivative', $tree, 'x'
)->apply_derivatives->simplify; # returns string

Python[edit]

class Expr:
  def __add__(self, other):
    return Plus(self, other)
  def __mul__(self, other):
    return Times(self, other)

class Int(Expr):
  def __init__(self, n):
    self.n = n
  def d(self, v):
    return Int(0)
  def __str__(self):
    return `self.n`

class Var(Expr):
  def __init__(self, var):
    self.var = var
  def d(self, v):
    return Int(self.var == v and 1 or 0)
  def __str__(self):
    return self.var

class Plus(Expr):
  def __init__(self, a, b):
    self.e1 = a
    self.e2 = b
  def d(self, v):
    return Plus(self.e1.d(v), self.e2.d(v))
  def __str__(self):
    return "(%s + %s)" % (self.e1, self.e2)

class Times(Expr):
  def __init__(self, a, b):
    self.e1 = a
    self.e2 = b
  def d(self, v):
    return Plus(Times(self.e1, self.e2.d(v)), Times(self.e1.d(v), self.e2))
  def __str__(self):
    return "(%s * %s)" % (self.e1, self.e2)

if __name__ == "__main__":
  x = Var("x")
  a = Var("a")
  b = Var("b")
  c = Var("c")
  e = a * x * x + b * x + c
  print "d(%s, x) = %s" % (e, e.d("x"))

Ruby[edit]

class Expr
  def +(other) Plus.new(self, other) end
  def *(other) Times.new(self, other) end
end

class Int < Expr
  def initialize(n) @n = n end
  def d(var) Int.new(0) end
  def to_s() @n.to_s end
end

class Var < Expr
  def initialize(var) @var = var end
  def d(var) Int.new(@var==var ? 1 : 0) end
  def to_s() @var end
end

class Plus < Expr
  def initialize(a, b) @e1 = a; @e2 = b end
  def d(var) Plus.new(@e1.d(var), @e2.d(var)) end
  def to_s() "(#@e1 + #@e2)" end
end

class Times < Expr
  def initialize(a, b) @e1 = a; @e2 = b end
  def d(var) Plus.new(Times.new(@e1, @e2.d(var)), Times.new(@e1.d(var), @e2)) end
  def to_s() "(#@e1 * #@e2)" end
end

x = Var.new("x")
a = Var.new("a")
b = Var.new("b")
c = Var.new("c")
e = a * x * x + b * x + c
puts "d(#{e}, x) = #{e.d("x")}"