Skip to content

Instantly share code, notes, and snippets.

@7shi
Last active December 15, 2016 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 7shi/c0a6f489fbe22b98b015 to your computer and use it in GitHub Desktop.
Save 7shi/c0a6f489fbe22b98b015 to your computer and use it in GitHub Desktop.
[Haskell][F#][JavaSript][C][C++][C#][Java]微分・積分
【実行結果】
f1: d/dx x^3+x^2+x+1 = 3*x^2+2*x+1+0
f2: ∫ x^3+x^2+x+1 dx = x^4/4+x^3/3+x^2/2+x+C
f3: d/dx f2 = 4*x^3/4+3*x^2/3+2*x/2+1+0
data Expr = N Int
| Add Expr Expr
| Mul Expr Expr
| Div Expr Expr
| Var String Int
x n = Var "x" n
tostr (N n) = show n
tostr (Add x y) = tostr x ++ "+" ++ tostr y
tostr (Mul x y) = tostr2 x ++ "*" ++ tostr2 y
tostr (Div x y) = tostr2 x ++ "/" ++ tostr2 y
tostr (Var name 1) = name
tostr (Var name n) = name ++ "^" ++ show n
tostr2 (Add x y) = "(" ++ tostr (Add x y) ++ ")"
tostr2 e = tostr e
differentiate (Add x y) = differentiate x `Add` differentiate y
differentiate (Mul x y) = x `Mul` differentiate y
differentiate (Div x y) = differentiate x `Div` y
differentiate (Var "x" 1) = N 1
differentiate (Var "x" n) = N n `Mul` x (n - 1)
differentiate _ = N 0
integrate (Add x y) = integrate x `Add` integrate y
integrate (Mul x y) = x `Mul` integrate y
integrate (Div x y) = integrate x `Div` y
integrate (Var "x" n) = x (n + 1) `Div` N (n + 1)
integrate (N 1) = x 1
integrate e = e `Mul` x 1
indefIntegrate e = integrate e `Add` Var "C" 1
eval (N n) = n
eval (Add x y) = (eval x) + (eval y)
eval (Mul x y) = (eval x) * (eval y)
eval (Div x y) = (eval x) `div` (eval y)
main = do
let f = x 3 `Add` x 2 `Add` x 1 `Add` N 1
f1 = differentiate(f)
f2 = indefIntegrate(f)
f3 = differentiate(f2)
putStrLn $ "f1: d/dx " ++ tostr f ++ " = " ++ tostr f1
putStrLn $ "f2: ∫ " ++ tostr f ++ " dx = " ++ tostr f2
putStrLn $ "f3: d/dx f2 = " ++ tostr f3
type Expr =
| Num of int
| Add of Expr * Expr
| Mul of Expr * Expr
| Div of Expr * Expr
| Var of string * int
static member (+)(x, y) = Add(x, Num y)
static member (+)(x, y) = Add(Num x, y)
static member (+)(x, y) = Add(x, y)
static member (*)(x, y) = Mul(x, y)
static member (/)(x, y) = Div(x, y)
static member Pow(x, n) =
match x with
| Var(name, xn) -> Var(name, xn * n)
| _ -> failwith "not supported"
let x = Var("x", 1)
let rec tostr e =
let tostr2 = function
| Add _ as e -> "(" + (tostr e) + ")"
| e -> (tostr e)
match e with
| Num n -> n.ToString()
| Add(x, y) -> (tostr x) + "+" + (tostr y)
| Mul(x, y) -> (tostr2 x) + "*" + (tostr2 y)
| Div(x, y) -> (tostr2 x) + "/" + (tostr2 y)
| Var(name, 1) -> name
| Var(name, n) -> sprintf "%s^%d" name n
let rec differentiate = function
| Add(x, y) -> (differentiate x) + (differentiate y)
| Mul(x, y) -> x * (differentiate y)
| Div(x, y) -> (differentiate x) / y
| Var("x", 1) -> Num 1
| Var("x", n) -> (Num n) * (x ** (n - 1))
| _ -> Num 0
let rec integrate = function
| Add(x, y) -> (integrate x) + (integrate y)
| Mul(x, y) -> x * (integrate y)
| Div(x, y) -> (integrate x) / y
| Var("x", n) -> (x ** (n + 1)) / (Num(n + 1))
| Num 1 -> x
| e -> e * x
let indefIntegrate e = (integrate e) + Var("C", 1)
let rec eval = function
| Num n -> float n
| Add(x, y) -> (eval x) + (eval y)
| Mul(x, y) -> (eval x) * (eval y)
| Div(x, y) -> (eval x) / (eval y)
| _ -> nan
let f = x**3 + x**2 + x + 1
let f1 = differentiate f
let f2 = indefIntegrate f
let f3 = differentiate f2
printfn "f1: d/dx %s = %s" (tostr f) (tostr f1)
printfn "f2: ∫ %s dx = %s" (tostr f) (tostr f2)
printfn "f3: d/dx f2 = %s" (tostr f3)
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>数式処理</title></head>
<body><pre><script type="text/javascript">
function Add(x, y) { this.x = x; this.y = y; }
function Mul(x, y) { this.x = x; this.y = y; }
function Div(x, y) { this.x = x; this.y = y; }
function Var(name, n) { this.name = name; this.n = n; }
function add(x, y) { return new Add(x, y); }
function mul(x, y) { return new Mul(x, y); }
function div(x, y) { return new Div(x, y); }
function x(n) { return new Var("x", n); }
function tostr(e) {
function tostr2(e) {
return e instanceof Add ? "(" + tostr(e) + ")" : tostr(e);
}
if (typeof(e) == "number") {
return e.toString();
} else if (e instanceof Add) {
return tostr(e.x) + "+" + tostr(e.y);
} else if (e instanceof Mul) {
return tostr2(e.x) + "*" + tostr2(e.y);
} else if (e instanceof Div) {
return tostr2(e.x) + "/" + tostr2(e.y);
} else if (e instanceof Var) {
return e.n == 1 ? e.name : e.name + "^" + e.n;
}
}
function differentiate(e) {
if (e instanceof Var && e.name == "x") {
return e.n == 1 ? 1 : mul(e.n, x(e.n - 1));
} else if (e instanceof Add) {
return add(differentiate(e.x), differentiate(e.y));
} else if (e instanceof Mul) {
return mul(e.x, differentiate(e.y));
} else if (e instanceof Div) {
return div(differentiate(e.x), e.y);
} else if (typeof(e) == "number" || e instanceof Var) {
return 0;
}
}
function integrate(e) {
if (e instanceof Var && e.name == "x") {
return div(x(e.n + 1), e.n + 1);
} else if (e instanceof Add) {
return add(integrate(e.x), integrate(e.y));
} else if (e instanceof Mul) {
return mul(e.x, integrate(e.y));
} else if (e instanceof Div) {
return div(integrate(e.x), e.y);
} else if (e instanceof Var) {
return mul(e, x(1));
} else if (typeof(e) == "number") {
return e == 1 ? x(1) : mul(e, x(1));
}
}
function indefIntegrate(e) {
return add(integrate(e), new Var("C", 1));
}
function eval(e) {
if (typeof(e) == "number") {
return e;
} else if (e instanceof Add) {
return eval(e.x) + eval(e.y);
} else if (e instanceof Mul) {
return eval(e.x) * eval(e.y);
} else if (e instanceof Div) {
return eval(e.x) / eval(e.y);
}
}
var f = add(add(add(x(3), x(2)), x(1)), 1);
var f1 = differentiate(f);
var f2 = indefIntegrate(f);
var f3 = differentiate(f2);
document.writeln("f1: d/dx " + tostr(f) + " = " + tostr(f1));
document.writeln("f2: ∫ " + tostr(f) + " dx = " + tostr(f2));
document.writeln("f3: d/dx f2 = " + tostr(f3));
</script></pre></body></html>
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>数式処理</title></head>
<body><pre><script type="text/javascript">
function Expr() {}
function Add(x, y) { this.x = x; this.y = y; }
function Mul(x, y) { this.x = x; this.y = y; }
function Div(x, y) { this.x = x; this.y = y; }
function Var(name, n) { this.name = name; this.n = n; }
function x(n) { return new Var("x", n); }
Number.prototype.add = Expr.prototype.add = function(e) { return new Add(this, e); }
Number.prototype.mul = Expr.prototype.mul = function(e) { return new Mul(this, e); }
Number.prototype.div = Expr.prototype.div = function(e) { return new Div(this, e); }
Number.prototype.tostr2 = Expr.prototype.tostr2 = function() { return this.toString(); }
Add.prototype = new Expr();
Mul.prototype = new Expr();
Div.prototype = new Expr();
Var.prototype = new Expr();
Add.prototype.tostr2 = function() { return "(" + this + ")"; }
Add.prototype.toString = function() { return this.x + "+" + this.y; }
Mul.prototype.toString = function() { return this.x.tostr2() + "*" + this.y.tostr2(); }
Div.prototype.toString = function() { return this.x.tostr2() + "/" + this.y.tostr2(); }
Var.prototype.toString = function() {
return this.n == 1 ? this.name : this.name + "^" + this.n;
}
Number.prototype.differentiate = function() { return 0; }
Add.prototype.differentiate = function() { return this.x.differentiate().add(this.y.differentiate()); }
Mul.prototype.differentiate = function() { return this.x.mul(this.y.differentiate()); }
Div.prototype.differentiate = function() { return this.x.differentiate().div(this.y); }
Var.prototype.differentiate = function() {
if (this.name != "x") return 0;
return this.n == 1 ? 1 : this.n.mul(x(this.n - 1));
}
Number.prototype.integrate = function() { return this == 1 ? x(1) : this.mul(x(1)); }
Add.prototype.integrate = function() { return this.x.integrate().add(this.y.integrate()); }
Mul.prototype.integrate = function() { return this.x.mul(this.y.integrate()); }
Div.prototype.integrate = function() { return this.x.integrate().div(this.y()); }
Var.prototype.integrate = function() {
if (this.name != "x") return this.mul(x(1));
return x(this.n + 1).div(this.n + 1);
}
Expr.prototype.indefIntegrate = function() {
return this.integrate().add(new Var("C", 1));
}
Number.prototype.eval = function() { return this; }
Add.prototype.eval = function() { return this.x.eval() + this.y.eval(); }
Mul.prototype.eval = function() { return this.x.eval() * this.y.eval(); }
Div.prototype.eval = function() { return this.x.eval() / this.y.eval(); }
Var.prototype.eval = function() { return NaN; }
var f = x(3).add(x(2)).add(x(1)).add(1);
var f1 = f.differentiate();
var f2 = f.indefIntegrate();
var f3 = f2.differentiate();
document.writeln("f1: d/dx " + f + " = " + f1);
document.writeln("f2: ∫ " + f + " dx = " + f2);
document.writeln("f3: d/dx f2 = " + f3);
</script></pre></body></html>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
typedef enum { NUM, ADD, MUL, DIV, VAR } ExprType;
typedef struct tagExpr {
ExprType type;
union {
struct { int num; };
struct { struct tagExpr *x, *y; };
struct { const char *name; int n; };
};
} Expr;
Expr *Num(int num) {
Expr *ret = (Expr *)malloc(sizeof(Expr));
ret->type = NUM;
ret->num = num;
return ret;
}
static Expr *makexy(ExprType type, Expr *x, Expr *y) {
Expr *ret = (Expr *)malloc(sizeof(Expr));
ret->type = type;
ret->x = x;
ret->y = y;
return ret;
}
Expr *Add(Expr *x, Expr *y) { return makexy(ADD, x, y); }
Expr *Mul(Expr *x, Expr *y) { return makexy(MUL, x, y); }
Expr *Div(Expr *x, Expr *y) { return makexy(DIV, x, y); }
Expr *Var(const char *name, int n) {
Expr *ret = (Expr *)malloc(sizeof(Expr));
ret->type = VAR;
ret->name = name;
ret->n = n;
return ret;
}
Expr *x(int n) { return Var("x", n); }
static char *aprintf(const char *format, ...) {
char *ret;
int len;
va_list args;
va_start(args, format);
len = vsnprintf(NULL, 0, format, args) + 1;
va_end(args);
ret = (char *)malloc(len);
va_start(args, format);
vsnprintf(ret, len, format, args);
va_end(args);
return ret;
}
static char *tostr2(Expr *e) {
char *ret, *tmp;
char *tostr(Expr *e);
switch (e->type) {
case ADD:
tmp = tostr(e);
ret = aprintf("(%s)", tmp);
free(tmp);
break;
default:
ret = tostr(e);
break;
}
return ret;
}
char *tostr(Expr *e) {
char *ret, *tmp1, *tmp2;
switch (e->type) {
case NUM:
ret = aprintf("%d", e->num);
break;
case ADD:
tmp1 = tostr(e->x);
tmp2 = tostr(e->y);
ret = aprintf("%s+%s", tmp1, tmp2);
free(tmp1);
free(tmp2);
break;
case MUL:
case DIV:
tmp1 = tostr2(e->x);
tmp2 = tostr2(e->y);
ret = aprintf("%s%c%s", tmp1, "*/"[e->type == DIV], tmp2);
free(tmp1);
free(tmp2);
break;
case VAR:
if (e->n == 1) {
ret = strdup(e->name);
} else {
ret = aprintf("%s^%d", e->name, e->n);
}
break;
default:
ret = strdup("?");
}
return ret;
}
Expr *differentiate(Expr *e) {
switch (e->type) {
case ADD: return Add(differentiate(e->x), differentiate(e->y));
case MUL: return Mul(e->x, differentiate(e->y));
case DIV: return Div(differentiate(e->x), e->y);
case VAR:
if (strcmp(e->name, "x")) break;
return e->n == 1 ? Num(1) : Mul(Num(e->n), x(e->n - 1));
}
return Num(0);
}
Expr *integrate(Expr *e) {
switch (e->type) {
case ADD: return Add(integrate(e->x), integrate(e->y));
case MUL: return Mul(e->x, integrate(e->y));
case DIV: return Div(integrate(e->x), e->y);
case VAR:
if (strcmp(e->name, "x")) break;
return Div(x(e->n + 1), Num(e->n + 1));
case NUM:
if (e->num == 1) return x(1);
break;
}
return Mul(e, x(1));
}
Expr *indefIntegrate(Expr *e) {
return Add(integrate(e), Var("C", 1));
}
double eval(Expr *e) {
switch (e->type) {
case NUM: return e->num;
case ADD: return eval(e->x) + eval(e->y);
case MUL: return eval(e->x) * eval(e->y);
case DIV: return eval(e->x) / eval(e->y);
}
return NAN;
}
int main() {
Expr *f = Add(Add(Add(x(3), x(2)), x(1)), Num(1));
Expr *f1 = differentiate(f);
Expr *f2 = indefIntegrate(f);
Expr *f3 = differentiate(f2);
printf("f1: d/dx %s = %s\n", tostr(f), tostr(f1));
printf("f2: ∫ %s dx = %s\n", tostr(f), tostr(f2));
printf("f3: d/dx f2 = %s\n", tostr(f3));
return 0;
}
#include <iostream>
#include <string>
#include <memory>
#include <cstdio>
#include <cmath>
using namespace std;
class Expr {
public:
virtual ~Expr() {}
virtual string tostr() const = 0;
virtual string tostr2() const { return tostr(); }
virtual shared_ptr<Expr> differentiate() const = 0;
virtual shared_ptr<Expr> integrate() const = 0;
virtual double eval() const = 0;
shared_ptr<Expr> indefIntegrate() const;
};
class Num : public Expr {
int n;
public:
Num(int n) : n(n) {}
virtual ~Num() {}
virtual string tostr() const;
virtual shared_ptr<Expr> differentiate() const;
virtual shared_ptr<Expr> integrate() const;
virtual double eval() const;
};
class Add : public Expr {
shared_ptr<Expr> x, y;
public:
Add(const shared_ptr<Expr> &x, const shared_ptr<Expr> &y) : x(x), y(y) {}
virtual ~Add() {}
virtual string tostr() const;
virtual string tostr2() const { return "(" + tostr() + ")"; }
virtual shared_ptr<Expr> differentiate() const;
virtual shared_ptr<Expr> integrate() const;
virtual double eval() const;
};
class Mul : public Expr {
shared_ptr<Expr> x, y;
public:
Mul(const shared_ptr<Expr> &x, const shared_ptr<Expr> &y) : x(x), y(y) {}
virtual ~Mul() {}
virtual string tostr() const;
virtual shared_ptr<Expr> differentiate() const;
virtual shared_ptr<Expr> integrate() const;
virtual double eval() const;
};
class Div : public Expr {
shared_ptr<Expr> x, y;
public:
Div(const shared_ptr<Expr> &x, const shared_ptr<Expr> &y) : x(x), y(y) {}
virtual ~Div() {}
virtual string tostr() const;
virtual shared_ptr<Expr> differentiate() const;
virtual shared_ptr<Expr> integrate() const;
virtual double eval() const;
};
class Var : public Expr {
string name;
int n;
public:
Var(const string &name, int n) : name(name), n(n) {}
virtual ~Var() {}
virtual string tostr() const;
virtual shared_ptr<Expr> differentiate() const;
virtual shared_ptr<Expr> integrate() const;
virtual double eval() const;
};
shared_ptr<Expr> num(int n) {
return shared_ptr<Expr>(new Num(n));
}
shared_ptr<Expr> var(const string &name, int n) {
return shared_ptr<Expr>(new Var(name, n));
}
shared_ptr<Expr> x(int n) { return var("x", n); }
shared_ptr<Expr> operator+(const shared_ptr<Expr> &x, int n) {
return shared_ptr<Expr>(new Add(x, num(n)));
}
shared_ptr<Expr> operator+(const shared_ptr<Expr> &x, const shared_ptr<Expr> &y) {
return shared_ptr<Expr>(new Add(x, y));
}
shared_ptr<Expr> operator*(const shared_ptr<Expr> &x, const shared_ptr<Expr> &y) {
return shared_ptr<Expr>(new Mul(x, y));
}
shared_ptr<Expr> operator/(const shared_ptr<Expr> &x, const shared_ptr<Expr> &y) {
return shared_ptr<Expr>(new Div(x, y));
}
string to_string(int n) {
char buf[16];
snprintf(buf, sizeof(buf), "%d", n);
return buf;
}
string Num::tostr() const { return to_string(n); }
string Add::tostr() const { return x->tostr () + "+" + y->tostr(); }
string Mul::tostr() const { return x->tostr2() + "*" + y->tostr2(); }
string Div::tostr() const { return x->tostr2() + "/" + y->tostr2(); }
string Var::tostr() const { return n == 1 ? name : name + "^" + to_string(n); }
shared_ptr<Expr> Num::differentiate() const { return num(0); }
shared_ptr<Expr> Add::differentiate() const { return x->differentiate() + y->differentiate(); }
shared_ptr<Expr> Mul::differentiate() const { return x * y->differentiate(); }
shared_ptr<Expr> Div::differentiate() const { return x->differentiate() / y; }
shared_ptr<Expr> Var::differentiate() const {
if (name != "x") return num(0);
return n == 1 ? num(1) : num(n) * x(n - 1);
}
shared_ptr<Expr> Num::integrate() const { return n == 1 ? x(1) : num(n) * x(1); }
shared_ptr<Expr> Add::integrate() const { return x->integrate() + y->integrate(); }
shared_ptr<Expr> Mul::integrate() const { return x * y->integrate(); }
shared_ptr<Expr> Div::integrate() const { return x->integrate() / y; }
shared_ptr<Expr> Var::integrate() const {
if (name != "x") return var(name, n) * x(1);
return x(n + 1) / num(n + 1);
}
shared_ptr<Expr> Expr::indefIntegrate() const {
return integrate() + var("C", 1);
}
double Num::eval() const { return n; }
double Add::eval() const { return x->eval() + y->eval(); }
double Mul::eval() const { return x->eval() * y->eval(); }
double Div::eval() const { return x->eval() / y->eval(); }
double Var::eval() const { return NAN; }
int main() {
auto f = x(3) + x(2) + x(1) + 1;
auto f1 = f->differentiate();
auto f2 = f->indefIntegrate();
auto f3 = f2->differentiate();
cout << "f1: d/dx " << f->tostr() << " = " << f1->tostr() << endl;
cout << "f2: ∫ " << f->tostr() << " dx = " << f2->tostr() << endl;
cout << "f3: d/dx f2 = " << f3->tostr() << endl;
}
using System;
abstract class ExprUtil {
public static Num Num(int n) { return new Num(n); }
public static Var Var(string name, int n) { return new Var(name, n); }
public static Var X(int n) { return Var("x", n); }
}
abstract class Expr : ExprUtil {
public virtual string tostr2() { return ToString(); }
public abstract Expr Differentiate();
public abstract Expr Integrate();
public abstract double Eval();
public Expr IndefIntegrate() { return Integrate() + Var("C", 1); }
public static Expr operator+(Expr x, int n) { return new Add(x, Num(n)); }
public static Expr operator+(Expr x, Expr y) { return new Add(x, y); }
public static Expr operator*(Expr x, Expr y) { return new Mul(x, y); }
public static Expr operator/(Expr x, Expr y) { return new Div(x, y); }
}
partial class Num : Expr {
private int n;
public Num(int n) { this.n = n; }
}
partial class Add : Expr {
private Expr x, y;
public Add(Expr x, Expr y) { this.x = x; this.y = y; }
public override string tostr2() { return "(" + this + ")"; }
}
partial class Mul : Expr {
private Expr x, y;
public Mul(Expr x, Expr y) { this.x = x; this.y = y; }
}
partial class Div : Expr {
private Expr x, y;
public Div(Expr x, Expr y) { this.x = x; this.y = y; }
}
partial class Var : Expr {
private string name;
private int n;
public Var(string name, int n) { this.name = name; this.n = n; }
}
partial class Num { public override string ToString() { return n.ToString (); } }
partial class Add { public override string ToString() { return x + "+" + y; } }
partial class Mul { public override string ToString() { return x.tostr2() + "*" + y.tostr2(); } }
partial class Div { public override string ToString() { return x.tostr2() + "/" + y.tostr2(); } }
partial class Var { public override string ToString() { return n == 1 ? name : name + "^" + n; } }
partial class Num { public override Expr Differentiate() { return Num(0); } }
partial class Add { public override Expr Differentiate() { return x.Differentiate() + y.Differentiate(); } }
partial class Mul { public override Expr Differentiate() { return x * y.Differentiate(); } }
partial class Div { public override Expr Differentiate() { return x.Differentiate() / y; } }
partial class Var { public override Expr Differentiate() {
if (name != "x") return Num(0);
return n == 1 ? Num(1) : Num(n) * X(n - 1);
} }
partial class Num { public override Expr Integrate() { return n == 1 ? X(1) : Num(n) * X(1); } }
partial class Add { public override Expr Integrate() { return x.Integrate() + y.Integrate(); } }
partial class Mul { public override Expr Integrate() { return x * y.Integrate(); } }
partial class Div { public override Expr Integrate() { return x.Integrate() / y; } }
partial class Var { public override Expr Integrate() {
if (name != "x") return Var(name, n) * X(1);
return X(n + 1) / Num(n + 1);
} }
partial class Num { public override double Eval() { return n; } }
partial class Add { public override double Eval() { return x.Eval() + y.Eval(); } }
partial class Mul { public override double Eval() { return x.Eval() * y.Eval(); } }
partial class Div { public override double Eval() { return x.Eval() / y.Eval(); } }
partial class Var { public override double Eval() { return Double.NaN; } }
class Formula : ExprUtil {
static void Main() {
Expr f = X(3) + X(2) + X(1) + 1;
Expr f1 = f.Differentiate();
Expr f2 = f.IndefIntegrate();
Expr f3 = f2.Differentiate();
Console.WriteLine("f1: d/dx {0} = {1}", f, f1);
Console.WriteLine("f2: ∫ {0} dx = {1}", f, f2);
Console.WriteLine("f3: d/dx f2 = {0}", f3);
}
}
abstract class ExprUtil {
public static Num num(int n) { return new Num(n); }
public static Var var(String name, int n) { return new Var(name, n); }
public static Var x(int n) { return var("x", n); }
}
abstract class Expr extends ExprUtil {
protected String tostr2() { return toString(); }
public abstract Expr differentiate();
public abstract Expr integrate();
public abstract double eval();
public final Expr indefIntegrate() { return integrate().add(var("C", 1)); }
public final Expr add(int n) { return new Add(this, num(n)); }
public final Expr add(Expr e) { return new Add(this, e); }
public final Expr mul(Expr e) { return new Mul(this, e); }
public final Expr div(Expr e) { return new Div(this, e); }
}
class Num extends Expr {
private int n;
public Num(int n) { this.n = n; }
public String toString() { return "" + n; }
public Expr differentiate() { return num(0); }
public Expr integrate() { return n == 1 ? x(1) : num(n).mul(x(1)); }
public double eval() { return n; }
}
class Add extends Expr {
private Expr x, y;
public Add(Expr x, Expr y) { this.x = x; this.y = y; }
public String toString() { return x + "+" + y; }
protected String tostr2() { return "(" + this+ ")"; }
public Expr differentiate() { return x.differentiate().add(y.differentiate()); }
public Expr integrate() { return x.integrate().add(y.integrate()); }
public double eval() { return x.eval() + y.eval(); }
}
class Mul extends Expr {
private Expr x, y;
public Mul(Expr x, Expr y) { this.x = x; this.y = y; }
public String toString() { return x.tostr2() + "*" + y.tostr2(); }
public Expr differentiate() { return x.mul(y.differentiate()); }
public Expr integrate() { return x.mul(y.integrate()); }
public double eval() { return x.eval() * y.eval(); }
}
class Div extends Expr {
private Expr x, y;
public Div(Expr x, Expr y) { this.x = x; this.y = y; }
public String toString() { return x.tostr2() + "/" + y.tostr2(); }
public Expr differentiate() { return x.differentiate().div(y); }
public Expr integrate() { return x.integrate().div(y); }
public double eval() { return x.eval() / y.eval(); }
}
class Var extends Expr {
private String name;
private int n;
public Var(String name, int n) { this.name = name; this.n = n; }
public String toString() { return n == 1 ? name : name + "^" + n; }
public Expr differentiate() {
if (!name.equals("x")) return num(0);
return n == 1 ? num(1) : num(n).mul(x(n - 1));
}
public Expr integrate() {
if (!name.equals("x")) return var(name, n).mul(x(1));
return x(n + 1).div(num(n + 1));
}
public double eval() { return Double.NaN; }
}
public class JFormula extends ExprUtil {
public static void main(String... args) {
Expr f = x(3).add(x(2)).add(x(1)).add(1);
Expr f1 = f.differentiate();
Expr f2 = f.indefIntegrate();
Expr f3 = f2.differentiate();
System.out.printf("f1: d/dx %s = %s\n", f, f1);
System.out.printf("f2: ∫ %s dx = %s\n", f, f2);
System.out.printf("f3: d/dx f2 = %s\n", f3);
}
}
@7shi
Copy link
Author

7shi commented Dec 15, 2016

関連記事です。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment