3个版本

0.1.2 2023年6月10日
0.1.1 2023年6月10日
0.1.0 2023年6月3日

#421 in 嵌入式开发

每月21次下载

Apache-2.0

91KB
2.5K SLoC

嵌入式科学计算的数学库

注意:此库尚未准备好用于任何有限用途。如果需要合适的数学库,请使用num-traits、num-complex和nalgebra。

此仓库包含Talrost,这是一个实验性库,旨在提供一个符合人体工程学、便捷且适用于嵌入式环境的数值塔,它存在于Rust对特化和类型强制转换的限制边缘。可能需要libm,当前需要std

使用示例

警告:大多数功能远未得到正确实现。不要期望现在能够使用此库。

代数特性

松散选择的代数结构

  • trait Element: Sized + Copy + Clone + core::fmt::Display + Debug{}
  • trait Monoid: Element + Add + AddAssign{ const ZERO: Self; }
  • trait Group: Monoid + Sub + SubAssign + Neg{ fn Neg(self) -> Self; }
  • trait Semiring: Monoid + Mul + MulAssign{ const ONE: Self; }
  • trait Ring: Group + Semiring{}
  • trait Field: Ring + Div + DivAssign{ fn recip(self) -> Self; }

然后组合它们来构建相应的数值塔

  • trait Natural: Semiring + PartialOrd + PartialEq{ ... } //无符号整数
  • trait Integer: Ring + Natural{ ... } //有符号整数
  • trait Float: Field + Natural{ ... } //标准浮点数和(目前)复数

复数算术

实现了Float,作为c32c64暴露,与f32f64具有类似的基础互操作性。

use talrost::complex::*;

let a: f64 = 0.25;
let mut b: c64 = (0.75, 1.0).into();
b += a;
b /= c64::new([0.5, 0.5]);
assert_eq!(b, "2 + 0i".into());

多项式

支持$\mathbb{R}$(工作)和$\mathbb{C}$(损坏)中的多项式。

use talrost::polynomial::*;
let tol = f64::EPSILON;

// p(x) = 1x^3 + 5x^2 + -14x + 0, has roots -7, 0, 2
let p = Polynomial::new([1.0, 5.0, -14.0, 0.0]);

let y = p.eval(4.0);
assert_eq!(y, 88.0); // p(4) = 88

let r = solvers::yuksel::roots_cubic(&p, tol);
assert_eq!(r.len(), 3); // count roots
assert_eq!(r, [-7.0, 0.0, 2.0]); // verify ordered roots

矢量和矩阵

支持在$\mathbb{R^n}$和$\mathbb{C^n}$上使用矢量,并明确转换为行和列矩阵类型。

use talrost::{vector::*, matrix::*};

let v1 = Vector::new([1., 2., 3.]);
let v2 = Vector::new([4., 5., 6.]);

assert_eq!(v1.magnitude(), 14_f64.sqrt());
assert_eq!(v1.normalize().magnitude(), 1.);
assert_eq!(v1.row(), Matrix::new([[1., 2., 3.]]));
assert_eq!(v1.column(), Matrix::new([[1.], [2.], [3.]]));

assert_eq!(v1 + v2, Vector::new([5., 7., 9.]));
assert_eq!(v1 - v2, Vector::new([-3., -3., -3.]));
assert_eq!(v1 * 2., Vector::new([2., 4., 6.]));
assert_eq!(2. * v2, Vector::new([8., 10., 12.]));

let vec_real = Vector::new([1.0, 2.0]);
let vec_complex = Vector::new([c64::new(1.0, 0.0), c64::new(2.0, 0.0)]);

assert_eq!(vec_real.magnitude(), 5_f64.sqrt());
assert_eq!(vec_complex.magnitude(), 5_f64.sqrt().into());

支持在$\mathbb{R^n}$和$\mathbb{C^n}$上使用$M \times N$矩阵。

use talrost::matrix::*;

let x = Matrix::<f32, 2, 3>::new([[1., 2.], [3., 4.], [5., 6.]]);
assert_eq!((x + Matrix::ZERO), x);

let y = Matrix::new([[1., 2.], [3., 4.]]);
assert_eq!((y * Matrix::<_, 2, _>::IDENTITY).determinant(), -2.0);

let a = Matrix::new([
    [1., 2., 3., 4.],
    [5., 6., 7., 8.],
    [9., 10., 11., 12.],
    [13., 14., 15., 16.],
]);
let b = Matrix::new([
    [17., 18., 19., 20.],
    [21., 22., 23., 24.],
    [25., 26., 27., 28.],
    [29., 30., 31., 32.],
]);
let c = Matrix::new([
    [250., 260., 270., 280.],
    [618., 644., 670., 696.],
    [986., 1028., 1070., 1112.],
    [1354., 1412., 1470., 1528.],
]);
assert_eq!(a * b, c);

无运行时依赖