Compare commits
3 commits
d969661b33
...
0a064694f5
Author | SHA1 | Date | |
---|---|---|---|
0a064694f5 | |||
b0b77834a8 | |||
fb1c4c0de7 |
10 changed files with 227 additions and 59 deletions
|
@ -35,7 +35,7 @@ import "js/math/latex.js" as LatexJS
|
||||||
\sa LogarithmPlotter
|
\sa LogarithmPlotter
|
||||||
*/
|
*/
|
||||||
MenuBar {
|
MenuBar {
|
||||||
property var settings: settingsMenu
|
property var settingsMenu: settingsSubMenu
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
title: qsTr("&File")
|
title: qsTr("&File")
|
||||||
|
@ -124,7 +124,7 @@ MenuBar {
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
id: settingsMenu
|
id: settingsSubMenu
|
||||||
title: qsTr("&Settings")
|
title: qsTr("&Settings")
|
||||||
Action {
|
Action {
|
||||||
id: checkForUpdatesMenuSetting
|
id: checkForUpdatesMenuSetting
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
import QtQml 2.12
|
import QtQml 2.12
|
||||||
|
import QtQuick.Window 2.12
|
||||||
import "../js/objects.js" as Objects
|
import "../js/objects.js" as Objects
|
||||||
import "../js/historylib.js" as HistoryLib
|
import "../js/historylib.js" as HistoryLib
|
||||||
import "../js/history/common.js" as HistoryCommon
|
import "../js/history/common.js" as HistoryCommon
|
||||||
|
@ -215,5 +216,6 @@ Item {
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
HistoryLib.history = historyObj
|
HistoryLib.history = historyObj
|
||||||
HistoryCommon.themeTextColor = sysPalette.windowText
|
HistoryCommon.themeTextColor = sysPalette.windowText
|
||||||
|
HistoryCommon.imageDepth = Screen.devicePixelRatio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
import QtQuick.Dialogs 1.3 as D
|
import QtQuick.Dialogs 1.3 as D
|
||||||
import QtQuick.Controls 2.12
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Window 2.12
|
||||||
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
import eu.ad5001.LogarithmPlotter.Setting 1.0 as Setting
|
||||||
import "../js/objects.js" as Objects
|
import "../js/objects.js" as Objects
|
||||||
import "../js/historylib.js" as HistoryLib
|
import "../js/historylib.js" as HistoryLib
|
||||||
|
@ -100,8 +101,8 @@ Item {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
visible: LatexJS.enabled
|
visible: LatexJS.enabled
|
||||||
property double depth: 2
|
property double depth: Screen.devicePixelRatio
|
||||||
property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*parent.font.pixelSize+4, parent.color).split(",") : ["","0","0"]
|
property var ltxInfo: visible ? Latex.render(obj.getLatexString(), depth*(parent.font.pixelSize+2), parent.color).split(",") : ["","0","0"]
|
||||||
source: visible ? ltxInfo[0] : ""
|
source: visible ? ltxInfo[0] : ""
|
||||||
width: parseInt(ltxInfo[1])/depth
|
width: parseInt(ltxInfo[1])/depth
|
||||||
height: parseInt(ltxInfo[2])/depth
|
height: parseInt(ltxInfo[2])/depth
|
||||||
|
|
|
@ -104,7 +104,7 @@ Popup {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Helper.setSettingBool("check_for_updates", checked)
|
Helper.setSettingBool("check_for_updates", checked)
|
||||||
// Set in the menu bar
|
// Set in the menu bar
|
||||||
appMenu.settings.children[0].checked = checked
|
appMenu.settingsMenu.children[0].checked = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ Popup {
|
||||||
text: qsTr('Reset redo stack when a new action is added to history')
|
text: qsTr('Reset redo stack when a new action is added to history')
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Helper.setSettingBool("reset_redo_stack", checked)
|
Helper.setSettingBool("reset_redo_stack", checked)
|
||||||
appMenu.settings.children[1].checked = checked
|
appMenu.settingsMenu.children[1].checked = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ Popup {
|
||||||
text: qsTr('Enable LaTeX rendering')
|
text: qsTr('Enable LaTeX rendering')
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Helper.setSettingBool("enable_latex", checked)
|
Helper.setSettingBool("enable_latex", checked)
|
||||||
appMenu.settings.children[2].checked = checked
|
appMenu.settingsMenu.children[2].checked = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ Popup {
|
||||||
text: qsTr('Automatically close parenthesises and brackets in expressions')
|
text: qsTr('Automatically close parenthesises and brackets in expressions')
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Helper.setSettingBool("expression_editor.autoclose", checked)
|
Helper.setSettingBool("expression_editor.autoclose", checked)
|
||||||
appMenu.settings.children[3].children[0].checked = checked
|
appMenu.settingsMenu.children[3].children[0].checked = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ Popup {
|
||||||
text: qsTr('Enable syntax highlighting for expressions')
|
text: qsTr('Enable syntax highlighting for expressions')
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Helper.setSettingBool("expression_editor.colorize", checked)
|
Helper.setSettingBool("expression_editor.colorize", checked)
|
||||||
appMenu.settings.children[3].children[1].checked = checked
|
appMenu.settingsMenu.children[3].children[1].checked = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ Popup {
|
||||||
text: qsTr('Enable autocompletion interface in expression editor')
|
text: qsTr('Enable autocompletion interface in expression editor')
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Helper.setSettingBool("autocompletion.enabled", checked)
|
Helper.setSettingBool("autocompletion.enabled", checked)
|
||||||
appMenu.settings.children[3].children[2].checked = checked
|
appMenu.settingsMenu.children[3].children[2].checked = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import QtQuick 2.7
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Window 2.12
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -48,8 +49,8 @@ Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
//smooth: true
|
//smooth: true
|
||||||
visible: false
|
visible: false
|
||||||
sourceSize.width: width*2
|
sourceSize.width: width*Screen.devicePixelRatio
|
||||||
sourceSize.height: width*2
|
sourceSize.height: width*Screen.devicePixelRatio
|
||||||
}
|
}
|
||||||
ColorOverlay {
|
ColorOverlay {
|
||||||
anchors.fill: img
|
anchors.fill: img
|
||||||
|
|
|
@ -1627,10 +1627,10 @@ function min(array) {
|
||||||
|
|
||||||
function arrayMap(f, a) {
|
function arrayMap(f, a) {
|
||||||
if (typeof f !== 'function') {
|
if (typeof f !== 'function') {
|
||||||
throw new Error(qsTranslate('error', 'First argument to map is not a function.'));
|
throw new EvalError(qsTranslate('error', 'First argument to map is not a function.'));
|
||||||
}
|
}
|
||||||
if (!Array.isArray(a)) {
|
if (!Array.isArray(a)) {
|
||||||
throw new Error(qsTranslate('error', 'Second argument to map is not an array.'));
|
throw new EvalError(qsTranslate('error', 'Second argument to map is not an array.'));
|
||||||
}
|
}
|
||||||
return a.map(function (x, i) {
|
return a.map(function (x, i) {
|
||||||
return f(x, i);
|
return f(x, i);
|
||||||
|
@ -1639,10 +1639,10 @@ function arrayMap(f, a) {
|
||||||
|
|
||||||
function arrayFold(f, init, a) {
|
function arrayFold(f, init, a) {
|
||||||
if (typeof f !== 'function') {
|
if (typeof f !== 'function') {
|
||||||
throw new Error(qsTranslate('error', 'First argument to fold is not a function.'));
|
throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.'));
|
||||||
}
|
}
|
||||||
if (!Array.isArray(a)) {
|
if (!Array.isArray(a)) {
|
||||||
throw new Error(qsTranslate('error', 'Second argument to fold is not an array.'));
|
throw new EvalError(qsTranslate('error', 'Second argument to fold is not an array.'));
|
||||||
}
|
}
|
||||||
return a.reduce(function (acc, x, i) {
|
return a.reduce(function (acc, x, i) {
|
||||||
return f(acc, x, i);
|
return f(acc, x, i);
|
||||||
|
@ -1651,10 +1651,10 @@ function arrayFold(f, init, a) {
|
||||||
|
|
||||||
function arrayFilter(f, a) {
|
function arrayFilter(f, a) {
|
||||||
if (typeof f !== 'function') {
|
if (typeof f !== 'function') {
|
||||||
throw new Error(qsTranslate('error', 'First argument to filter is not a function.'));
|
throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.'));
|
||||||
}
|
}
|
||||||
if (!Array.isArray(a)) {
|
if (!Array.isArray(a)) {
|
||||||
throw new Error(qsTranslate('error', 'Second argument to filter is not an array.'));
|
throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.'));
|
||||||
}
|
}
|
||||||
return a.filter(function (x, i) {
|
return a.filter(function (x, i) {
|
||||||
return f(x, i);
|
return f(x, i);
|
||||||
|
@ -1773,6 +1773,7 @@ class Parser {
|
||||||
atan2: Math.atan2,
|
atan2: Math.atan2,
|
||||||
'if': condition,
|
'if': condition,
|
||||||
gamma: gamma,
|
gamma: gamma,
|
||||||
|
'Γ': gamma,
|
||||||
roundTo: roundTo,
|
roundTo: roundTo,
|
||||||
map: arrayMap,
|
map: arrayMap,
|
||||||
fold: arrayFold,
|
fold: arrayFold,
|
||||||
|
|
|
@ -98,7 +98,7 @@ class Action {
|
||||||
renderLatexAsHtml(latexString) {
|
renderLatexAsHtml(latexString) {
|
||||||
if(!Latex.enabled)
|
if(!Latex.enabled)
|
||||||
throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.")
|
throw new Error("Cannot render an item as LaTeX when LaTeX is disabled.")
|
||||||
let latexInfo = Latex.Renderer.render(latexString, imageDepth*fontSize+4, themeTextColor).split(",")
|
let latexInfo = Latex.Renderer.render(latexString, imageDepth*(fontSize+2), themeTextColor).split(",")
|
||||||
return `<img src="${latexInfo[0]}" width="${parseInt(latexInfo[1])/imageDepth}" height="${parseInt(latexInfo[2])/imageDepth}" style="vertical-align: middle"></img>`
|
return `<img src="${latexInfo[0]}" width="${parseInt(latexInfo[1])/imageDepth}" height="${parseInt(latexInfo[2])/imageDepth}" style="vertical-align: middle"></img>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ class GainBode extends Common.ExecutableObject {
|
||||||
|
|
||||||
draw(canvas, ctx) {
|
draw(canvas, ctx) {
|
||||||
var base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)]
|
var base = [canvas.x2px(this.om_0.x), canvas.y2px(this.om_0.y)]
|
||||||
var dbfn = new MathLib.Expression(`${this.gain.execute()}*(ln(x)-ln(${this.om_0.x}))/ln(10)+${this.om_0.y}`)
|
var dbfn = new MathLib.Expression(`${this.gain.execute()}*(log10(x)-log10(${this.om_0.x}))+${this.om_0.y}`)
|
||||||
var inDrawDom = new MathLib.EmptySet()
|
var inDrawDom = new MathLib.EmptySet()
|
||||||
|
|
||||||
if(this.pass == 'high') {
|
if(this.pass == 'high') {
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/**
|
||||||
|
* LogarithmPlotter - 2D plotter software to make BODE plots, sequences and distribution functions.
|
||||||
|
* Copyright (C) 2022 Ad5001
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Contains polyfill math functions used for reference.
|
||||||
|
|
||||||
|
.pragma library
|
||||||
|
|
||||||
|
function factorial(x) {
|
||||||
|
if (x < 0) // Integrating by less than 0
|
||||||
|
if(isFinite(n))
|
||||||
|
return Infinity
|
||||||
|
else
|
||||||
|
throw new EvalError("Cannot calculate the factorial of -∞.")
|
||||||
|
|
||||||
|
return gamma(x+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
let GAMMA_G = 4.7421875
|
||||||
|
let GAMMA_P = [
|
||||||
|
0.99999999999999709182,
|
||||||
|
57.156235665862923517, -59.597960355475491248,
|
||||||
|
14.136097974741747174, -0.49191381609762019978,
|
||||||
|
0.33994649984811888699e-4,
|
||||||
|
0.46523628927048575665e-4, -0.98374475304879564677e-4,
|
||||||
|
0.15808870322491248884e-3, -0.21026444172410488319e-3,
|
||||||
|
0.21743961811521264320e-3, -0.16431810653676389022e-3,
|
||||||
|
0.84418223983852743293e-4, -0.26190838401581408670e-4,
|
||||||
|
0.36899182659531622704e-5
|
||||||
|
]
|
||||||
|
|
||||||
|
function gamma(n) {
|
||||||
|
if(n <= 0) // Integrating by less than 0
|
||||||
|
if(isFinite(n))
|
||||||
|
return Infinity
|
||||||
|
else
|
||||||
|
throw new EvalError("Cannot calculate Γ(-∞).")
|
||||||
|
|
||||||
|
if(n >= 171.35)
|
||||||
|
return Infinity // Would return more than 2^1024 - 1 (aka Number.INT_MAX)
|
||||||
|
|
||||||
|
if(n === Math.round(n) && isFinite(n)) {
|
||||||
|
// Calculating (n-1)!
|
||||||
|
let res = n - 1
|
||||||
|
|
||||||
|
for(let i = n - 2; i > 1; i++)
|
||||||
|
res *= i
|
||||||
|
|
||||||
|
if(res === 0)
|
||||||
|
res = 1 // 0! is per definition 1
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section below adapted function adapted from math.js
|
||||||
|
if(n < 0.5)
|
||||||
|
return Math.PI / (Math.sin(Math.PI * n) * gamma(1 - n))
|
||||||
|
|
||||||
|
if(n > 85.0) { // Extended Stirling Approx
|
||||||
|
let twoN = n * n
|
||||||
|
let threeN = twoN * n
|
||||||
|
let fourN = threeN * n
|
||||||
|
let fiveN = fourN * n
|
||||||
|
return Math.sqrt(2 * Math.PI / n) * Math.pow((n / Math.E), n) *
|
||||||
|
(1 + (1 / (12 * n)) + (1 / (288 * twoN)) - (139 / (51840 * threeN)) -
|
||||||
|
(571 / (2488320 * fourN)) + (163879 / (209018880 * fiveN)) +
|
||||||
|
(5246819 / (75246796800 * fiveN * n)))
|
||||||
|
}
|
||||||
|
|
||||||
|
--n
|
||||||
|
let x = GAMMA_P[0]
|
||||||
|
for (let i = 1 i < GAMMA_P.length ++i) {
|
||||||
|
x += GAMMA_P[i] / (n + i)
|
||||||
|
}
|
||||||
|
|
||||||
|
let t = n + GAMMA_G + 0.5
|
||||||
|
return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayMap(f, arr) {
|
||||||
|
if (typeof f != 'function')
|
||||||
|
throw new EvalError(qsTranslate('error', 'First argument to map is not a function.'))
|
||||||
|
if (!Array.isArray(arr))
|
||||||
|
throw new EvalError(qsTranslate('error', 'Second argument to map is not an array.'))
|
||||||
|
return arr.map(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayFold(f, init, arr) {
|
||||||
|
if (typeof f != 'function')
|
||||||
|
throw new EvalError(qsTranslate('error', 'First argument to fold is not a function.'))
|
||||||
|
if (!Array.isArray(arr))
|
||||||
|
throw new EvalError(qsTranslate('error', 'Second argument to fold is not an array.'))
|
||||||
|
return arr.reduce(f, init)
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayFilter(f, arr) {
|
||||||
|
if (typeof f != 'function')
|
||||||
|
throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.'))
|
||||||
|
if (!Array.isArray(arr))
|
||||||
|
throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.'))
|
||||||
|
return arr.filter(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayFilter(f, arr) {
|
||||||
|
if (typeof f != 'function')
|
||||||
|
throw new EvalError(qsTranslate('error', 'First argument to filter is not a function.'))
|
||||||
|
if (!Array.isArray(arr))
|
||||||
|
throw new EvalError(qsTranslate('error', 'Second argument to filter is not an array.'))
|
||||||
|
return arr.filter(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayJoin(sep, arr) {
|
||||||
|
if (!Array.isArray(arr))
|
||||||
|
throw new Error(qsTranslate('error', 'Second argument to join is not an array.'))
|
||||||
|
return arr.join(sep)
|
||||||
|
}
|
||||||
|
|
||||||
|
function indexOf(target, s) {
|
||||||
|
if (!(Array.isArray(s) || typeof s === 'string'))
|
||||||
|
throw new Error(qsTranslate('error', 'Second argument to indexOf is not a string or array.'))
|
||||||
|
return s.indexOf(target)
|
||||||
|
}
|
|
@ -18,54 +18,81 @@
|
||||||
|
|
||||||
.pragma library
|
.pragma library
|
||||||
|
|
||||||
|
.import "polyfill.js" as Polyfill
|
||||||
|
|
||||||
|
|
||||||
const CONSTANTS = {
|
const CONSTANTS = {
|
||||||
"π": Math.PI,
|
"π": Math.PI,
|
||||||
"pi": Math.PI,
|
"pi": Math.PI,
|
||||||
"inf": Infinity,
|
"inf": Infinity,
|
||||||
"infinity": Infinity,
|
"infinity": Infinity,
|
||||||
"∞": Infinity,
|
"∞": Infinity,
|
||||||
"e": Infinity
|
"e": Math.E
|
||||||
};
|
};
|
||||||
const CONSTANTS_LIST = Object.keys(CONSTANTS);
|
const CONSTANTS_LIST = Object.keys(CONSTANTS);
|
||||||
|
|
||||||
const FUNCTIONS = {
|
const FUNCTIONS = {
|
||||||
"abs": Math.abs,
|
// The functions commented are the one either not implemented
|
||||||
"acos": Math.acos,
|
// in the parser, or not to be used for autocompletion.
|
||||||
"acosh": Math.acosh,
|
// Unary operators
|
||||||
"asin": Math.asin,
|
//'+': Number,
|
||||||
"asinh": Math.asinh,
|
//'-': (x) => -x,
|
||||||
"atan": Math.atan,
|
//'!'
|
||||||
"atan2": Math.atan2,
|
// Other operations
|
||||||
"atanh": Math.atanh,
|
'length': (s) => Array.isArray(s) ? s.length : String(s).length,
|
||||||
"cbrt": Math.cbrt,
|
// Boolean functions
|
||||||
"ceil": Math.ceil,
|
'not': (x) => !x,
|
||||||
"clz32": Math.clz32,
|
// Math functions
|
||||||
"cos": Math.cos,
|
'abs': Math.abs,
|
||||||
"cosh": Math.cosh,
|
'acos': Math.acos,
|
||||||
"exp": Math.exp,
|
'acosh': Math.acosh,
|
||||||
"expm1": Math.expm1,
|
'asin': Math.asin,
|
||||||
"floor": Math.floor,
|
'asinh': Math.asinh,
|
||||||
"fround": Math.fround,
|
'atan': Math.atan,
|
||||||
"hypot": Math.hypot,
|
'atan2': Math.atan2,
|
||||||
"imul": Math.imul,
|
'atanh': Math.atanh,
|
||||||
"log": Math.log,
|
'cbrt': Math.cbrt,
|
||||||
"log10": Math.log10,
|
'ceil': Math.ceil,
|
||||||
"log1p": Math.log1p,
|
//'clz32': Math.clz32,
|
||||||
"log2": Math.log2,
|
'cos': Math.cos,
|
||||||
"max": Math.max,
|
'cosh': Math.cosh,
|
||||||
"min": Math.min,
|
'exp': Math.exp,
|
||||||
"pow": Math.log2,
|
'expm1': Math.expm1,
|
||||||
"random": Math.random,
|
'floor': Math.floor,
|
||||||
"round": Math.round,
|
//'fround': Math.fround,
|
||||||
"sign": Math.sign,
|
'hypot': Math.hypot,
|
||||||
"sin": Math.sin,
|
//'imul': Math.imul,
|
||||||
"sinh": Math.sinh,
|
'lg': Math.log10,
|
||||||
"sqrt": Math.sqrt,
|
'ln': Math.log,
|
||||||
"tan": Math.tan,
|
'log': Math.log,
|
||||||
"tanh": Math.tanh,
|
'log10': Math.log10,
|
||||||
"trunc": Math.trunc,
|
'log1p': Math.log1p,
|
||||||
"integral": () => 0, // TODO: Implement
|
'log2': Math.log2,
|
||||||
"derivative": () => 0,
|
'max': Math.max,
|
||||||
|
'min': Math.min,
|
||||||
|
'pow': Math.log2,
|
||||||
|
'random': Math.random,
|
||||||
|
'round': Math.round,
|
||||||
|
'sign': Math.sign,
|
||||||
|
'sin': Math.sin,
|
||||||
|
'sinh': Math.sinh,
|
||||||
|
'sqrt': Math.sqrt,
|
||||||
|
'tan': Math.tan,
|
||||||
|
'tanh': Math.tanh,
|
||||||
|
'trunc': Math.trunc,
|
||||||
|
// Functions in expr-eval, ported here.
|
||||||
|
'fac': Polyfill.factorial,
|
||||||
|
'gamma': Polyfill.gamma,
|
||||||
|
'Γ': Polyfill.gamma,
|
||||||
|
'roundTo': (x, exp) => Number(x).toFixed(exp),
|
||||||
|
'map': Polyfill.arrayMap,
|
||||||
|
'fold': Polyfill.arrayFold,
|
||||||
|
'filter': Polyfill.arrayFilter,
|
||||||
|
'indexOf': Polyfill.indexOf,
|
||||||
|
'join': Polyfill.arrayJoin,
|
||||||
|
// Integral & derivative (only here for autocomplete).
|
||||||
|
'integral': () => 0, // TODO: Implement
|
||||||
|
'derivative': () => 0,
|
||||||
}
|
}
|
||||||
const FUNCTIONS_LIST = Object.keys(FUNCTIONS);
|
const FUNCTIONS_LIST = Object.keys(FUNCTIONS);
|
||||||
// TODO: Complete
|
// TODO: Complete
|
||||||
|
|
Loading…
Reference in a new issue