Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- "use strict";
- const variablesArray = ["x",
- "y",
- "z"
- ];
- const consts = new Set();
- const operations = new Map();
- const variables = new Map(variablesArray.map((s, id, variablesArray) => [s, id]));
- function Operation(sign, calc, ...args) {
- this.calc = calc;
- this.args = args;
- this.evaluate = function (...other) {
- return calc.apply(this, args.map(x => x.evaluate(...other)));
- };
- this.toString = function () {
- return args.reduce((pr, cur) => pr + cur.toString() + " ", "")
- + sign + (this.caller == null ? "" : " ");
- };
- this.diff = function (variable) {
- return this.calcDiff.apply(this, args.concat(variable));
- }
- }
- function createOperation(name, calc, calcDiff) {
- function inner(...args) {
- Operation.call(this, name, calc, ...args);
- this.calcDiff = calcDiff;
- }
- inner.countOfArguments = calc.length;
- operations.set(name, inner);
- return inner;
- }
- function hf(arg, calcDiff, v) {
- return new Multiply(arg.diff(v), calcDiff(arg))
- }
- function linearDiff(f) {
- return new f(x.diff(v), y.diff(v));
- }
- const Add = createOperation("+", (x, y) => x + y,
- (x, y, v) => linearDiff(Add));
- const Subtract = createOperation("-", (x, y) => x - y,
- (x, y, v) => linearDiff(Subtract));
- const Multiply = createOperation("*", (x, y) => x * y,
- (x, y, v) => new Add(new Multiply(x.diff(v), y), new Multiply(y.diff(v), x)));
- const Divide = createOperation("/", (x, y) => x / y, (x, y, v) =>
- new Divide(new Subtract(new Multiply(x.diff(v), y), new Multiply(y.diff(v), x)), new Multiply(y, y)));
- const Cosh = createOperation("cosh", x => Math.cosh(x),
- (x, v) => hf(x, arg => new Sinh(arg), v));
- const Sinh = createOperation("sinh", x => Math.sinh(x),
- (x, v) => hf(x, arg => new Cosh(arg), v));
- const Negate = createOperation("negate", x => -x,
- (x, v) => new Negate(x.diff(v)));
- const Power = createOperation("pow", (x, y) => Math.pow(x, y),
- (x, y, v) => new Exp(new Multiply(new Ln(x), y)).diff(v)
- );
- const Log = createOperation("log", (x, y) => Math.log(Math.abs(y)) / Math.log(Math.abs(x)),
- (x, y, v) => new Divide(new Ln(y), new Ln(x)).diff(v)
- );
- const Exp = createOperation("exp", x => Math.exp(x), (x, v) => hf(x, x => new Exp(x), v));
- const Ln = createOperation("ln", x => Math.log(Math.abs(x)), (x, v) =>
- hf(x, x => new Divide(new Const(1), x), v));
- const Const = function (value) {
- this.value = value;
- this.evaluate = function (...other) {
- return this.value;
- };
- this.toString = () => String(this.value);
- this.diff = (variable) => new Const(0);
- };
- const Variable = function (value) {
- this.value = value;
- this.id = variables.get(value);
- this.evaluate = function (...other) {
- return other[this.id];
- };
- this.toString = () => this.value;
- this.diff = (variable) => new Const((variable === this.value ? 1 : 0));
- };
- function parse(str) {
- const nextChar = () => str.charAt(ch++);
- const isOperation = s => operations.has(s);
- const curChar = () => str.charAt(ch);
- const hasNextChar = () => ch < str.length;
- const isVariable = s => variables.has(s);
- function skipWhitespaces() {
- for (; curChar() === " "; nextChar()) ;
- }
- function parseToken() {
- let res = "";
- for (; curChar() !== " " && hasNextChar(); res+=nextChar()) ;
- return res;
- }
- function getOperation(s) {
- let g = operations.get(s), res = [];
- for (let i = 0; i < g.countOfArguments; i++) {
- res.push(stack.pop());
- }
- res.reverse();
- return new g(...res);
- }
- function getNumber(s) {
- return consts.has(s) ? consts.get(s) : new Const(Number.parseFloat(s));
- }
- function parseTokenAndPush() {
- skipWhitespaces();
- let s = parseToken();
- stack.push(isOperation(s) ? getOperation(s) : isVariable(s) ? new Variable(s) : getNumber(s));
- }
- let stack = [];
- let ch = 0;
- while (hasNextChar()) {
- parseTokenAndPush();
- }
- return stack[0];
- }
- function test() {
- let expression = parse("x x * 2 x * + 1 +");
- for (let x = 0; x <= 10; x++) {
- console.log(expression.evaluate(x, x, x));
- }
- }
- //test();
- console.log(new Power(new Variable("x"), new Variable("y")).diff("x").evaluate(2, 2, 2));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement