Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement symbols for CAS computations #1732

Closed
cshaa opened this issue Feb 2, 2020 · 11 comments
Closed

Implement symbols for CAS computations #1732

cshaa opened this issue Feb 2, 2020 · 11 comments

Comments

@cshaa
Copy link
Collaborator

cshaa commented Feb 2, 2020

Advanced CAS systems let users define their own symbols and perform symbolic operations with them. Example in Sympy. Since all math.js functions can operate on complex numbers (that means they have to call add and mul methods instead of JavaScript + and * operators), it should be really straightforward to implement something like SymbolicExpression (EDIT: already implemented as Node) which behaves like a number but remembers the symbols involved.

Example usage:

let [x, y] = math.symbols('x y')
math.evaluate('det( [[ 1, x ],[ y, 0 ]] )', {x, y})
// - x * y
@josdejong
Copy link
Owner

Thanks for your input Michal. So far we already have SymbolNode, which is for example used for symbolic computations in the functions simplify and derivative. Is that what you mean?

See docs: https://mathjs.org/docs/expressions/algebra.html

@cshaa
Copy link
Collaborator Author

cshaa commented Feb 6, 2020

Well, SymbolNode is an internal API and I don't see how it can be used by users right now. If I modify my example to use SymbolNode, it doesn't work:

let x = new math.SymbolNode('x');
let y = new math.SymbolNode('y');
math.evaluate('det( [[ 1, x ],[ y, 0 ]] )', {x, y});
// "Unexpected type of argument in function multiplyScalar (expected: number or Complex or BigNumber or Fraction or Unit or string or boolean, actual: Node, index: 0)"

I know simplify and derivative allow for symbolic computation, but those are the only places where mathjs allows for symbolic computation. In a true CAS, symbols are first-class citizens that can be used anywhere you like.

Of course the implementation of symbols should leverage the existing functionality. After looking into the Algebra chapter of the docs, I think that allowing arithmetical operations on Node object would be enough for my example (and many other potential uses of symbols) to work.

So should I go ahead and try implementing arithmetics on Node?

@josdejong
Copy link
Owner

In a true CAS, symbols are first-class citizens that can be used anywhere you like.

I understand what you mean. The SymbolNode is public API though. We could definitely extend all functions in mathjs to support these nodes, so math.add(new SymbolNode('x'), 2) would return an OperatorNode with the SymbolNode(x) and a ConstantNode(2). I think we discussed this somewhere before but I can't find it.

I'm not sure though if that is what you are really looking for. The example you give:

let [x, y] = math.symbols('x y')
math.evaluate('det( [[ 1, x ],[ y, 0 ]] )', {x, y})
// - x * y

is solving an equation. It may be enough to implement a function solve(expr, variable), similar to the existing function derivative(expr, variable), without the need to implement support for Node in all functions. Would that address your needs?

Implementing a function solve is discussed here: #38

@cshaa
Copy link
Collaborator Author

cshaa commented Feb 9, 2020

Thanks for your comment, I'll start working on this in a week!

Just to clarify: I didn't mean solving an equation, I really meant computing the determinant with the symbol x in the upper right corner and the symbol y in the left bottom corner. Determinant in 2×2 matrices is just A₁₁ A₂₂ − A₁₂ A₂₁ = 1·0−x·y = −xy. But that's just nitpicking, not especially important for the gist of this issue 😅️

@josdejong
Copy link
Owner

Thanks for your comment, I'll start working on this in a week!

That sounds good :). I don't yet have a clear idea on what you're going to implement exactly and whether that's something generic that we can put in mathjs. "the determinant with the symbol x in the upper right corner and the symbol y in the left bottom corner" sounds very specific to me?

@cshaa
Copy link
Collaborator Author

cshaa commented Feb 12, 2020

I started fiddling with the implementation, but I got stuck very early. I wanted to add this overload for the add function:

'Node, any': function(x, y) {
  return new OperatorNode('+', 'add', [clone(x), clone(y)])
},

However, when I try to add OperatorNode as a dependency for add, tests fail with Uncaught Error: some dependencies are missing. After investigating little further, I found out that everything in /expression/node depends on mathWithTransform, which means it can only load after the whole core of mathjs is done, right? Isn't there a way to use OperatorNode in add without creating a deadlock? Or should I somehow move the code “downstream” to /expression/node?


In a reply to your previous comment: Determinants are used very often in antisymetrization problems, which are quite wide-spread across several disciplines (see Jacobian, Hessian, Wronskian, Slater, Vandermonde determinants), so imho it's one of the operations you'd want to perform on symbols quite often. But I'll make an actual showcase once I have a working prototype :)

@josdejong
Copy link
Owner

Did you add OperatorNode as a new dependency on top of the add function?

@cshaa
Copy link
Collaborator Author

cshaa commented Feb 14, 2020

Yes, that's exactly what I did. And this alone was enough to stop the project from compiling loading successfully via require.

@josdejong
Copy link
Owner

@m93a I created a small proof of concept of being able to use function addScalar to add two Nodes. see this PR: #1747

@josdejong
Copy link
Owner

Closing the POC of #1747 in favor of #2475

@gwhitney
Copy link
Collaborator

gwhitney commented Oct 6, 2023

This is a very valuable idea, and has spurred multiple POCs (including one I did myself), but still is rather more of a Discussion than an issue. Hence, moving.

Repository owner locked and limited conversation to collaborators Oct 6, 2023
@gwhitney gwhitney converted this issue into discussion #3061 Oct 6, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants