float_backend API

float_backend 包提供 Complex[Double] 的解析函数:模与辐角、除法、开方、指数与对数、幂,以及三角函数、双曲函数及其反函数。它还为浮点标量定义了三个能力 trait,并为 Float 和 Double 实现了它们。公式与分支切割线的推导见 float_backend 设计。

源码:src/float_backend/(float_backend_traits.mbt、complex_elementary.mbt、complex_trigonometric.mbt、complex_hyperbolic.mbt)。

导入

import {
  "Luna-Flow/luna-complex/float_backend" @fb,
}

示例中用 @fb 表示本包,用 @complex 表示根包。所有函数都是作用于 Complex[Double] 的自由函数(MoonBit 不允许一个包为另一个包的类型添加方法)。

约定

  • 主值。 多值函数返回某个固定分支上的一个值,各函数分别说明。arg 返回 (−π,π](-\pi, \pi] 内的值,负实轴上除外(见下方警告)。
  • 特殊值。 NaN 和无穷大仅在注明之处(div、atan、atanh、acosh、abs_log、pow)做专门处理;其他地方它们通过普通 Double 算术传播,可能产生 NaN 分量。
  • 倒数类函数在极点处中止。 sec、csc、cot、sech、csch、coth、asec、acsc、asech、acsch、acoth 以及 pow 的指数 −1-1 都使用 Complex::inv,它在模为零时以 Double::inv: division by zero 中止。

能力 trait

FloatingAnalyticScalar

解析后端对其实数标量所需的代数与解析能力。

pub(open) trait FloatingAnalyticScalar : @luna-generic.Field + @luna-generic.Num + Compare + @arithmetic.Constants + @arithmetic.Sqrt + @arithmetic.Exponential + @arithmetic.Logarithmic + @arithmetic.Trigonometric + @arithmetic.InverseTrigonometric + @arithmetic.Hyperbolic + @arithmetic.InverseHyperbolic {
}
pub impl FloatingAnalyticScalar for Float
pub impl FloatingAnalyticScalar for Double

它本身没有方法:它只是为 luna-generic 与 arithmetic trait 的组合命名。

FloatingSpecialValues

IEEE 754 特殊值及其判定。

pub(open) trait FloatingSpecialValues {
  fn nan() -> Self
  fn infinity() -> Self
  fn neg_infinity() -> Self
  fn is_nan(Self) -> Bool
  fn is_inf(Self) -> Bool
  fn is_pos_inf(Self) -> Bool
  fn is_neg_inf(Self) -> Bool
  fn is_negative_zero(Self) -> Bool
}
pub impl FloatingSpecialValues for Float
pub impl FloatingSpecialValues for Double

is_negative_zero(x) 即 is_neg_inf(1.0 / x),因此它恰好对 −0-0 为真。

FloatingBackendScalar

数值稳定算法在上述两个 trait 之上所用的基本操作。

pub(open) trait FloatingBackendScalar : FloatingAnalyticScalar + FloatingSpecialValues {
  fn from_double(Double) -> Self
  fn trunc(Self) -> Self
  fn to_int(Self) -> Int
  fn hypot(Self, Self) -> Self
  fn log1p(Self) -> Self
}
pub impl FloatingBackendScalar for Float
pub impl FloatingBackendScalar for Double
方法含义DoubleFloat
from_double转换一个 Double 常量恒等Float::from_double
trunc向零舍入Double::truncFloat::trunc
to_int转换为 IntDouble::to_intFloat::to_int
hypot不会上溢的 x2+y2\sqrt{x^2 + y^2}@math.hypot@math.hypotf
log1pln⁡(1+x)\ln(1 + x)@math.log1pln(1.0 + x)

Float 的 log1p 是直接公式,当 ∣x∣≪1|x| \ll 1 时会损失相对精度。本包目前还没有对这些 trait 泛型的公开函数;下面的 Complex[Double] 函数直接调用 Double 的基本操作。

