2个版本
0.1.1 | 2024年2月14日 |
---|---|
0.1.0 | 2024年2月14日 |
#232 in 数学
200KB
5K SLoC
艾希
一个用于操作和分析符号表达式的库。这个名字在德语中意味着“橡树”,因为艾希中的符号表达式被表示为树。
用法
创建表达式
deftree
宏在定义使用s表达式(如LISP)的表达式时非常有用。你可以创建一个表达式并按如下方式将其打印为LaTex
let tree = deftree!(/ (+ (* k x) (* k y)) (+ x y)).unwrap();
println!("$`{}`$\n", tree.to_latex());
$\dfrac{{{k}.{x}} + {{{k}.{y}}}}{{x} + {y}}
$
简化表达式
你可以使用reduce
函数简化上述树表达式,如下所示
let steps = reduce(tree, 8).unwrap();
for step in steps {
println!("$`= {}`$\n", step.to_latex());
}
$= \dfrac{{{k}.{({x} + {y}\right)}}}{{x} + {y}}
$
$= {k}.{\dfrac{{x} + {y}}{{x} + {y}}}
$
$= k
$
Eiche还可以简化更复杂的表达式。以下表达式代表标准化向量的长度
$\sqrt{{{\left(\dfrac{x}{\sqrt{{{x}^{2}} + {{y}^{2}}}}\right)}^{2}} + {{\left(\dfrac{y}{\sqrt{{{x}^{2}} + {{y}^{2}}}}\right)}^{2}}}
$
赋值运算符 = \sqrt{{{\left(\dfrac{x}}{{{x}^{2}} + {{y}^{2}}}\right)}^{2}} + {\dfrac{{y}^{2}}{{\left(\sqrt{{{x}^{2}} + {{y}^{2}}}\right)}^{2}}}}
$
$$= \sqrt{{\dfrac{{x}^{2}}}{{\left(\sqrt{{{x}^{2}} + {{y}^{2}}}\right)}^{2}}} + {\dfrac{{y}^{2}}}{{\left(\sqrt{{{x}^{2}} + {{y}^{2}}}\right)}^{2}}}}
$$
$$= \sqrt{\dfrac{{{x}^{2}} + {{y}^{2}}}{{\left(\sqrt{{{x}^{2}} + {{y}^{2}}}\right)}^{2}}}
$$
$= \sqrt{\dfrac{{{x}^{2}} + {{y}^{2}}}{{{x}^{2}} + {{y}^{2}}}}
$
$= 1
$
求导
Eiche可以符号地对一个或多个自变量求表达式的导数。下面的例子定义了一个两个变量x和y的函数
let tree = deftree!(- (+ (pow x 3) (pow y 3)) 5).unwrap();
println!("$`f(x, y) = {}`$\n", tree.to_latex(
$f(x, y) = {\left({{x}^{3}} + {{y}^{3}}\right)} - {5}
$
您可以对该函数关于x和y求导,以生成一个包含偏导数的行向量
$\begin{bmatrix}{{{x}^{3}}.{\left({3}.{\dfrac{1}{x}}\right)}} & {{{y}^{3}}.{\left({3}.{\dfrac{1}{y}}\right)}}\end{bmatrix}
$
您可以对结果再次分别对x和y进行求导,以获得Hessian矩阵
let hessian = deriv.symbolic_deriv("xy").unwrap();
println!("$`{}`$\n", hessian.to_latex());
$\begin{bmatrix}{{{{x}^{3}}.{\left({3}.{\dfrac{-1}{{x}^{2}}}\right)}} + {{\left({3}.{\dfrac{1}{x}}\right)}.{\left({{x}^{3}}.{\left({3}.{\dfrac{1}{x}}\right)}\right)}}} & {0} \\ {0} & {{{{y}^{3}}.{\left({3}.{\dfrac{-1}{{y}^{2}}}\right)}} + {{\left({3}.{\dfrac{1}{y}}\right)}.{\left({{y}^{3}}.{\left({3}.{\dfrac{1}{y}}\right)}\right)}}}\end{bmatrix}
$
这个关于导数和Hessian的表达式过于复杂。这是由于Eiche在求导表达式时应用链式法则的方式。让我们使用reduce
函数来简化
let steps = reduce(hessian, 256).unwrap();
// The last step is the most simplified form:
println!("$`{}`$\n", steps.last().unwrap().to_latex());
$\begin{bmatrix}{{x}}.{{6}}} & {{0}} \\ {{0}} & {{{y}}}.{{6}}}}{bmatrix}
$
依赖项
~320KB