mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-18 14:59:29 +00:00
501 lines
9.1 KiB
JavaScript
501 lines
9.1 KiB
JavaScript
'use strict';
|
|
|
|
// FIXME: remove dependencies on Nodes
|
|
var ArrayNode = require('../expression/node/ArrayNode');
|
|
var OperatorNode = require('../expression/node/OperatorNode');
|
|
var SymbolNode = require('../expression/node/SymbolNode');
|
|
var ConstantNode = require('../expression/node/ConstantNode');
|
|
|
|
// GREEK LETTERS
|
|
var greek = {
|
|
Alpha: 'A', alpha: true,
|
|
Beta: 'B', beta: true,
|
|
Gamma: true, gamma: true,
|
|
Delta: true, delta: true,
|
|
Epsilon: 'E', epsilon: true, varepsilon: true,
|
|
Zeta: 'Z', zeta: true,
|
|
Eta: 'H', eta: true,
|
|
Theta: true, theta: true, vartheta: true,
|
|
Iota: 'I', iota: true,
|
|
Kappa: 'K', kappa: true, varkappa: true,
|
|
Lambda: true, lambda: true,
|
|
Mu: 'M', mu: true,
|
|
Nu: 'N', nu: true,
|
|
Xi: true, xi: true,
|
|
Omicron: 'O', omicron: true,
|
|
Pi: true, pi: true, varpi: true,
|
|
Rho: 'P', rho: true, varrho: true,
|
|
Sigma: true, sigma: true, varsigma: true,
|
|
Tau: 'T', tau: true,
|
|
Upsilon: true, upsilon: true,
|
|
Phi: true, phi: true, varphi: true,
|
|
Chi: 'X', chi: true,
|
|
Psi: true, psi: true,
|
|
Omega: true, omega: true
|
|
};
|
|
|
|
var dots = {
|
|
dots: true,
|
|
ldots: true,
|
|
cdots: true,
|
|
vdots: true,
|
|
ddots: true,
|
|
idots: true
|
|
};
|
|
|
|
var logic = {
|
|
'true': '\\mathrm{True}',
|
|
'false': '\\mathrm{False}'
|
|
};
|
|
|
|
var other = {
|
|
inf: '\\infty',
|
|
Inf: '\\infty',
|
|
infinity: '\\infty',
|
|
Infinity: '\\infty',
|
|
oo: '\\infty',
|
|
lim: true,
|
|
'undefined': '\\mathbf{?}'
|
|
};
|
|
|
|
// FUNCTIONS
|
|
var functions = {
|
|
acos: '\\cos^{-1}',
|
|
arccos: '\\cos^{-1}',
|
|
cos: true,
|
|
csc: true,
|
|
csch: false,
|
|
exp: true,
|
|
ker: true,
|
|
limsup: true,
|
|
min: true,
|
|
sinh: true,
|
|
asin: '\\sin^{-1}',
|
|
arcsin: '\\sin^{-1}',
|
|
cosh: true,
|
|
deg: true,
|
|
gcd: true,
|
|
lg: true,
|
|
ln: true,
|
|
Pr: true,
|
|
sup: true,
|
|
atan: '\\tan^{-1}',
|
|
atan2: '\\tan2^{-1}',
|
|
arctan: '\\tan^{-1}',
|
|
cot: true,
|
|
det: true,
|
|
hom: true,
|
|
log: true,
|
|
log10: '\\log_{10}',
|
|
sec: true,
|
|
sech: false,
|
|
tan: true,
|
|
arg: true,
|
|
coth: true,
|
|
dim: true,
|
|
inf: true,
|
|
max: true,
|
|
sin: true,
|
|
tanh: true,
|
|
|
|
fix: false,
|
|
lcm: false,
|
|
sign: false,
|
|
xgcd: false,
|
|
unaryMinus: false,
|
|
unaryPlus: false,
|
|
|
|
// complex
|
|
complex: false,
|
|
conj: false,
|
|
im: false,
|
|
re: false,
|
|
|
|
// matrix
|
|
diag: false,
|
|
resize: false,
|
|
size: false,
|
|
squeeze: false,
|
|
subset: false,
|
|
index: false,
|
|
ones: false,
|
|
zeros: false,
|
|
range: false,
|
|
|
|
// probability
|
|
random: false,
|
|
|
|
// statistics
|
|
mean: '\\mu',
|
|
median: false,
|
|
prod: false,
|
|
std: '\\sigma',
|
|
'var': '\\sigma^2'
|
|
};
|
|
|
|
// CURLY FUNCTIONS
|
|
// wrap parameters with {}
|
|
var curlyFunctions = {
|
|
sqrt: true,
|
|
inv: true,
|
|
int: '\\int',
|
|
Int: '\\int',
|
|
integrate: '\\int',
|
|
eigenvalues: '\\lambda',
|
|
liminf: true,
|
|
lim: true,
|
|
exp: 'e^',
|
|
sum: true,
|
|
|
|
eye: '\\mathbf{I}'
|
|
};
|
|
|
|
var operators = {
|
|
'<=': '\\leq',
|
|
'>=': '\\geq',
|
|
'!=': '\\neq',
|
|
'in': true,
|
|
'*': '\\cdot',
|
|
'/': '\\frac',
|
|
'mod': '\\bmod',
|
|
'to': '\\rightarrow'
|
|
};
|
|
|
|
var units = {
|
|
deg: '^{\\circ}'
|
|
};
|
|
|
|
var symbols = {};
|
|
|
|
function mapSymbols() {
|
|
var args = Array.prototype.slice.call(arguments),
|
|
obj;
|
|
for (var i = 0, len = args.length; i < len; i++) {
|
|
obj = args[i];
|
|
for (var key in obj) {
|
|
if (obj.hasOwnProperty(key)) {
|
|
symbols[key] = obj[key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
mapSymbols(
|
|
functions,
|
|
curlyFunctions,
|
|
greek,
|
|
dots,
|
|
logic,
|
|
other
|
|
);
|
|
|
|
function latexIs(arr, value) {
|
|
return typeof arr[value] !== 'undefined';
|
|
}
|
|
|
|
function latexIsFn(arr) {
|
|
return function(value) {
|
|
return latexIs(arr, value);
|
|
};
|
|
}
|
|
|
|
function latexToFn(arr) {
|
|
return function(value) {
|
|
if (typeof arr[value] === 'boolean') {
|
|
if (arr[value] === true) {
|
|
value = '\\' + value;
|
|
}
|
|
else {
|
|
value = '\\mathrm{' + value + '}';
|
|
}
|
|
}
|
|
else if (typeof arr[value] === 'string') {
|
|
value = arr[value];
|
|
}
|
|
else if (typeof value === 'string') {
|
|
var index = value.indexOf('_');
|
|
if (index !== -1) {
|
|
value = exports.toSymbol(value.substring(0, index)) + '_{' +
|
|
exports.toSymbol(value.substring(index+1)) + '}';
|
|
}
|
|
}
|
|
|
|
return value;
|
|
};
|
|
}
|
|
|
|
exports.isSymbol = latexIsFn(symbols);
|
|
exports.toSymbol = latexToFn(symbols);
|
|
|
|
exports.isFunction = latexIsFn(functions);
|
|
exports.toFunction = latexToFn(functions);
|
|
|
|
exports.isCurlyFunction = latexIsFn(curlyFunctions);
|
|
exports.toCurlyFunction = latexToFn(curlyFunctions);
|
|
|
|
exports.isOperator = latexIsFn(operators);
|
|
exports.toOperator = latexToFn(operators);
|
|
|
|
exports.isUnit = latexIsFn(units);
|
|
exports.toUnit = (function() {
|
|
var _toUnit = latexToFn(units);
|
|
|
|
return function(value, notSpaced) {
|
|
if (exports.isUnit(value)) {
|
|
return _toUnit(value);
|
|
}
|
|
|
|
return (notSpaced ? '' : '\\,') + '\\mathrm{' + value + '}';
|
|
};
|
|
}());
|
|
|
|
exports.addBraces = function(s, brace, type) {
|
|
if (brace === null) {
|
|
return s;
|
|
}
|
|
|
|
var braces = ['', ''];
|
|
type = type || 'normal';
|
|
|
|
if (typeof brace === 'undefined' || brace === false) {
|
|
braces = ['{', '}'];
|
|
}
|
|
else if (brace === true) {
|
|
braces = ['(', ')'];
|
|
type = 'lr';
|
|
}
|
|
else if (Array.isArray(brace) && brace.length === 2) {
|
|
braces = brace;
|
|
}
|
|
else {
|
|
braces = [brace, brace];
|
|
}
|
|
|
|
switch (type) {
|
|
case 'normal':
|
|
case false:
|
|
return braces[0] + s + braces[1];
|
|
|
|
case 'lr':
|
|
return '\\left' + braces[0] + '{' + s + '}' + '\\right' + braces[1];
|
|
|
|
case 'be':
|
|
return '\\begin{' + braces[0] + '}' + s + '\\end{' + braces[1] + '}';
|
|
}
|
|
|
|
return braces[0] + s + braces[1];
|
|
};
|
|
|
|
exports.toArgs = function(that) {
|
|
var name = that.name,
|
|
args = that.args,
|
|
func = exports.toSymbol(that.name),
|
|
texParams = null,
|
|
brace = null,
|
|
type = false,
|
|
showFunc = false,
|
|
prefix = '',
|
|
suffix = '',
|
|
op = null;
|
|
|
|
switch (name) {
|
|
// OPERATORS
|
|
case 'add':
|
|
op = '+';
|
|
break;
|
|
|
|
case 'subtract':
|
|
op = '-';
|
|
break;
|
|
|
|
case 'larger':
|
|
op = '>';
|
|
break;
|
|
|
|
case 'largerEq':
|
|
op = '>=';
|
|
break;
|
|
|
|
case 'smaller':
|
|
op = '<';
|
|
break;
|
|
|
|
case 'smallerEq':
|
|
op = '<=';
|
|
break;
|
|
|
|
case 'unequal':
|
|
op = '!=';
|
|
break;
|
|
|
|
case 'equal':
|
|
op = '=';
|
|
break;
|
|
|
|
case 'mod':
|
|
op = 'mod';
|
|
break;
|
|
|
|
case 'multiply':
|
|
op = '*';
|
|
break;
|
|
|
|
case 'pow':
|
|
op = '^';
|
|
break;
|
|
|
|
case 'concat':
|
|
op = '||';
|
|
break;
|
|
|
|
case 'factorial':
|
|
op = '!';
|
|
break;
|
|
|
|
case 'permutations':
|
|
if (args.length === 1) {
|
|
if (args[0] instanceof SymbolNode || args[0] instanceof ConstantNode) {
|
|
op = '!';
|
|
}
|
|
else {
|
|
return '{\\left(' + args[0].toTex() + '\\right)!}';
|
|
}
|
|
}
|
|
else {
|
|
// op = 'P';
|
|
var n = args[0].toTex(),
|
|
k = args[1].toTex();
|
|
return '\\frac{' + n + '!}{\\left(' + n + ' - ' + k + '\\right)!}';
|
|
}
|
|
break;
|
|
|
|
// probability
|
|
case 'combinations':
|
|
op = '\\choose';
|
|
break;
|
|
|
|
// LR BRACES
|
|
case 'abs':
|
|
brace = '|';
|
|
type = 'lr';
|
|
break;
|
|
|
|
case 'norm':
|
|
brace = '\\|';
|
|
type = 'lr';
|
|
|
|
if (args.length === 2) {
|
|
var tmp = args[1].toTex();
|
|
|
|
if (tmp === '\\text{inf}') {
|
|
tmp = '\\infty';
|
|
}
|
|
else if (tmp === '\\text{-inf}') {
|
|
tmp = '{- \\infty}';
|
|
}
|
|
else if (tmp === '\\text{fro}') {
|
|
tmp = 'F';
|
|
}
|
|
|
|
suffix = '_{' + tmp + '}';
|
|
args = [args[0]];
|
|
}
|
|
break;
|
|
|
|
case 'ceil':
|
|
brace = ['\\lceil', '\\rceil'];
|
|
type = 'lr';
|
|
break;
|
|
|
|
case 'floor':
|
|
brace = ['\\lfloor', '\\rfloor'];
|
|
type = 'lr';
|
|
break;
|
|
|
|
case 'round':
|
|
brace = ['\\lfloor', '\\rceil'];
|
|
type = 'lr';
|
|
|
|
if (args.length === 2) {
|
|
suffix = '_' + exports.addBraces(args[1].toTex());
|
|
args = [args[0]];
|
|
}
|
|
break;
|
|
|
|
|
|
// NORMAL BRACES
|
|
case 'inv':
|
|
suffix = '^{-1}';
|
|
break;
|
|
|
|
case 'transpose':
|
|
suffix = '^{T}';
|
|
brace = false;
|
|
break;
|
|
|
|
// SPECIAL NOTATION
|
|
case 'log':
|
|
var base = 'e';
|
|
if (args.length === 2) {
|
|
base = args[1].toTex();
|
|
func = '\\log_{' + base + '}';
|
|
args = [args[0]];
|
|
}
|
|
if (base === 'e') {
|
|
func = '\\ln';
|
|
}
|
|
|
|
showFunc = true;
|
|
break;
|
|
|
|
case 'square':
|
|
suffix = '^{2}';
|
|
break;
|
|
|
|
case 'cube':
|
|
suffix = '^{3}';
|
|
break;
|
|
|
|
|
|
// MATRICES
|
|
case 'eye':
|
|
showFunc = true;
|
|
brace = false;
|
|
func += '_';
|
|
break;
|
|
|
|
case 'det':
|
|
if (that.args[0] instanceof ArrayNode) {
|
|
return that.args[0].toTex('vmatrix');
|
|
}
|
|
|
|
brace = 'vmatrix';
|
|
type = 'be';
|
|
break;
|
|
|
|
default:
|
|
showFunc = true;
|
|
break;
|
|
}
|
|
|
|
if (op !== null) {
|
|
brace = (op === '+' || op === '-');
|
|
texParams = (new OperatorNode(op, name, args)).toTex();
|
|
}
|
|
else {
|
|
op = ', ';
|
|
}
|
|
|
|
if (brace === null && !exports.isCurlyFunction(name)) {
|
|
brace = true;
|
|
}
|
|
|
|
texParams = texParams || args.map(function(param) {
|
|
return '{' + param.toTex() + '}' ;
|
|
}).join(op);
|
|
|
|
return prefix + (showFunc ? func : '') +
|
|
exports.addBraces(texParams, brace, type) +
|
|
suffix;
|
|
};
|