fn[T : @fb.FloatingSpecialValues] classify(x : T) -> String {
  if @fb.FloatingSpecialValues::is_nan(x) {
    "nan"
  } else if @fb.FloatingSpecialValues::is_inf(x) {
    "inf"
  } else if @fb.FloatingSpecialValues::is_negative_zero(x) {
    "-0"
  } else {
    "finite"
  }
}

test "special values" {
  assert_eq(classify(-0.0), "-0")
  assert_eq(classify(@double.infinity), "inf")
  let nan : Float = @fb.FloatingSpecialValues::nan()
  assert_eq(classify(nan), "nan")
  assert_eq(@fb.FloatingBackendScalar::hypot(3.0, 4.0), 5.0)
}

重新导出的类型

Complex

@fb.Complex 就是 @complex.Complex;参见核心 API。

pub using @luna-complex {type Complex}

构造与存储

polar

构造 reiθ=rcos⁡θ+i rsin⁡θr e^{i\theta} = r\cos\theta + i\,r\sin\theta。

pub fn polar(Double, Double) -> Complex[Double]

不做规范化:接受负的 rr 和任意实数 θ\theta。

pack

将 zz 写入交错缓冲区 [re0, im0, re1, im1, …] 中复数下标为 offset 的位置。

pub fn pack(Complex[Double], Array[Double], Int) -> Unit

native_pack

将实部和虚部写入交错缓冲区。

pub fn native_pack(Double, Double, Array[Double], Int) -> Unit

缓冲区长度必须为偶数。如果 offset 等于复数条目数(arr.length() / 2),则追加这一对值;否则覆盖第 offset 个条目。长度为奇数时以 native_pack: buffer length must be even 中止,偏移量超出 0..=arr.length() / 2 时以 native_pack: offset out of bounds 中止。

test "polar and packing" {
  let z = @fb.polar(2.0, 0.0)
  assert_eq(z, @complex.Complex::new(2.0, 0.0))
  let buf : Array[Double] = []
  @fb.pack(z, buf, 0)
  @fb.native_pack(3.0, 4.0, buf, 1)
  @fb.native_pack(5.0, 6.0, buf, 0)
  assert_eq(buf, [5.0, 6.0, 3.0, 4.0])
}

模与辐角

abs

用 hypot 返回 ∣z∣=x2+y2|z| = \sqrt{x^2 + y^2},中间过程不会上溢或下溢。

pub fn abs(Complex[Double]) -> Double

abs_sqr

返回 ∣z∣2|z|^2,按 m2((x/m)2+(y/m)2)m^2\big((x/m)^2 + (y/m)^2\big) 计算,其中 m=max⁡(∣x∣,∣y∣)m = \max(|x|, |y|)。

pub fn abs_sqr(Complex[Double]) -> Double

缩放避免了平方项的虚假下溢;当 ∣z∣2|z|^2 超出 Double 范围时,结果本身会上溢为无穷大。00 映射为 00。

abs_log

按 ln⁡m+12ln⁡(1+t2)\ln m + \tfrac12\ln(1 + t^2) 返回 ln⁡∣z∣\ln|z|,其中 m=max⁡(∣x∣,∣y∣)m = \max(|x|,|y|),t=min⁡/max⁡t = \min/\max。

pub fn abs_log(Complex[Double]) -> Double

对每个有限非零的 zz,结果都是有限的,即使 ∣z∣|z| 本身会上溢。abs_log(0) 为 −∞-\infty。

arg

返回满足 z=∣z∣eiθz = |z| e^{i\theta} 的辐角 θ\theta。

