UNPKG

4.85 kBJavaScriptView Raw
1'use strict'
2require('./../utils/polyfills')
3
4const isFactory = require('./../utils/object').isFactory
5const typedFactory = require('./typed')
6const emitter = require('./../utils/emitter')
7
8const importFactory = require('./function/import')
9const configFactory = require('./function/config')
10
11/**
12 * Math.js core. Creates a new, empty math.js instance
13 * @param {Object} [options] Available options:
14 * {number} epsilon
15 * Minimum relative difference between two
16 * compared values, used by all comparison functions.
17 * {string} matrix
18 * A string 'Matrix' (default) or 'Array'.
19 * {string} number
20 * A string 'number' (default), 'BigNumber', or 'Fraction'
21 * {number} precision
22 * The number of significant digits for BigNumbers.
23 * Not applicable for Numbers.
24 * {boolean} predictable
25 * Predictable output type of functions. When true,
26 * output type depends only on the input types. When
27 * false (default), output type can vary depending
28 * on input values. For example `math.sqrt(-4)`
29 * returns `complex('2i')` when predictable is false, and
30 * returns `NaN` when true.
31 * {string} randomSeed
32 * Random seed for seeded pseudo random number generator.
33 * Set to null to randomly seed.
34 * @returns {Object} Returns a bare-bone math.js instance containing
35 * functions:
36 * - `import` to add new functions
37 * - `config` to change configuration
38 * - `on`, `off`, `once`, `emit` for events
39 */
40exports.create = function create (options) {
41 // simple test for ES5 support
42 if (typeof Object.create !== 'function') {
43 throw new Error('ES5 not supported by this JavaScript engine. ' +
44 'Please load the es5-shim and es5-sham library for compatibility.')
45 }
46
47 // cached factories and instances
48 const factories = []
49 const instances = []
50
51 // create a namespace for the mathjs instance, and attach emitter functions
52 const math = emitter.mixin({})
53 math.type = {}
54 math.expression = {
55 transform: {},
56 mathWithTransform: {}
57 }
58
59 // create a new typed instance
60 math.typed = typedFactory.create(math.type)
61
62 // create configuration options. These are private
63 const _config = {
64 // minimum relative difference between two compared values,
65 // used by all comparison functions
66 epsilon: 1e-12,
67
68 // type of default matrix output. Choose 'matrix' (default) or 'array'
69 matrix: 'Matrix',
70
71 // type of default number output. Choose 'number' (default) 'BigNumber', or 'Fraction
72 number: 'number',
73
74 // number of significant digits in BigNumbers
75 precision: 64,
76
77 // predictable output type of functions. When true, output type depends only
78 // on the input types. When false (default), output type can vary depending
79 // on input values. For example `math.sqrt(-4)` returns `complex('2i')` when
80 // predictable is false, and returns `NaN` when true.
81 predictable: false,
82
83 // random seed for seeded pseudo random number generation
84 // null = randomly seed
85 randomSeed: null
86 }
87
88 /**
89 * Load a function or data type from a factory.
90 * If the function or data type already exists, the existing instance is
91 * returned.
92 * @param {{type: string, name: string, factory: Function}} factory
93 * @returns {*}
94 */
95 function load (factory) {
96 if (!isFactory(factory)) {
97 throw new Error('Factory object with properties `type`, `name`, and `factory` expected')
98 }
99
100 const index = factories.indexOf(factory)
101 let instance
102 if (index === -1) {
103 // doesn't yet exist
104 if (factory.math === true) {
105 // pass with math namespace
106 instance = factory.factory(math.type, _config, load, math.typed, math)
107 } else {
108 instance = factory.factory(math.type, _config, load, math.typed)
109 }
110
111 // append to the cache
112 factories.push(factory)
113 instances.push(instance)
114 } else {
115 // already existing function, return the cached instance
116 instance = instances[index]
117 }
118
119 return instance
120 }
121
122 // load the import and config functions
123 math['import'] = load(importFactory)
124 math['config'] = load(configFactory)
125 math.expression.mathWithTransform['config'] = math['config']
126
127 // apply options
128 if (options) {
129 math.config(options)
130 }
131
132 return math
133}