New system for integrals the same as for derivatives.
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
d991deee7b
commit
803416d08d
2 changed files with 47 additions and 24 deletions
|
@ -44,34 +44,55 @@ const parser = new ExprEval.Parser()
|
|||
|
||||
parser.consts = Object.assign({}, parser.consts, evalVariables)
|
||||
|
||||
/**
|
||||
* Parses arguments for a function, returns the corresponding JS function if it exists.
|
||||
* Throws either usage error otherwise.
|
||||
* @param {array} args - Arguments of the function, either [ ExecutableObject ] or [ string, variable ].
|
||||
* @param {string} usage1 - Usage for executable object.
|
||||
* @param {string} usage2 - Usage for string function.
|
||||
* @return {callable} JS function to call..
|
||||
*/
|
||||
function parseArgumentsForFunction(args, usage1, usage2) {
|
||||
let f, target, variable
|
||||
if(args.length == 1) {
|
||||
// Parse object
|
||||
f = args[0]
|
||||
if(typeof f != 'object' || !f.execute)
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage1))
|
||||
let target = f
|
||||
f = (x) => target.execute(x)
|
||||
} else if(args.length == 2) {
|
||||
// Parse variable
|
||||
[f,variable] = args
|
||||
if(typeof f != 'string' || typeof variable != 'number')
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1').arg(usage2))
|
||||
f = parser.parse(f).toJSFunction(variable, currentVars)
|
||||
} else
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)))
|
||||
return f
|
||||
}
|
||||
|
||||
// Function definition
|
||||
parser.functions.integral = function(a, b, f, variable) {
|
||||
parser.functions.integral = function(a, b, ...args) {
|
||||
let usage1 = qsTranslate('usage', 'integral(<from: number>, <to: number>, <f: ExecutableObject>)')
|
||||
let usage2 = qsTranslate('usage', 'integral(<from: number>, <to: number>, <f: string>, <variable: string>)')
|
||||
let f = parseArgumentsForFunction(args, usage1, usage2)
|
||||
if(a == null || b == null)
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)))
|
||||
|
||||
// https://en.wikipedia.org/wiki/Simpson%27s_rule
|
||||
// Simpler, faster than tokenizing the expression
|
||||
f = parser.parse(f).toJSFunction(variable, currentVars)
|
||||
return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b))
|
||||
}
|
||||
|
||||
parser.functions.derivative = function(...args) {
|
||||
let f, target, variable, x
|
||||
if(args.length == 2) {
|
||||
[f, x] = args
|
||||
if(typeof f != 'object' || !f.execute)
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: ExecutableObject>, <x: variable>)')))
|
||||
target = f
|
||||
f = (x) => target.execute(x)
|
||||
} else if(args.length == 3) {
|
||||
[f, variable, x] = args
|
||||
if(typeof f != 'string')
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: string>, <variable: string>, <x: variable>)')))
|
||||
f = parser.parse(f).toJSFunction(variable, currentVars)
|
||||
} else
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: string>, <variable: string>, <x: variable>)')
|
||||
.arg(qsTranslate('usage', 'derivative(<function: string>, <variable: string>, <x: variable>)'))))
|
||||
|
||||
let usage1 = qsTranslate('usage', 'derivative(<f: ExecutableObject>, <x: variable>)')
|
||||
let usage2 = qsTranslate('usage', 'derivative(<f: string>, <variable: string>, <x: variable>)')
|
||||
let x = args.pop()
|
||||
let f = parseArgumentsForFunction(args, usage1, usage2)
|
||||
if(x == null)
|
||||
throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)))
|
||||
|
||||
let derivative_precision = x/10
|
||||
return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision
|
||||
}
|
||||
|
|
|
@ -71,16 +71,18 @@ function parif(elem, contents) {
|
|||
* @returns {string}
|
||||
*/
|
||||
function functionToLatex(f, args) {
|
||||
console.log("Generating latex", f, args)
|
||||
switch(f) {
|
||||
case "derivative":
|
||||
if(args.length == 3)
|
||||
return '\\frac{d' + args[0].substr(1, args[0].length-2).replace(new RegExp(args[1].substr(1, args[1].length-2), 'g'), 'x') + '}{dx}';
|
||||
else
|
||||
return '\\frac{d' + args[0] + '}{dx}';
|
||||
return '\\frac{d' + args[0] + '}{dx}(x)';
|
||||
break;
|
||||
case "integral":
|
||||
return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2);
|
||||
if(args.length == 4)
|
||||
return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2].substr(1, args[2].length-2) + ' d' + args[3].substr(1, args[3].length-2);
|
||||
else
|
||||
return '\\int\\limits_{' + args[0] + '}^{' + args[1] + '}' + args[2] + '(t) dt';
|
||||
break;
|
||||
case "sqrt":
|
||||
return '\\sqrt\\left(' + args.join(', ') + '\\right)';
|
||||
|
|
Loading…
Reference in a new issue