pub fn arg(Complex[Double]) -> Double
输入结果
z=0z = 0(任一零符号)00
y=±0y = \pm 0, x<0x < 02π2\pi(见上方警告)
其他情况atan2(y, x) ∈(−π,π)\in (-\pi, \pi)
test "modulus and argument" {
  let z = @complex.Complex::new(3.0, 4.0)
  assert_eq(@fb.abs(z), 5.0)
  assert_eq(@fb.abs_sqr(z), 25.0)
  assert_eq(@fb.arg(@complex.Complex::new(0.0, 1.0)), @math.PI / 2.0)
  let huge = @complex.Complex::new(1.0e300, 1.0e300)
  assert_true(@fb.abs_sqr(huge).is_inf())
  assert_true(@fb.abs_log(huge) < 692.0) // ln(sqrt 2 * 1e300) is about 691.1
}

除法

div

使用 Smith 缩放和 IEEE 特殊值处理计算 z/wz / w。

pub fn div(Complex[Double], Complex[Double]) -> Complex[Double]

对于有限的 ww,它先除以 ∣c∣,∣d∣|c|, |d| 中较大者(当 ∣c∣≥∣d∣|c| \ge |d| 时取 r=d/cr = d/c):

a+bic+di=(a+br)+(b−ar) ic (1+r2),\frac{a + bi}{c + di} = \frac{(a + b r) + (b - a r)\,i}{c\,(1 + r^2)} ,

因此不会形成 cc 或 dd 的平方。当 zz 没有 NaN 分量而 ww 有无穷分量时,结果由无穷大的符号算出:有限的 zz 得到 ±0\pm 0 分量,无穷的 zz 得到符号模式之商。除以 0+0i0 + 0i 会产生无穷大或 NaN(不会中止)。

test "robust division" {
  let one = @complex.Complex::new(1.0, 0.0)
  let tiny = @complex.Complex::new(1.0e-300, 1.0e-300)
  let q = @fb.div(one, tiny)
  assert_true(q.re > 4.9e299 && q.im < -4.9e299)
  let z = @fb.div(@complex.Complex::new(1.0, 2.0), @complex.Complex::new(@double.infinity, 0.0))
  assert_eq(z.re, 0.0)
}

开方

sqrt

返回主平方根:Re⁡z≥0\operatorname{Re}\sqrt z \ge 0,分支切割线沿负实轴。

pub fn sqrt(Complex[Double]) -> Complex[Double]

它以缩放形式计算 w=(∣x∣+∣z∣)/2w = \sqrt{(|x| + |z|)/2},当 x≥0x \ge 0 时返回 w+y2wiw + \frac{y}{2w} i,当 x<0x < 0 时返回 ∣y∣2w±w i\frac{|y|}{2w} \pm w\,i(符号与 yy 相同)。在割线上(y=±0y = \pm 0,x<0x < 0),对两种零符号结果都是 +∣x∣ i+\sqrt{|x|}\,i。sqrt(0) 为 00。

sqrt_real

实数的平方根,以复数表示:x≥0x \ge 0 时为 x\sqrt x,x<0x < 0 时为 i−xi\sqrt{-x}。

pub fn sqrt_real(Double) -> Complex[Double]
test "square roots" {
  assert_eq(@fb.sqrt(@complex.Complex::new(-3.0, 4.0)), @complex.Complex::new(1.0, 2.0))
  assert_eq(@fb.sqrt(@complex.Complex::new(-4.0, 0.0)), @complex.Complex::new(0.0, 2.0))
  assert_eq(@fb.sqrt_real(-9.0), @complex.Complex::new(0.0, 3.0))
}

指数与对数

exp

返回 ez=ex(cos⁡y+isin⁡y)e^z = e^x(\cos y + i\sin y)。

pub fn exp(Complex[Double]) -> Complex[Double]

由于先计算 exe^x,当 x>709.78x > 709.78 时它会上溢,即使结果的某个分量本应有限;并且 exp(710 + 0i) 的虚部为 NaN(∞⋅0\infty \cdot 0)。

log

用 abs_log 和 arg 返回 ln⁡∣z∣+iarg⁡z\ln|z| + i\arg z。

pub fn log(Complex[Double]) -> Complex[Double]

