扩展 #
该库可以使用 import 函数轻松地用函数和变量进行扩展。 import 函数可在 mathjs 实例上使用,该实例可以使用 create 函数创建。
import { create, all } from 'mathjs'
const math = create(all)
math.import(/* ... */)
函数 import 接受一个包含函数和变量的对象,或者一个包含工厂函数的数组。它的语法如下:
math.import(functions: Object [, options: Object])
其中
-
functions是一个包含要导入的函数和/或值的对象或数组。import支持普通值和函数、类型化函数(请参阅 类型化函数 部分)以及工厂函数(请参阅 工厂函数 部分)。仅当数组包含工厂函数时,才适用数组。 -
options是一个可选的第二个参数,用于指定选项。以下选项可用:{boolean} override如果为true,则会覆盖现有函数。默认值为false。{boolean} silent如果为true,则函数不会在遇到重复项或无效类型时抛出错误。默认值为false。{boolean} wrap如果为true,则函数将被包装在一个包装函数中,该函数将 Matrix 等数据类型转换为 Array 等原始数据类型。当使用不支持 math.js 数据类型的库扩展 math.js 时,需要此包装器。默认值为false。
以下代码示例演示了如何将一个函数和一个值导入 math.js:
// define new functions and variables
math.import({
myvalue: 42,
hello: function (name) {
return 'hello, ' + name + '!'
}
})
// defined functions can be used in both JavaScript as well as the parser
math.myvalue * 2 // 84
math.hello('user') // 'hello, user!'
const parser = math.parser()
parser.evaluate('myvalue + 10') // 52
parser.evaluate('hello("user")') // 'hello, user!'
导入外部库 #
可以按如下方式导入 numbers.js 和 numeric.js 等外部库。必须使用 npm 安装这些库:
$ npm install numbers
$ npm install numeric
可以使用 import 轻松地将库导入 math.js。为了将 Matrix 等 math.js 特定数据类型转换为 Array 等原始类型,可以通过启用 {wrap: true} 来包装导入的函数。
import { create, all } from 'mathjs'
import * as numbers from 'numbers'
import * as numeric from 'numeric'
// create a mathjs instance and import the numbers.js and numeric.js libraries
const math = create(all)
math.import(numbers, {wrap: true, silent: true})
math.import(numeric, {wrap: true, silent: true})
// use functions from numbers.js
math.fibonacci(7) // 13
math.evaluate('fibonacci(7)') // 13
// use functions from numeric.js
math.evaluate('eig([1, 2; 4, 3])').lambda.x // [5, -1]
类型化函数 #
可以使用 math.typed 创建类型化函数。类型化函数是对此输入参数进行类型检查的函数。它可以有多个签名,并能自动转换所需的输入类型。
可以这样创建类型化函数:
const max = typed('max', {
'number, number': function (a, b) {
return Math.max(a, b)
},
'BigNumber, BigNumber': function (a, b) {
return a.greaterThan(b) ? a : b
}
})
只要签名没有冲突,就可以合并类型化函数。这使得通过支持新数据类型来扩展 math.js 中的现有函数成为可能。
// create a new data type
function MyType (value) {
this.value = value
}
MyType.prototype.isMyType = true
MyType.prototype.toString = function () {
return 'MyType:' + this.value
}
// define a new datatype
math.typed.addType({
name: 'MyType',
test: function (x) {
// test whether x is of type MyType
return x && x.isMyType
}
})
// use the type in a new typed function
const add = typed('add', {
'MyType, MyType': function (a, b) {
return new MyType(a.value + b.value)
}
})
// import in math.js, extend the existing function `add` with support for MyType
math.import({add: add})
// use the new type
const ans = math.add(new MyType(2), new MyType(3)) // returns MyType(5)
console.log(ans) // outputs 'MyType:5'
有关类型化函数的详细信息,请访问: https://github.com/josdejong/typed-function
工厂函数 #
可以使用 math.import 将常规 JavaScript 函数导入 math.js:
math.import({
myFunction: function (a, b) {
// ...
}
})
该函数可以存储在单独的文件中:
export function myFunction (a, b) {
// ...
}
可以这样导入:
import { myFunction } from './myFunction.js'
math.import({
myFunction
})
当 myFunction 需要 math.js 的功能时,就会出现一个问题:在单独的文件中时,它无法访问 math.js 的当前实例。可以使用工厂函数来解决此问题。工厂函数允许在创建函数时注入依赖项。
工厂函数的语法是:
factory(name: string, dependencies: string[], create: function, meta?: Object): function
其中
name是创建的函数的名称。dependencies是一个包含依赖函数名称的数组。create是一个创建函数的函数。一个包含依赖项的对象将作为第一个参数传递。meta是一个可选对象,可以包含您想要的任何元数据。这些元数据将作为meta属性附加到创建的函数上。mathjs 实例使用的已知元数据属性包括:isClass: boolean如果为 true,则创建的函数应为类,并且出于安全原因,例如不会在表达式解析器中公开。lazy: boolean。默认情况下,所有内容都通过import惰性导入。仅当导入的函数或常量实际使用时,它才会被构建。可以通过在元数据中设置lazy: false来强制立即创建函数。isTransformFunction: boolean。如果为 true,则导入的函数将作为转换函数导入。它不会导入到math本身,而仅导入到表达式解析器使用的内部mathWithTransform命名空间。recreateOnConfigChange: boolean。如果为 true,则在配置更改时会重新创建导入的工厂。例如,这用于pi等常量,这些常量取决于number设置,可以是数字或 BigNumbers。formerly: string。如果存在,则创建的函数也将作为指定name的(已弃用的)同义词在实例下可用。此设施仅在重命名函数时使用,以允许临时使用以前的名称,以实现向后兼容。
这是一个依赖于 multiply 的工厂函数的示例:
import { factory, create, all } from 'mathjs'
// create a factory function
const name = 'negativeSquare'
const dependencies = ['multiply', 'unaryMinus']
const createNegativeSquare = factory(name, dependencies, function ({ multiply, unaryMinus }) {
return function negativeSquare (x) {
return unaryMinus(multiply(x, x))
}
})
// create an instance of the function yourself:
const multiply = (a, b) => a * b
const unaryMinus = (a) => -a
const negativeSquare = createNegativeSquare({ multiply, unaryMinus })
console.log(negativeSquare(3)) // -9
// or import the factory in a mathjs instance and use it there
const math = create(all)
math.import(createNegativeSquare)
console.log(math.negativeSquare(4)) // -16
console.log(math.evaluate('negativeSquare(5)')) // -25
您可能会想,为什么要在函数内部直接进行这些计算,而不是注入 multiply 和 unaryMinus 函数?原因是这使得工厂函数 negativeSquare 能够适用于不同的实现:数字、BigNumbers、单位等。
import { Decimal } from 'decimal.js'
// create an instance of our negativeSquare supporting BigNumbers instead of numbers
const multiply = (a, b) => a.mul(b)
const unaryMinus = (a) => new Decimal(0).minus(a)
const negativeSquare = createNegativeSquare({ multiply, unaryMinus })