Integrals, opening directly from the command line

This commit is contained in:
Ad5001 2021-01-10 20:48:11 +01:00
parent 2fa6d71a27
commit 6d1c3d5450
4 changed files with 39 additions and 8 deletions

View file

@ -21,9 +21,7 @@
.import "expr-eval.js" as ExprEval .import "expr-eval.js" as ExprEval
.import "utils.js" as Utils .import "utils.js" as Utils
const parser = new ExprEval.Parser()
var u = {1: 1, 2: 2, 3: 3}
var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manualy var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manualy
"pi": Math.PI, "pi": Math.PI,
@ -35,6 +33,15 @@ var evalVariables = { // Variables not provided by expr-eval.js, needs to be pro
"E": Math.E "E": Math.E
} }
var currentVars = {}
const parser = new ExprEval.Parser()
parser.functions.integral = function(a, b, f, variable) {
// https://en.wikipedia.org/wiki/Simpson%27s_rule
f = parser.parse(f).toJSFunction(variable, currentVars)
return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b))
}
class Expression { class Expression {
constructor(expr) { constructor(expr) {
this.expr = expr this.expr = expr
@ -49,7 +56,8 @@ class Expression {
execute(x = 1) { execute(x = 1) {
if(this.cached) return this.cachedValue if(this.cached) return this.cachedValue
return this.calc.evaluate(Object.assign({'x': x}, evalVariables)) currentVars = Object.assign({'x': x}, evalVariables)
return this.calc.evaluate(currentVars)
} }
simplify(x) { simplify(x) {
@ -111,9 +119,10 @@ class Sequence extends Expression {
cache(n = 1) { cache(n = 1) {
var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString())
var expr = parser.parse(str).simplify() var expr = parser.parse(str).simplify()
var l = {} var l = {'n': n-this.valuePlus} // Just in case, add n (for custom functions)
l[this.name] = this.calcValues l[this.name] = this.calcValues
this.calcValues[n] = expr.evaluate(Object.assign(l, evalVariables)) currentVars = Object.assign(l, evalVariables)
this.calcValues[n] = expr.evaluate(currentVars)
} }
toString(forceSign=false) { toString(forceSign=false) {

View file

@ -236,7 +236,7 @@ class Function extends ExecutableObject {
if(this.displayMode == 'application') { if(this.displayMode == 'application') {
return `${this.name}: ${this.definitionDomain} ⸺> ${this.destinationDomain}\n ${' '.repeat(this.name.length)}x ⸺> ${this.expression.toString()}` return `${this.name}: ${this.definitionDomain} ⸺> ${this.destinationDomain}\n ${' '.repeat(this.name.length)}x ⸺> ${this.expression.toString()}`
} else { } else {
return `${this.name}(x) = ${this.expression.toString()}\nD<sub>${this.name}</sub> = ${this.definitionDomain}` return `${this.name}(x) = ${this.expression.toString()}\nD${Utils.textsub(this.name)} = ${this.definitionDomain}`
} }
} }

View file

@ -23,6 +23,8 @@ var powerpos = {
"+": "⁺", "+": "⁺",
"=": "⁼", "=": "⁼",
" ": "", " ": "",
"(": "⁽",
")": "⁾",
"0": "⁰", "0": "⁰",
"1": "¹", "1": "¹",
"2": "²", "2": "²",
@ -64,6 +66,8 @@ var indicepos = {
"-": "₋", "-": "₋",
"+": "₊", "+": "₊",
"=": "₌", "=": "₌",
"(": "₍",
")": "₎",
" ": "", " ": "",
"0": "₀", "0": "₀",
"1": "₁", "1": "₁",
@ -255,6 +259,14 @@ function makeExpressionReadable(str) {
[/(\d|\))×/g, '$1'], [/(\d|\))×/g, '$1'],
//[/×(\d|\()/g, '$1'], //[/×(\d|\()/g, '$1'],
[/\(([^)(+.\/-]+)\)/g, "$1"], [/\(([^)(+.\/-]+)\)/g, "$1"],
[/integral\((.+), ?(.+), ("|')(.+)("|'), ?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) {
console.log('Intégrale', a, b, body, by)
if(a.length < b.length) {
return `${textsub(a)}${textsup(b)} ${body} d${by}`
} else {
return `${textsup(b)}${textsub(a)} ${body} d${by}`
}
}]
] ]
str = simplifyExpression(str) str = simplifyExpression(str)

14
run.py
View file

@ -25,7 +25,11 @@ import os
import tempfile import tempfile
from platform import release as os_release from platform import release as os_release
from json import dumps from json import dumps
from sys import platform from sys import platform, argv
pwd = os.getcwd()
os.chdir(os.path.dirname(os.path.realpath(__file__)))
tempfile = tempfile.mkstemp(suffix = '.png')[1] tempfile = tempfile.mkstemp(suffix = '.png')[1]
@ -77,7 +81,7 @@ class Helper(QObject):
# TODO: Better copy system # TODO: Better copy system
os.system("xclip -selection clipboard -t image/png -i " + tempfile) os.system("xclip -selection clipboard -t image/png -i " + tempfile)
app = QApplication([]) app = QApplication(argv)
app.setApplicationName("Logarithmic Plotter") app.setApplicationName("Logarithmic Plotter")
app.setOrganizationName("Ad5001") app.setOrganizationName("Ad5001")
app.setWindowIcon(QIcon(os.path.realpath(os.path.join(os.getcwd(), "logplotter.svg")))) app.setWindowIcon(QIcon(os.path.realpath(os.path.join(os.getcwd(), "logplotter.svg"))))
@ -88,6 +92,12 @@ engine.rootContext().setContextProperty("Helper", helper)
engine.addImportPath(os.path.realpath(os.path.join(os.getcwd(), "qml"))) engine.addImportPath(os.path.realpath(os.path.join(os.getcwd(), "qml")))
engine.load(os.path.realpath(os.path.join(os.getcwd(), "qml", "LogGraph.qml"))) engine.load(os.path.realpath(os.path.join(os.getcwd(), "qml", "LogGraph.qml")))
os.chdir(pwd)
if len(argv) > 0 and os.path.exists(argv[-1]) and argv[-1].split('.')[-1] == 'json':
print(argv[-1])
engine.rootObjects()[0].loadDiagram(argv[-1])
os.chdir(os.path.dirname(os.path.realpath(__file__)))
if not engine.rootObjects(): if not engine.rootObjects():
print("No root object") print("No root object")
exit(-1) exit(-1)