1

Is there a way to print the expression string after the scope substitutions?

var n = math.compile('x * 2');
n.eval({x:2}); // returns 4

// I WISH I could do this:
n.toString({x:2}); // returns '2 * 2'
Scott
  • 3,204
  • 3
  • 31
  • 41
  • I could use variable substitution (as commented and deleted), but I feel like it would get complicated solving for all of the permutations of expressions. For example: `'apple*banana + a' {apple: 2, banana: 3, a: 4}`. If mathjs has already solved these, I'd like to use it. – Scott May 01 '19 at 19:47
  • Did you get anywhere with this? Looking to do something similar. Doesn't look like there's a simple way. Thinking I'll have to write a custom function, iterate through the nodes, and if the node is a SymbolNode then evaluate it using the scope... – rjoxford Apr 21 '20 at 12:07

1 Answers1

0

It is first necessary to understand the way that MathJS parses to Expression Trees, and the different types of nodes used. You can read more here in the docs.

Algebraic variables get parsed as SymbolNodes. These will need to be substituted for their values. The simplest way to do this would be to use the transform function, which is explained in the API further down the page given above.

From the Docs

transform(callback: function)

Recursively transform an expression tree via a transform function. Similar to Array.map, but recursively executed on all nodes in the expression tree. The callback function is a mapping function accepting a node, and returning a replacement for the node or the original node. Function callback is called as callback(node: Node, path: string, parent: Node) for every node in the tree, and must return a Node. Parameter path is a string containing a relative JSON Path.

The transform function will stop iterating when a node is replaced by the callback function, it will not iterate over replaced nodes.

For example, to replace all nodes of type SymbolNode having name ‘x’ with a ConstantNode with value 3:

const node = math.parse('x^2 + 5*x')
const transformed = node.transform(function (node, path, parent) {
  if (node.isSymbolNode && node.name === 'x') {
    return new math.expression.node.ConstantNode(3)
  }
  else {
    return node
  }
})
transformed.toString() // returns '3 ^ 2 + 5 * 3'
Community
  • 1
  • 1
rjoxford
  • 351
  • 3
  • 12
  • There's a shortcoming here... eg if x=3 then 2x get printed as 23, not 2*3. Will look to develop this solution when possible to allow for this. – rjoxford Apr 22 '20 at 09:34