虚部遵循 arg,因此在负实轴上为 2π2\pi。log(0) 为 −∞+0i-\infty + 0i。

log_10

返回 log⁡10z=log⁡z/ln⁡10\log_{10} z = \log z / \ln 10。

pub fn log_10(Complex[Double]) -> Complex[Double]

log_b

返回 log⁡bz=log⁡z/log⁡b\log_b z = \log z / \log b,除法使用 div。

pub fn log_b(Complex[Double], Complex[Double]) -> Complex[Double]
test "exponential and logarithm" {
  let z = @complex.Complex::new(1.0, 2.0)
  let back = @fb.exp(@fb.log(z))
  assert_true((back.re - 1.0).abs() < 1.0e-12 && (back.im - 2.0).abs() < 1.0e-12)
  let l = @fb.log_10(@complex.Complex::new(100.0, 0.0))
  assert_true((l.re - 2.0).abs() < 1.0e-15)
}

幂

pow

返回 zwz^w。

pub fn pow(Complex[Double], Complex[Double]) -> Complex[Double]

依次尝试以下情形:

情形结果
z=0z = 0, w=0w = 011
z=0z = 0,ww 为正实数00
z=0z = 0,其他情况NaN + NaNii
w=1w = 1zz
w=−1w = -1z.inv()(z=0z = 0 时中止,但前面几行已排除该情况)
ww 为实整数,∣w∣≤231−1\lvert w\rvert \le 2^{31} - 1二进制快速幂;负指数先对 zz 求逆
其他情况极坐标形式的 ewlog⁡ze^{w\log z}

极坐标形式先计算 ρ=eRe⁡wln⁡∣z∣−Im⁡warg⁡z\rho = e^{\operatorname{Re} w \ln|z| - \operatorname{Im} w \arg z} 与 β=Re⁡warg⁡z+Im⁡wln⁡∣z∣\beta = \operatorname{Re} w \arg z + \operatorname{Im} w \ln|z|,再返回 ρ(cos⁡β+isin⁡β)\rho(\cos\beta + i\sin\beta)。

pow_real

对实指数 pp 返回 zpz^p,零、整数与极坐标情形与 pow 相同。

pub fn pow_real(Complex[Double], Double) -> Complex[Double]
test "powers" {
  let z = @complex.Complex::new(1.0, 2.0)
  assert_eq(@fb.pow_real(z, 2.0), @complex.Complex::new(-3.0, 4.0))
  let r = @fb.pow(@complex.Complex::new(0.0, 1.0), @complex.Complex::new(0.5, 0.0))
  assert_true((r.re - 0.7071067811865476).abs() < 1.0e-15)
  assert_true(@fb.pow_real(@complex.Complex::new(0.0, 0.0), -1.0).re.is_nan())
}

标量操作数

op_bin_re

以实数 x+0ix + 0i 作为第二个操作数应用二元复函数。

pub fn op_bin_re(Complex[Double], Double, (Complex[Double], Complex[Double]) -> Complex[Double]) -> Complex[Double]

op_bin_im

以纯虚数 0+yi0 + yi 作为第二个操作数应用二元复函数。

pub fn op_bin_im(Complex[Double], Double, (Complex[Double], Complex[Double]) -> Complex[Double]) -> Complex[Double]
test "scalar operands" {
  let z = @complex.Complex::new(1.0, 2.0)
  assert_eq(@fb.op_bin_re(z, 2.0, @fb.div), @complex.Complex::new(0.5, 1.0))
  assert_eq(@fb.op_bin_im(z, 1.0, (a, b) => a * b), @complex.Complex::new(-2.0, 1.0))
}

三角函数

sin

返回 sin⁡z=sin⁡xcosh⁡y+icos⁡xsinh⁡y\sin z = \sin x\cosh y + i\cos x\sinh y;当 y=0y = 0 严格成立时,返回实数 sin⁡x\sin x。

