Calculate a derivative

From CodeCodex

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")}"