15-p15_deriv导数

import math
import numpy as np


class Exp:
    def eval(self, ** env):
        pass

    def deriv(self, x):
        pass

    def __add__(self, other):
        other = to_exp(other)
        return Add(self, other)

    def __radd__(self, other):
        other = to_exp(other)
        return Add(other, self)

    def __sub__(self, other):
        other = to_exp(other)
        return Sub(self, other)

    def __rsub__(self, other):
        other = to_exp(other)
        return Sub(other, self)

    def __mul__(self, other):
        other = to_exp(other)
        if isinstance(other, Const) and other.value == 0:
            return 0
        return Mul(self, other)

    def __rmul__(self, other):
        other = to_exp(other)
        if isinstance(other, Const) and other.value == 0:
            return 0
        return Mul(other, self)

    def __truediv__(self, other):
        other = to_exp(other)
        return Truediv(self, other)

    def __rtruediv__(self, other):
        other = to_exp(other)
        if isinstance(other, Const) and other.value == 0:
            return 0
        return Truediv(other, self)

    def __pow__(self, power, modulo=None):
        return Pow(self, to_exp(power))

    def __rpow__(self, other):
        return Pow(to_exp(other), self)

    def __abs__(self):
        return Abs(self)


def to_exp(value):
    if isinstance(value, Exp):
        return value
    if type(value) == str:
        return Variable(value)
    if type(value) in (int, float):
        return Const(value)
    raise Exception('Can not convert %s to an Expression' % value)


class Abs(Exp):
    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return '|%s|' % self.value

    def eval(self, **env):
        self.result = abs(self.value.eval(**env))
        return self.result

    def deriv(self, x):
        return (1 if self.result > 0 else -1) * self.value.deriv(x)


def log(exp):
    exp = to_exp(exp)
    return Log(exp, e)


class Pow(Exp):
    def __init__(self, left, right):
        self.left = left
        self.right = right

    def eval(self, **env):
        return self.left.eval(**env) ** self.right.eval(**env)

    def deriv(self, x):
        if isinstance(self.right, Const):
            return self.right * self.left**(self.right-1) * self.left.deriv(x)
        if isinstance(self.left, Const):
            return self.right.deriv(x) * log(self.left) * self
        result = self.right.deriv(x) * log(self.left) + self.right * self.left.deriv(x) / self.left
        return result * self

    def __repr__(self):
        return '%s ** %s' % (self.left, self.right)


class Truediv(Exp):
    def __init__(self, left, right):
        self.left = left
        self.right = right

    def eval(self, **env):
        div = self.left.eval(**env)
        if div == 0:
            return 0
        der = self.right.eval(**env)
        return div / der

    def deriv(self, x):
        return (self.left.deriv(x) * self.right - self.left * self.right.deriv(x)) / self.right ** 2

    def __repr__(self):
        return '(%s / %s)' % (self.left, self.right)


class Mul(Exp):
    def __init__(self, left, right):
        self.left = left
        self.right = right

    def eval(self, **env):
        return self.left.eval(**env) * self.right.eval(**env)

    def deriv(self, x):
        return self.left.deriv(x) * self.right + self.left * self.right.deriv(x)

    def __repr__(self):
        return '(%s * %s)' % (self.left, self.right)


class Sub(Exp):
    def __init__(self, left, right):
        self.left = left
        self.right = right

    def eval(self, **env):
        return self.left.eval(**env) - self.right.eval(**env)

    def deriv(self, x):
        return self.left.deriv(x) - self.right.deriv(x)

    def __repr__(self):
        return '(%s - %s)' % (self.left, self.right)


class Add(Exp):
    def __init__(self, left, right):
        self.left = left
        self.right = right

    def eval(self, **env):
        return self.left.eval(**env) + self.right.eval(**env)

    def deriv(self, x):
        return self.left.deriv(x) + self.right.deriv(x)

    def __repr__(self):
        return '(%s + %s)' % (self.left, self.right)


class Const(Exp):
    def __init__(self, value):
        self.value = value

    def eval(self, **env):
        return self.value

    def deriv(self, x):
        return 0

    def __repr__(self):
        return str(self.value)


e = Const(math.e)
pi = Const(math.pi)


class Log(Exp):
    def __init__(self, value, base=e):
        self.value = value
        self.base = base

    def eval(self, **env):
        return math.log(self.value.eval(**env), self.base.eval(**env))

    def deriv(self, x):
        if isinstance(self.base, Const):
            return self.value.deriv(x) / self.value / log(self.base)
        if isinstance(self.value, Const):
            return - log(self.value) * self.base.deriv(x) / (self.base * log(self.base)**2)
        result = self.value.deriv(x) / self.value * log(self.base)
        result -= self.base.deriv(x) / self.base * log(self.value)
        return result / (log(self.base) ** 2)

    def __repr__(self):
        return 'log(%s, %s)' % (self.value, self.base)


class Variable(Exp):
    def __init__(self, name):
        self.name = name

    def eval(self, **env):
        if self.name in env:
            return env[self.name]
        raise Exception('Variable %s not found' % self.name)

    def deriv(self, x):
        if isinstance(x, Variable):
            x = x.name
        return 1 if self.name == x else 0

    def __repr__(self):
        return self.name


def _test_deriv(y, x):
    dy_dx = y.deriv('x')
    print('-' * 200)
    print(y)
    print(dy_dx)
    print(dy_dx.eval(x=x))


if __name__ == '__main__':
    x = Variable('x')
    print(x.eval(x=3.14))

    y = x + 3
    dy_dx = y.deriv(x)
    print(y)
    print(dy_dx)

    print('-' * 200)
    y = 4 * x + 3
    dy_dx = y.deriv(x)
    print(y)
    print(dy_dx)

    print('-' * 200)
    y = 4 * x * x + 3 * x + 5
    dy_dx = y.deriv(x)
    print(y)
    print(dy_dx)
    print(dy_dx.eval(x=1))

    print('-' * 200)
    y = 1 / x
    dy_dx = y.deriv(x)
    print(y)
    print(dy_dx)
    print(dy_dx.eval(x=0.5))

    _test_deriv(e ** (2*x), 0.5)

    y = abs(x**3)
    y.eval(x=0.5)
    _test_deriv(y, 0.5)
D:\Anaconda\python.exe D:/AI20/06_codes/deeplearning_20/p15_deriv.py
3.14
(x + 3)
1
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
((4 * x) + 3)
((0 + (4 * 1)) + 0)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
((((4 * x) * x) + (3 * x)) + 5)
(((((0 + (4 * 1)) * x) + ((4 * x) * 1)) + (0 + (3 * 1))) + 0)
11
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(1 / x)
((0 - (1 * 1)) / x ** 2)
-4.0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.718281828459045 ** (2 * x)
(((0 + (2 * 1)) * log(2.718281828459045, 2.718281828459045)) * 2.718281828459045 ** (2 * x))
5.43656365691809
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|x ** 3|
(1 * ((3 * x ** (3 - 1)) * 1))
0.75

Process finished with exit code 0

发布了88 篇原创文章 · 获赞 2 · 访问量 1301

猜你喜欢

转载自blog.csdn.net/HJZ11/article/details/104508159
15
今日推荐