pub fn sin(Complex[Double]) -> Complex[Double]

cos

返回 cos⁡z=cos⁡xcosh⁡y−isin⁡xsinh⁡y\cos z = \cos x\cosh y - i\sin x\sinh y;当 y=0y = 0 严格成立时,返回实数 cos⁡x\cos x。

pub fn cos(Complex[Double]) -> Complex[Double]

tan

返回 tan⁡z\tan z。

pub fn tan(Complex[Double]) -> Complex[Double]

当 ∣y∣<1|y| < 1 时使用 sin⁡2x+isinh⁡2y2(cos⁡2x+sinh⁡2y)\dfrac{\sin 2x + i\sinh 2y}{2(\cos^2 x + \sinh^2 y)};当 ∣y∣≥1|y| \ge 1 时使用以 e−2∣y∣e^{-2|y|} 缩放的形式,它趋于 ±i\pm i 而不会上溢(见设计文档)。

sec

返回 1/cos⁡z1/\cos z;在 cos⁡z=0\cos z = 0 处中止。

pub fn sec(Complex[Double]) -> Complex[Double]

csc

返回 1/sin⁡z1/\sin z;在 z=kπz = k\pi 处中止。

pub fn csc(Complex[Double]) -> Complex[Double]

cot

返回 1/tan⁡z1/\tan z;在 z=kπz = k\pi 处中止。

pub fn cot(Complex[Double]) -> Complex[Double]
test "trigonometric functions" {
  let z = @complex.Complex::new(1.0, 1.0)
  let s = @fb.sin(z)
  let c = @fb.cos(z)
  let one = s * s + c * c
  assert_true((one.re - 1.0).abs() < 1.0e-15 && one.im.abs() < 1.0e-15)
  let t = @fb.tan(@complex.Complex::new(1.0, 100.0))
  assert_eq(t.im, 1.0)
}

反三角函数

asin

返回主值反正弦,分支切割线位于实轴上 [−1,1][-1, 1] 之外;Re⁡\operatorname{Re} 位于 [−π/2,π/2][-\pi/2, \pi/2] 内。

pub fn asin(Complex[Double]) -> Complex[Double]

实数输入交给 asin_real,纯虚数输入转为 iasinh⁡yi\operatorname{asinh} y,某一分量超过 1015010^{150} 的输入使用渐近形式 atan2⁡(∣x∣,∣y∣)+i(ln⁡2+ln⁡∣z∣)\operatorname{atan2}(|x|, |y|) + i(\ln 2 + \ln|z|),其余输入使用 Hull–Fairgrieve–Tang 算法(见设计文档)。结果在每个分量上都是奇函数:xx 与 yy 的符号分别复制到实部和虚部。

asin_real

实数的反正弦:∣x∣≤1|x| \le 1 时为 arcsin⁡x\arcsin x,∣x∣>1|x| > 1 时为 ±π/2+iacosh⁡∣x∣\pm\pi/2 + i\operatorname{acosh}|x|(符号同 xx),NaN 时为 NaN。

pub fn asin_real(Double) -> Complex[Double]

acos

返回反余弦,分支切割线位于实轴上 [−1,1][-1, 1] 之外。

pub fn acos(Complex[Double]) -> Complex[Double]

当 x≥0x \ge 0 时,实部是 [0,π/2][0, \pi/2] 内的主值,虚部符号与 yy 相反。当 x<0x < 0 时,虚部是主值,但实部为 2π−ρ2\pi - \rho 而非主值 π−ρ\pi - \rho,其中 ρ∈[0,π/2]\rho \in [0, \pi/2] 是 arccos⁡(−z)\arccos(-z) 的实部(见上方警告)。纯虚数输入得到 π/2−iasinh⁡y\pi/2 - i\operatorname{asinh} y,实数输入交给 acos_real。

acos_real

