core API
根包 Luna-Flow/luna-complex 定义了 Complex[T],即任意标量类型 T 上的复数 ,并提供构造、原地修改、共轭、算术运算符以及 luna-generic 结构 trait。它不包含解析函数;这些函数位于 float_backend。这些实例背后的代数原理见核心设计。
源码:src/complex.mbt、src/complex_traits.mbt 和 src/extends.mbt。
导入
import {
"Luna-Flow/luna-complex" @complex,
}
示例使用别名 @complex。
类型
Complex
具有实部 re 和虚部 im 的复数。
pub(all) struct Complex[T] {
mut re : T
mut im : T
} derive(Eq, @debug.Debug)
其值为 ,其中 。两个字段都是公开且可变的,且该结构体为 pub(all),因此包外代码可以读取、写入它,并用记录字面量构造它。Complex[T] 是引用类型:绑定到同一个值的两个变量能看到彼此的修改。
derive(Eq) 使用 T 的相等性比较两个部分(对于 Double,0.0 == -0.0,且 NaN 不等于自身)。derive(Debug) 打印记录形式 { re: …, im: … }。
构造与修改
Complex::new
构造 。
pub fn[T] Complex::new(T, T) -> Complex[T]
Complex::set
原地覆盖两个部分。
pub fn[T] Complex::set(Complex[T], T, T) -> Unit
Complex::set_re
原地覆盖实部。
pub fn[T] Complex::set_re(Complex[T], T) -> Unit
Complex::set_im
原地覆盖虚部。
pub fn[T] Complex::set_im(Complex[T], T) -> Unit
test "construct and mutate" {
let z = @complex.Complex::new(1.0, 2.0)
assert_eq(z.re, 1.0)
z.set(3.0, 4.0)
z.set_im(-1.0)
assert_eq(z, @complex.Complex::new(3.0, -1.0))
}
单位元
Complex::zero
返回 。
pub fn[T : @luna-generic.Zero] Complex::zero() -> Complex[T]
Complex::one
返回 。
pub fn[T : @luna-generic.One + @luna-generic.Zero] Complex::one() -> Complex[T]
两者分别是 Zero 和 One 实例的提升方法。
算术
每种运算既可作为运算符使用,也可作为提升方法使用。
| 项目 | 运算符 | 结果 | 对 T 的约束 |
|---|---|---|---|
Complex::add | z + w | Add | |
Complex::sub | z - w | Sub | |
Complex::neg | -z | Neg | |
Complex::mul | z * w | Mul + Add + Sub | |
Complex::div | z / w | Field |
此处 ,。
Complex::add
逐分量相加。
pub fn[T : Add] Complex::add(Complex[T], Complex[T]) -> Complex[T]
pub impl[T : Add] Add for Complex[T]
Complex::sub
逐分量相减。
pub fn[T : Sub] Complex::sub(Complex[T], Complex[T]) -> Complex[T]
pub impl[T : Sub] Sub for Complex[T]
Complex::neg
对两个部分取负。
pub fn[T : Neg] Complex::neg(Complex[T]) -> Complex[T]
pub impl[T : Neg] Neg for Complex[T]
Complex::mul
按 相乘,使用四次乘法。
pub fn[T : Mul + Add + Sub] Complex::mul(Complex[T], Complex[T]) -> Complex[T]
pub impl[T : Mul + Add + Sub] Mul for Complex[T]
Complex::div
通过乘以模平方的倒数来做除法。
pub fn[T : @luna-generic.Field] Complex::div(Complex[T], Complex[T]) -> Complex[T]
pub impl[T : @luna-generic.Field] Div for Complex[T]
它先计算 ,再计算 Inverse::inv(n),并用它乘以 的两个部分。该公式未做缩放:对于 Double,当 时 上溢,当 时下溢;而当 为零(包括下溢导致为零)时,Double 的 Inverse::inv 会以 Double::inv: division by zero 中止。稳健的浮点除法请使用 @fb.div。
test "complex arithmetic" {
let z = @complex.Complex::new(1.0, 2.0)
let w = @complex.Complex::new(3.0, -1.0)
assert_eq(z + w, @complex.Complex::new(4.0, 1.0))
assert_eq(z - w, @complex.Complex::new(-2.0, 3.0))
assert_eq(z * w, @complex.Complex::new(5.0, 5.0))
assert_eq(z * w / w, z)
assert_eq(-z, @complex.Complex::new(-1.0, -2.0))
}
共轭与逆
Complex::conjugate
返回 。
pub fn[T : Neg] Complex::conjugate(Complex[T]) -> Complex[T]
pub impl[T : Neg] @luna-generic.Conjugate for Complex[T]
Complex::inv
返回 。
pub fn[T : @luna-generic.Field] Complex::inv(Complex[T]) -> Complex[T]
pub impl[T : @luna-generic.Field] @luna-generic.Inverse for Complex[T]
它采用与 Complex::div 相同的未缩放公式,在模为零时同样会中止。
test "conjugate and inverse" {
let z = @complex.Complex::new(3.0, 4.0)
assert_eq(z.conjugate(), @complex.Complex::new(3.0, -4.0))
assert_eq(z * z.conjugate(), @complex.Complex::new(25.0, 0.0))
assert_eq(z.inv(), @complex.Complex::new(0.12, -0.16))
}
相等性与文本
Complex::equal
比较两个部分;是派生的 Eq 的提升方法。建议使用 ==。
pub fn[T : Eq] Complex::equal(Complex[T], Complex[T]) -> Bool
Complex::to_string
使用 T 的 Show 将 格式化为 "<re> + <im>i"。
pub fn[T : Show] Complex::to_string(Complex[T]) -> String
pub impl[T : Show] Show for Complex[T]
虚部的符号由 T 打印,因此 打印为 1 + -2i。字符串插值 "\{z}" 使用相同的文本。
test "text form" {
inspect(@complex.Complex::new(1.5, -2.0), content="1.5 + -2i")
debug_inspect(@complex.Complex::new(1, 2), content="{ re: 1, im: 2 }")
}
结构实例
Complex[T] 在下列约束下实现了 luna-generic 的结构 trait。核心设计推导了每条定律。
| 实例 | 对 T 的约束 |
|---|---|
Zero | Zero |
One | One + Zero |
AddMonoid | Add + Zero |
AddGroup | Add + Zero + Neg + Sub |
MulMonoid | Ring |
Semiring | Ring |
Ring | Ring |
Inverse | Field |
MulGroup | Field |
Field | Field |
Conjugate | Neg |
fn[T : @lg.Field] average(a : T, b : T) -> T {
let two = @lg.One::one() + @lg.One::one()
(a + b) / two
}
test "generic field code accepts complex numbers" {
let m = average(@complex.Complex::new(1.0, 2.0), @complex.Complex::new(3.0, 0.0))
assert_eq(m, @complex.Complex::new(2.0, 1.0))
}
已弃用
这些方法形式来自 trait 实例,并在接口文件中隐藏;在包外使用时会发出警告。
| 已弃用的方法 | 替代方案 |
|---|---|
z.not_equal(w) | z != w |
z.output(logger) | z.to_string() 或 "\{z}" |
z.to_repr() | Repr(z) 或 @debug.Debug::to_repr(z) |