Advertisement
Guest User

Untitled

a guest
Apr 2nd, 2020
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.38 KB | None | 0 0
  1. "use strict";
  2. const variablesArray = ["x",
  3. "y",
  4. "z"
  5. ];
  6. const consts = new Set();
  7. const operations = new Map();
  8. const variables = new Map(variablesArray.map((s, id, variablesArray) => [s, id]));
  9.  
  10. function Operation(sign, calc, ...args) {
  11. this.calc = calc;
  12. this.args = args;
  13. this.evaluate = function (...other) {
  14. return calc.apply(this, args.map(x => x.evaluate(...other)));
  15. };
  16. this.toString = function () {
  17. return args.reduce((pr, cur) => pr + cur.toString() + " ", "")
  18. + sign + (this.caller == null ? "" : " ");
  19. };
  20. this.diff = function (variable) {
  21. return this.calcDiff.apply(this, args.concat(variable));
  22. }
  23. }
  24.  
  25. function createOperation(name, calc, calcDiff) {
  26. function inner(...args) {
  27. Operation.call(this, name, calc, ...args);
  28. this.calcDiff = calcDiff;
  29. }
  30. inner.countOfArguments = calc.length;
  31. operations.set(name, inner);
  32. return inner;
  33. }
  34. function hf(arg, calcDiff, v) {
  35. return new Multiply(arg.diff(v), calcDiff(arg))
  36. }
  37. function linearDiff(f) {
  38. return new f(x.diff(v), y.diff(v));
  39. }
  40. const Add = createOperation("+", (x, y) => x + y,
  41. (x, y, v) => linearDiff(Add));
  42.  
  43. const Subtract = createOperation("-", (x, y) => x - y,
  44. (x, y, v) => linearDiff(Subtract));
  45.  
  46. const Multiply = createOperation("*", (x, y) => x * y,
  47. (x, y, v) => new Add(new Multiply(x.diff(v), y), new Multiply(y.diff(v), x)));
  48.  
  49. const Divide = createOperation("/", (x, y) => x / y, (x, y, v) =>
  50. new Divide(new Subtract(new Multiply(x.diff(v), y), new Multiply(y.diff(v), x)), new Multiply(y, y)));
  51.  
  52. const Cosh = createOperation("cosh", x => Math.cosh(x),
  53. (x, v) => hf(x, arg => new Sinh(arg), v));
  54. const Sinh = createOperation("sinh", x => Math.sinh(x),
  55. (x, v) => hf(x, arg => new Cosh(arg), v));
  56.  
  57. const Negate = createOperation("negate", x => -x,
  58. (x, v) => new Negate(x.diff(v)));
  59.  
  60. const Power = createOperation("pow", (x, y) => Math.pow(x, y),
  61. (x, y, v) => new Exp(new Multiply(new Ln(x), y)).diff(v)
  62. );
  63. const Log = createOperation("log", (x, y) => Math.log(Math.abs(y)) / Math.log(Math.abs(x)),
  64. (x, y, v) => new Divide(new Ln(y), new Ln(x)).diff(v)
  65. );
  66. const Exp = createOperation("exp", x => Math.exp(x), (x, v) => hf(x, x => new Exp(x), v));
  67. const Ln = createOperation("ln", x => Math.log(Math.abs(x)), (x, v) =>
  68. hf(x, x => new Divide(new Const(1), x), v));
  69.  
  70. const Const = function (value) {
  71. this.value = value;
  72. this.evaluate = function (...other) {
  73. return this.value;
  74. };
  75. this.toString = () => String(this.value);
  76. this.diff = (variable) => new Const(0);
  77. };
  78.  
  79.  
  80. const Variable = function (value) {
  81. this.value = value;
  82. this.id = variables.get(value);
  83. this.evaluate = function (...other) {
  84. return other[this.id];
  85. };
  86. this.toString = () => this.value;
  87. this.diff = (variable) => new Const((variable === this.value ? 1 : 0));
  88. };
  89.  
  90. function parse(str) {
  91. const nextChar = () => str.charAt(ch++);
  92. const isOperation = s => operations.has(s);
  93. const curChar = () => str.charAt(ch);
  94. const hasNextChar = () => ch < str.length;
  95. const isVariable = s => variables.has(s);
  96.  
  97. function skipWhitespaces() {
  98. for (; curChar() === " "; nextChar()) ;
  99. }
  100.  
  101. function parseToken() {
  102. let res = "";
  103. for (; curChar() !== " " && hasNextChar(); res+=nextChar()) ;
  104. return res;
  105. }
  106.  
  107. function getOperation(s) {
  108. let g = operations.get(s), res = [];
  109. for (let i = 0; i < g.countOfArguments; i++) {
  110. res.push(stack.pop());
  111. }
  112. res.reverse();
  113. return new g(...res);
  114. }
  115.  
  116. function getNumber(s) {
  117. return consts.has(s) ? consts.get(s) : new Const(Number.parseFloat(s));
  118. }
  119.  
  120. function parseTokenAndPush() {
  121. skipWhitespaces();
  122. let s = parseToken();
  123. stack.push(isOperation(s) ? getOperation(s) : isVariable(s) ? new Variable(s) : getNumber(s));
  124. }
  125.  
  126. let stack = [];
  127. let ch = 0;
  128. while (hasNextChar()) {
  129. parseTokenAndPush();
  130. }
  131. return stack[0];
  132. }
  133.  
  134. function test() {
  135. let expression = parse("x x * 2 x * + 1 +");
  136. for (let x = 0; x <= 10; x++) {
  137. console.log(expression.evaluate(x, x, x));
  138. }
  139. }
  140. //test();
  141. 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