实数的反余弦:∣x∣≤1|x| \le 1 时为 arccos⁡x\arccos x,x>1x > 1 时为 −iacosh⁡x-i\operatorname{acosh} x,x<−1x < -1 时为 2π−iacosh⁡(−x)2\pi - i\operatorname{acosh}(-x)。

pub fn acos_real(Double) -> Complex[Double]

atan

返回主值反正切,分支切割线位于虚轴上 [−i,i][-i, i] 之外。

pub fn atan(Complex[Double]) -> Complex[Double]

虚部为 14ln⁡x2+(1+y)2x2+(1−y)2\tfrac14\ln\frac{x^2 + (1+y)^2}{x^2 + (1-y)^2},当比值接近 11 时用 log1p 计算;实部为 12atan2⁡(2x,1−x2−y2)\tfrac12\operatorname{atan2}(2x, 1 - x^2 - y^2),对大输入会重新缩放。在割线上(x=0x = 0,∣y∣>1|y| > 1),实部为 ±π/2\pm\pi/2,符号同 yy。无穷输入返回 ±π/2+0i\pm\pi/2 + 0i。

asec

返回 acos⁡(1/z)\operatorname{acos}(1/z);在 z=0z = 0 处中止。

pub fn asec(Complex[Double]) -> Complex[Double]

asec_real

实数的反正割:∣x∣≥1|x| \ge 1 时为 arccos⁡(1/x)\arccos(1/x),0≤x<10 \le x < 1 时为 −iacosh⁡(1/x)-i\operatorname{acosh}(1/x),−1<x<0-1 < x < 0 时为 2π−iacosh⁡(−1/x)2\pi - i\operatorname{acosh}(-1/x)。

pub fn asec_real(Double) -> Complex[Double]

acsc

返回 asin⁡(1/z)\operatorname{asin}(1/z);在 z=0z = 0 处中止。

pub fn acsc(Complex[Double]) -> Complex[Double]

acsc_real

实数的反余割:∣x∣≥1|x| \ge 1 时为 arcsin⁡(1/x)\arcsin(1/x),∣x∣<1|x| < 1 时为 ±π/2+iacosh⁡∣1/x∣\pm\pi/2 + i\operatorname{acosh}|1/x|。

pub fn acsc_real(Double) -> Complex[Double]

acot

返回 atan⁡(1/z)\operatorname{atan}(1/z),在 z=0z = 0 处返回 π/2\pi/2。

pub fn acot(Complex[Double]) -> Complex[Double]
test "inverse trigonometric functions" {
  let z = @complex.Complex::new(1.0, 1.0)
  let back = @fb.sin(@fb.asin(z))
  assert_true((back.re - 1.0).abs() < 1.0e-10 && (back.im - 1.0).abs() < 1.0e-10)
  assert_eq(@fb.asin_real(2.0).re, @math.PI / 2.0)
  assert_eq(@fb.acot(@complex.Complex::new(0.0, 0.0)).re, @math.PI / 2.0)
}

双曲函数

sinh

返回 sinh⁡z=sinh⁡xcos⁡y+icosh⁡xsin⁡y\sinh z = \sinh x\cos y + i\cosh x\sin y。

pub fn sinh(Complex[Double]) -> Complex[Double]

cosh

返回 cosh⁡z=cosh⁡xcos⁡y+isinh⁡xsin⁡y\cosh z = \cosh x\cos y + i\sinh x\sin y。

pub fn cosh(Complex[Double]) -> Complex[Double]

tanh

返回 tanh⁡z\tanh z;当 ∣x∣≥1|x| \ge 1 时使用以 e−2∣x∣e^{-2|x|} 缩放的形式,它趋于 ±1\pm 1 而不会上溢。

pub fn tanh(Complex[Double]) -> Complex[Double]

sech

返回 1/cosh⁡z1/\cosh z;在 cosh⁡z=0\cosh z = 0 处中止。

pub fn sech(Complex[Double]) -> Complex[Double]

csch

