- 科学计算
【免费下载链接】mathjs
An extensive math library for JavaScript and Node.js
导读
本文是 mathjs 中复数(Complex Numbers)数据类型的系统性技术指南,覆盖从复数的数学定义、math.complex的多种构造方式,到四则运算、实部/虚部/共轭等常用函数,再到Complex对象完整的实例 API 与静态方法的全链路内容。读完本文,你将掌握如何在 JavaScript / Node.js 项目中创建与操作复数、如何用极坐标与 JSON 序列化处理复数,并了解 mathjs 底层如何基于 complex.js 实现复数支持、为什么math.sqrt(-4)能返回2i这类"看似越界"的运算。
复数在 mathjs 中的定位
mathjs 是一个面向 JavaScript 与 Node.js 的扩展数学库,复数是其核心数据类型之一。官方文档明确说明:**mathjs 的复数支持由 complex.js。从源码可以确认:
createComplexClass通过 factory 机制注册Complex类,并为其附加类型标记Complex.prototype.type = 'Complex'与Complex.prototype.isComplex = true(见 src/type/complex/Complex.js),这也是 mathjs 内部isComplex类型判断(见 src/utils/is.js)与 Unit 等类型识别复数的依据。- 在数学上,复数形如
a + bi,其中a、b为实数,虚数单位i满足i² = -1(即i是-1的平方根)。a称为实部(real part),b称为虚部(imaginary part),例如3 + 2i的实部为3、虚部为2。
复数广泛应用于应用数学、控制理论、信号分析、流体力学等工程与科学领域——这也是 mathjs 将复数作为一等公民数据类型的原因。
创建复数:math.complex 的多种构造方式
创建复数使用math.complex函数。根据官方文档与 src/type/complex/function/complex.js 中的 typed-function 签名定义,该函数支持下列全部调用形式:
math.complex() // 无参数,返回 0 + 0i(对应源码中 Complex.ZERO) math.complex(re) // 仅实部,虚部为 0 math.complex(re, im) // 实部 + 虚部 math.complex(complex) // 克隆一个已有的 Complex 对象 math.complex({re, im}) // 对象形式:实部 + 虚部 math.complex({r, phi}) // 对象形式:极坐标(模 + 辐角) math.complex({abs, arg}) // 对象形式:极坐标的别名写法 math.complex(str) // 字符串形式,如 '4 - 2i'源码 src/type/complex/function/complex.js 中的实现要点:
- 空调用返回
Complex.ZERO(0 + 0i); number单参数构造虚部为 0 的复数;number, number双参数直接构造;BigNumber, BigNumber会先toNumber()再构造(源码注释标注该签名是冗余的);Fraction通过x.valueOf()转为数值;- 传入
Complex时调用x.clone()完成克隆,保证返回独立对象; - 传入
string时直接交给 complex.js 解析(例如'2 + 3i'); - 传入
Object时依次识别re+im、r+phi、abs+arg三组属性,三者均不满足时抛出Expected object with properties (re and im) or (r and phi) or (abs and arg); - 传入
Array | Matrix时通过deepMap逐元素递归转换(见 src/utils/collection.js),即复数构造可以作用于矩阵。
官方文档给出的基础示例:
const a = math.complex(2, 3) // Complex 2 + 3i a.re // Number 2 a.im // Number 3 const b = math.complex('4 - 2i') // Complex 4 - 2i b.re = 5 // Number 5 b // Complex 5 - 2i在表达式解析器中使用
除了函数式调用,complex也是表达式解析器(math.evaluate/math.parser())中的构造函数关键字。其嵌入式文档定义于 src/expression/embeddedDocs/construction/complex.js,声明语法为complex()、complex(re, im)、complex(string),例如math.evaluate('complex(2, 3)')与math.evaluate('complex("7 - 2i")')均可用。此外,表达式语法本身也内置虚数单位常量i(见 src/expression/embeddedDocs/constants/i.js),可直接书写2 + 3i形式的表达式。
复数运算:实部、虚部、共轭与四则运算
mathjs 中绝大多数函数都支持复数,且复数与实数可以混合参与运算。官方文档示例:
const a = math.complex(2, 3) // Complex 2 + 3i const b = math.complex('4 - 2i') // Complex 4 - 2i math.re(a) // Number 2 math.im(a) // Number 3 math.conj(a) // Complex 2 - 3i math.add(a, b) // Complex 6 + i math.multiply(a, 2) // Complex 4 + 6i math.sqrt(-4) // Complex 2i从源码看这些运算的底层实现:
math.re(src/function/complex/re.js):对Complex直接返回x.re;对number | BigNumber | Fraction原样返回;对数组/矩阵逐元素计算。注意math.im(src/function/complex/im.js)对number返回0、对BigNumber | Fraction返回x.mul(0),保证类型一致。math.conj(src/function/complex/conj.js):对Complex调用x.conjugate()得到共轭a - bi;对Unit会先toNumeric()求共轭再保持原单位,对数组/矩阵同样逐元素处理。math.sqrt(-4)返回2i:这是复数支持带来的自然结果——开方、pow、log、三角函数(如sin、cos)等函数在实数域无解时自动落入复数域。测试 test/unit-tests/type/complex/Complex.test.js 以及算术函数测试中对sqrt负数输入的断言均验证了该行为。
复数与实数的混合运算(如math.multiply(a, 2))由 typed-function 的多签名分派自动处理,开发者无需手动做类型转换。
Complex 对象实例 API
math.complex返回的Complex对象包含以下属性与方法(与 complex.js 保持一致的语义):
complex.re / complex.im
complex.re:实部,数值类型,可读可写;complex.im:虚部,数值类型,可读可写。
赋值后对象立即反映新值,例如上文示例中b.re = 5后b变为Complex 5 - 2i。
complex.clone()
创建当前复数的一个独立副本(修改副本不影响原对象)。math.complex(complex)内部即调用该方法。
complex.equals(other)
测试两个复数是否相等。当且仅当实部与虚部都相等时返回true。测试用例(test/unit-tests/type/complex/Complex.test.js)验证了new Complex(2, 4).equals(new Complex(2, 3))为false、new Complex(0, 0).equals(new Complex())为true等边界情况。
complex.neg()
取相反数:实部、虚部保持绝对值、符号取反,即a + bi→-a - bi。
complex.conjugate()
取共轭:实部不变、虚部符号取反,即a + bi→a - bi。与函数math.conj(x)等价。
complex.inverse()
返回当前复数的乘法逆元(倒数)。复数z的逆为1/z,满足z * z⁻¹ = 1。
complex.toVector()
返回当前复数的向量表示,即一个长度为 2 的数组[re, im],可用于与向量/矩阵运算对接。
complex.toJSON()
返回复数的 JSON 表示,结构为{mathjs: 'Complex', re: number, im: number}。该实现位于 src/type/complex/Complex.js,是 mathjs 序列化机制的基础——JSON.stringify会自动调用它。完整序列化/反序列化流程参见 序列化文档。
complex.toPolar()
返回极坐标表示{r: number, phi: number},其中r是模(this.abs()),phi是辐角(this.arg(),区间为[-pi, pi])。实现见 src/type/complex/Complex.js。
complex.toString()
返回字符串表示,格式为a + bi(如2 + 3i)。源码中还定义了Complex.prototype.valueOf = Complex.prototype.toString(见 src/type/complex/Complex.js),即隐式类型转换时同样得到字符串。
complex.format([precision])
获取格式化字符串。除toString()的基础输出外,format支持传入精度参数或格式化选项:
- 传数字
precision:按 10 的负幂次 epsilon(Math.pow(10, -precision))做舍入,当实部/虚部比值小于 epsilon 时将该分量归零,从而消除浮点噪声(实现见 src/type/complex/Complex.js); - 输出对纯实部(
im === 0)、纯虚部(re === 0,含i、-i缩写)以及一般复数分别处理,负数虚部使用a - bi形式。
对应的测试用例(test/unit-tests/type/complex/Complex.test.js)验证了"虚部相对实部极小则归零""实部相对虚部极小则归零"等舍入行为。
Complex 静态方法
以下静态方法通过math.Complex访问:
Complex.fromJSON(json)
从 JSON 对象复活复数,接受{mathjs: 'Complex', re: number, im: number}(mathjs属性可选),re、im缺省为 0。实现见 src/type/complex/Complex.js,与toJSON配对使用,是 序列化机制 中math.reviver恢复 Complex 类型的底层入口。
const c = math.Complex.fromJSON({ mathjs: 'Complex', re: 4, im: 3 }) // Complex 4 + 3iComplex.fromPolar(r, phi)
从极坐标创建复数,支持两种调用形式(实现见 src/type/complex/Complex.js):
Complex.fromPolar(r, phi) // 双参数 Complex.fromPolar({r, phi}) // 单对象参数r必须是数值;phi可以是数值,也可以是角度单位(Unit,含ANGLE基准),此时自动toNumber('rad')转为弧度。测试 test/unit-tests/type/complex/Complex.test.js 验证了Complex.fromPolar(1, new Unit(90, 'deg'))与Complex.fromPolar(1, new Unit(100, 'grad'))均得到虚部为 1 的复数;- 参数非法时分别抛出
TypeError(r 非数值 / phi 非数值且非角度单位)或SyntaxError(参数个数错误)。
Complex.compare(a, b)
比较两个复数的大小,规则为字典序比较(先比实部,再比虚部),返回-1、0或1:
- 实部
a.re > b.re→ 返回1; - 实部
a.re < b.re→ 返回-1; - 实部相等时,虚部
a.im > b.im→ 返回1;虚部a.im < b.im→ 返回-1; - 实部虚部均相等 → 返回
0。
该实现直接对应源码 src/type/complex/Complex.js:
const a = math.complex(2, 3) // Complex 2 + 3i const b = math.complex(2, 1) // Complex 2 + 1i math.Complex.compare(a, b) // 返回 1(实部相等,a 的虚部更大)序列化与反序列化
由于Complex是实例化对象,跨进程、跨端传输或持久化时需要序列化。mathjs 的通用序列化方案见 序列化文档,对复数而言:
const x = math.complex('2 + 3i') const str = JSON.stringify(x, math.replacer) // 输出 '{"mathjs":"Complex","re":2,"im":3}'JSON.stringify默认会调用Complex.prototype.toJSON,因此大多数场景不传math.replacer也能正确序列化;但文档特别提示:像Infinity这类值必须借助math.replacer才能无损序列化,最佳实践是一律传入math.replacer。反序列化时需配合math.reviver:
const json = '{"mathjs":"Complex","re":2,"im":3}' const x = JSON.parse(json, math.reviver) // Complex 2 + 3i当与其他数据类型(如 Unit、Matrix)混用多个 reviver 时,可以通过级联组合:
const reviver = function (key, value) { return reviver1(key, reviver2(key, value)) }小结
mathjs 的复数支持是一套完整的类型体系:构造上支持数字对、字符串、{re, im}对象、{r, phi}/{abs, arg}极坐标对象、数组矩阵逐元素转换以及克隆;运算上与实数无缝混用,且能自然扩展sqrt、log、三角函数到复数域;对象层提供了re/im读写、clone、equals、neg、conjugate、inverse、toVector、toPolar、toString、format等完整实例方法;静态层提供fromJSON、fromPolar(支持角度单位)、compare。其底层实现集中在 src/type/complex/Complex.js 与 src/type/complex/function/complex.js,并有 test/unit-tests/type/complex/Complex.test.js 等测试保障行为正确性。无论是信号处理、控制理论等领域的科学计算,还是在浏览器与 Node.js 间的数据交换,本文覆盖的内容都足以支撑完整的复数编程实践。
- 科学计算
【免费下载链接】mathjs
An extensive math library for JavaScript and Node.js
相关推荐
CSS 预处理器依赖分析:如何使用 node-dependency-tree 处理 Sass、Less、Stylus
CSS 预处理器依赖分析:如何使用 node dependency tree 处理 Sass、Less、Stylus 在前端开发中,CSS 预处理器(如 Sas
EdgeDB Numbers 标准库完全指南:数值类型、运算符与函数
EdgeDB Numbers 标准库完全指南:数值类型、运算符与函数 本篇技术指南以 EdgeDB(Gel)标准库的 Numbers 参考文档( docs/re
数据库图数据库关系型数据库Complex and Rational Numbers in Julia: A Comprehensive Guide
Complex and Rational Numbers in Julia: A Comprehensive Guide Julia 语言内建了两种重要的数值类
编程语言编译器语言运行时标准库JIT编译
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考