1 Star 0 Fork 0

Mercator/微分

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
求导算法.ts 11.65 KB
一键复制 编辑 原始数据 按行查看 历史
Mercator 提交于 2022-05-13 14:38 . 添加文件
namespace dd {
/**
*
* 定义两类函子,一种是包含简单函数的计算函子,另一类是包含其他函子关系的关系函子
* 计算函子有 f(x)=C,f(x)=a*x,f(x)=x^a,f(x)=sin(a),f(x)=ln(a)等
* 关系函子只有三类,相加、相乘和管道,分别表示f(x)+g(x),f(x)*g(x),f(g(x))
* 计算函子只进行函数操作,不包含其他函子
* 关系函子只包含各类函子,不包含具体的函数
*
* show()和toString()函数显示函子的内容
* apply()方法是进行计算,返回一个数值
* d()方法是求导,生成新的函子,为当前函子的导数
*/
/**
* 定义两个方法,阶乘算法和数列累加算法,
* 由于在这两个算法在初等代数中无法求导,并不将其封装成函子
* 而是定义为普通函数,在函子的运算中调用
*
*/
//阶乘 f(x)=x*(x-1)*...*1
const factorial = (x: number): number => x <= 1 ? 1 : x * factorial(x - 1)
/**
* 求数列的和,即带上下标的大Sigma方法,F(x)=Σ(f(x))
* @param x 数列每一项的自变量
* @param func 数列每一项的算法
* @param n 数列的元素总数
* @returns
*/
const sum_sequence = (func: Function): any => (n: number) => (x: number) => n < 0 ? 0 : func(n)(x) + sum_sequence(func)(n - 1)(x)//柯里化的单行写法
//定义自然对数e
//@ts-ignore
const e=():number=>(exp.of().apply(1))
/*
//常量C,f(x)=a
const C1=(constant:number)=>(x?:number)=>constant
//常量的导数为0
C1.d=()=>(x?:number)=>0
//标量函数,f(x)=ax
const scalar=(a:number)=>(x:number)=>a*x
//标量函数的导数是标量
scalar.d=()=>(a:number)=>(x:number)=>C1(a)(x)
*/
interface MathFunc {
// constructor(...any:any):any
get op(): any//获取算法链
get type(): string//返回函子类型
get param(): number//获取当前算子的参数
show(): any//展示算法
//apply(x?:number): number//应用对象中存储的算法,只允许一个变量X
d(): MathFunc//返回对应的导数
// of(...any:any):MathFunc//生成对象
toString(): string
}
abstract class MathFunc implements MathFunc {
static of(a: any, b?: any): MathFunc { throw new Error("Method not implemented.") }
d(): any { throw new Error("Method not implemented.") }
abstract apply(x?: number): number;
}
//最基本的函数,只保存一个常量,f(x)=c
class C extends MathFunc {
_param: number
_Op: Function
protected constructor(constant: number) {
super()
const C = (constant: number) => (x?: number) => constant
this._Op = C(constant)
this._param = constant
}
get type(): string {
return "C"
}
get param(): number {
return this._param
}
get value(): number {
return this._param
}
get op(): any {
throw new Error("Method not implemented.")
}
show(): MathFunc {
console.log(`${this._param}`)
return C.of(this._param)
}
toString(): string {
return `${this._param}`
}
apply(x?: number): any {
return this.value
}
d(): MathFunc {
return C.of(0)
}
static of(constant: number): MathFunc {
return new C(constant)
}
}
//数乘,f(x)=a*x
class scalar extends MathFunc {
_param: number
_Op: Function
protected constructor(a: number) {
super()
const scalar = (a: number) => (x: number) => a * x
this._param = a
this._Op = scalar(a)
}
get op(): any {
throw new Error("Method not implemented.")
}
show(): MathFunc {
console.log(`${this._param}*x`)
return scalar.of(this._param)
}
toString(): string {
return `${this._param}*x`
}
apply(x: number) {
return this._Op(x)
}
d(): MathFunc {
return C.of(this._param)
}
static of(a: number): MathFunc {
return new scalar(a)
}
}
//以a为幂的关于x的函数,f(x)=x^a
class power extends MathFunc {
_param: number
_Op: Function
static of(a: number): MathFunc {
if (1 === a) {
//一次方返回一倍数乘
return scalar.of(1)
} else if (0 === a) {
//0次方返回数字1
return C.of(1)
} else {
return new power(a)
}
}
protected constructor(a: number) {
super()
const power = (a: number) => (x: number) => x ** a
this._Op = power(a)
this._param = a
}
apply(x: number) {
return this._Op(x)
}
show() {
console.log(this.toString())
return power.of(this._param)
}
toString(): string {
return `pow(x,${this._param})`
}
d(): MathFunc {
if (this._param === 2) {
//2次方求导返回2倍数乘,1次方和0次方已经在初始化时转变成标量数乘或常量了
return scalar.of(2)
} else {
return Mul.of(C.of(this._param), power.of((this._param) - 1))
}
}
}
//ln(x)函数
class ln extends MathFunc {
_param: null = null
_Op: Function
protected constructor() {
super()
const ln = (x: number) =>
sum_sequence(
(n: number) => (x: number) =>
((-1) ** n) * ((x - 1) ** (n + 1) / (n + 1))
)
(500)
(x)
this._Op = ln
}
static of(): MathFunc {
return new ln()
}
apply(x: number) {
return this._Op(x)
}
show() {
console.log(this.toString())
return ln.of()
}
toString(): string {
return `ln(x)`
}
//求导 (ln(X))'=x^(-1)
d(): MathFunc {
return power.of(-1)
}
}
//实现exp函数,即e^x
class exp extends MathFunc {
_Op:Function
protected constructor() {
super()
//实现exp函数,即e^x
const exp = (x: number) =>
sum_sequence(
(n: number) => (x: number) =>
(x ** n) / factorial(n)//函数
)
(50)//要计算的项数上限
(x)//自变量
this._Op=exp
}
of():MathFunc{
return new exp()
}
apply(x: number): number {
return this._Op(x)
}
get param(): number {
return e()
}
}
/* 下面是连接函子 */
//函数相加 f(x)=f1(x)+f2(x)
class Add extends MathFunc {
_left: MathFunc
_right: MathFunc
protected constructor(left: MathFunc, right: MathFunc) {
super()
this._left = left
this._right = right
}
static of(left: MathFunc, right: MathFunc): MathFunc {
if (left.type === "C" && right.type === "C") {
//如果左右都是常数,直接返回常数函子
return C.of(left.apply() + right.apply())
} else {
//@ts-ignore
return new Add(left, right)
}
}
get op(): any {
throw new Error("Method not implemented.")
}
show(): MathFunc {
console.log(this.toString())
return Add.of(this._left, this._right)
}
toString(): string {
return this._left.toString() + "+" + this._right.toString()
}
//加法函数值等于两个子函数分别求值再相加
apply(x:number) {
return this._left.apply(x)+this._right.apply(x)
}
d(): MathFunc {
return Add.of(this._left.d(), this._right.d())
}
}
//相乘关系f(x)=f1(x)*f2(x)
class Mul extends MathFunc {
_left: MathFunc
_right: MathFunc
protected constructor(left: MathFunc, right: MathFunc) {
super()
this._left = left
this._right = right
}
show(): MathFunc {
console.log(this.toString())
return Mul.of(this._left, this._right)
}
toString(): string {
return "(" + this._left.toString() + ")*(" + this._right.toString() + ")"
}
static of(left: MathFunc, right: MathFunc): MathFunc {
if (left.type === "C" && right.type === "C") {
//如果左右都是常数,直接返回常数函子
return C.of(left.apply() * right.apply())
}else if (left.type === "C" || right.type === "C") {
if(left.param===0||right.param===0) return C.of(0)
else if(left.param===1) return right
else if (right.param===1) return left
else return new Mul(left, right)
}
else {
return new Mul(left, right)
}
}
//乘法函数的值等于两个函数分别求值再相乘
apply(x: number): number {
return this._left.apply(x)*this._right.apply(x)
}
//(fg)′= f′g + fg′
d(): MathFunc {
return Add.of(Mul.of(this._left.d(), this._right), Mul.of(this._left, this._right.d()))
}
}
//包含关系f(x)=f1(f2(x))
class Pipe extends MathFunc {
_outer: MathFunc
_inner: MathFunc
protected constructor(outer: MathFunc, inner: MathFunc) {
super()
this._outer = outer
this._inner = inner
}
show(): MathFunc {
console.log(this.toString())
return Pipe.of(this._outer, this._inner)
}
toString(): string {
//把外层函数的x替换成内层函数
return this._outer.toString().split("x").join("(" + this._inner.toString() + ")")
}
//在外侧再包裹一层函子
//为了维护代码风格,关闭此方法
// map(outer: MathFunc) {
// return Pipe.of(outer, Pipe.of(this._outer, this._inner))
// }
//求导,f(g),g=g(x),df/dx=(df/dg)*(dg/dx)
d(): MathFunc {
return Mul.of(this._outer.d(), this._inner.d())
}
static of(outer: MathFunc, inner: MathFunc): MathFunc {
if (outer.type==="C") return inner //如果外层是一个常数,直接丢弃内层即可
else if(inner.type==="C") return C.of(outer.apply(inner.apply()))//如果内层函数是常数,直接计算并返回数值
else return new Pipe(outer, inner)
}
//复合函数的值,先计算内部函数的值,再带入结果计算外部函数的值
apply(x: number): number {
return this._outer.apply(this._inner.apply(x))
}
}
let F1=Mul.of(scalar.of(5),C.of(2)).show()
let F2=Add.of(C.of(5),scalar.of(8)).show()
let F3=Pipe.of(F1,F2).show()
F1.d().show()
F1.d().d().show()
F3.d().show()
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
TypeScript
1
https://gitee.com/Mercator/differential.git
git@gitee.com:Mercator/differential.git
Mercator
differential
微分
master

搜索帮助