返回 1/sinh⁡z1/\sinh z;在 z=kπiz = k\pi i 处中止。

pub fn csch(Complex[Double]) -> Complex[Double]

coth

返回 1/tanh⁡z1/\tanh z;在 z=kπiz = k\pi i 处中止。

pub fn coth(Complex[Double]) -> Complex[Double]

反双曲函数

asinh

返回 asinh⁡z=−iasin⁡(iz)\operatorname{asinh} z = -i\operatorname{asin}(iz),分支切割线位于虚轴上 [−i,i][-i, i] 之外。

pub fn asinh(Complex[Double]) -> Complex[Double]

实数输入使用实数 asinh;纯虚数输入 iyiy 在 ∣y∣≤1|y| \le 1 时得到 iarcsin⁡yi\arcsin y,否则得到 ±(acosh⁡∣y∣+iπ/2)\pm(\operatorname{acosh}|y| + i\pi/2)。

acosh

返回 acosh⁡z=2ln⁡(z+12+z−12)\operatorname{acosh} z = 2\ln\Big(\sqrt{\tfrac{z+1}{2}} + \sqrt{\tfrac{z-1}{2}}\Big),分支切割线位于实轴上 11 以下的部分。

pub fn acosh(Complex[Double]) -> Complex[Double]

实数输入交给 acosh_real;含无穷分量时得到 ∞+iarg⁡z\infty + i\arg z。

acosh_real

实数的反双曲余弦:x≥1x \ge 1 时为 acosh⁡x\operatorname{acosh} x,−1≤x<1-1 \le x < 1 时为 iarccos⁡xi\arccos x,x<−1x < -1 时为 acosh⁡(−x)+2πi\operatorname{acosh}(-x) + 2\pi i。

pub fn acosh_real(Double) -> Complex[Double]

atanh

返回 atanh⁡z\operatorname{atanh} z,分支切割线位于实轴上 [−1,1][-1, 1] 之外。

pub fn atanh(Complex[Double]) -> Complex[Double]

实部为 14ln⁡(1+x)2+y2(1−x)2+y2\tfrac14\ln\frac{(1+x)^2 + y^2}{(1-x)^2 + y^2}(在零附近使用 log1p),虚部为 12atan2⁡(2y,1−x2−y2)\tfrac12\operatorname{atan2}(2y, 1 - x^2 - y^2),对大输入会重新缩放。无穷输入返回 0±iπ/20 \pm i\pi/2。

atanh_real

实数的反双曲正切:∣x∣<1|x| < 1 时为 atanh⁡x\operatorname{atanh} x,在 ±1\pm 1 处为 ±∞\pm\infty,∣x∣>1|x| > 1 时为 atanh⁡(1/x)+iπ/2\operatorname{atanh}(1/x) + i\pi/2。

pub fn atanh_real(Double) -> Complex[Double]

asech

返回 acosh⁡(1/z)\operatorname{acosh}(1/z);在 z=0z = 0 处中止。

pub fn asech(Complex[Double]) -> Complex[Double]

acsch

返回 asinh⁡(1/z)\operatorname{asinh}(1/z);在 z=0z = 0 处中止。

pub fn acsch(Complex[Double]) -> Complex[Double]

acoth

返回 atanh⁡(1/z)\operatorname{atanh}(1/z);在 z=0z = 0 处中止。

pub fn acoth(Complex[Double]) -> Complex[Double]
test "hyperbolic functions" {
  let z = @complex.Complex::new(0.5, 0.25)
  let back = @fb.tanh(@fb.atanh(z))
  assert_true((back.re - 0.5).abs() < 1.0e-12 && (back.im - 0.25).abs() < 1.0e-12)
  let w = @fb.sinh(@fb.asinh(@complex.Complex::new(0.0, 2.0)))
  assert_true((w.im - 2.0).abs() < 1.0e-12)
  assert_eq(@fb.atanh_real(2.0).im, @math.PI / 2.0)
}