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)
|
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
|
// 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
|
// https://en.wikipedia.org/wiki/Simpson%27s_rule
|
||||||
// Simpler, faster than tokenizing the expression
|
// 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))
|
return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.functions.derivative = function(...args) {
|
parser.functions.derivative = function(...args) {
|
||||||
let f, target, variable, x
|
let usage1 = qsTranslate('usage', 'derivative(<f: ExecutableObject>, <x: variable>)')
|
||||||
if(args.length == 2) {
|
let usage2 = qsTranslate('usage', 'derivative(<f: string>, <variable: string>, <x: variable>)')
|
||||||
[f, x] = args
|
let x = args.pop()
|
||||||
if(typeof f != 'object' || !f.execute)
|
let f = parseArgumentsForFunction(args, usage1, usage2)
|
||||||
throw EvalError(qsTranslate('usage', 'Usage: %1')
|
if(x == null)
|
||||||
.arg(qsTranslate('usage', 'derivative(<function: ExecutableObject>, <x: variable>)')))
|
throw EvalError(qsTranslate('usage', 'Usage: %1 or\n%2').arg(usage1).arg(usage2)))
|
||||||
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 derivative_precision = x/10
|
let derivative_precision = x/10
|
||||||
return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision
|
return (f(x+derivative_precision/2)-f(x-derivative_precision/2))/derivative_precision
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,16 +71,18 @@ function parif(elem, contents) {
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function functionToLatex(f, args) {
|
function functionToLatex(f, args) {
|
||||||
console.log("Generating latex", f, args)
|
|
||||||
switch(f) {
|
switch(f) {
|
||||||
case "derivative":
|
case "derivative":
|
||||||
if(args.length == 3)
|
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}';
|
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
|
else
|
||||||
return '\\frac{d' + args[0] + '}{dx}';
|
return '\\frac{d' + args[0] + '}{dx}(x)';
|
||||||
break;
|
break;
|
||||||
case "integral":
|
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;
|
break;
|
||||||
case "sqrt":
|
case "sqrt":
|
||||||
return '\\sqrt\\left(' + args.join(', ') + '\\right)';
|
return '\\sqrt\\left(' + args.join(', ') + '\\right)';
|
||||||
|
|
Loading…
Reference in a new issue