mathnet/mathnet-symbolics

Discussion: The design and extensibility of the library

Zaid-Ajaj opened this issue · 5 comments

I would like to open here a small discussion about the library and share some ideas with you guys for future contributions. First of all, I think this is a really exciting project to work with, and because of F#, it is also a whole lot of fun. On that I think we agree. Lets now turn to the library and to be specific, lets talk about how the Function is implemented.

Right now, if someone would want to come and implement a new function like arcsec(x) for example, (s)he would have to add a new case for the Function discriminated union and then update ALL THE FUNCTIONS that do matching over Function like the differentiate, evaluate, print, fapply etc. and thats one problem.

The second problem is that we don't have a definition for a purely symbolic function. By a symbolic function I mean just a function f that when applied to x where x = Symbol("x") it just returns f(x) or when you ask it for a derivative it returns Derivative(f, x), why would we need this? considor the case when you have written an ODE solver (ordinary differential equation solver) then you need a way to define a differential equation in terms of these symbolic functions and pass it to the solver.

Ok, concerning the first problem. I think an elegant way to solve it is by means of F#'s OOP capabilities. I am not an expert on OOP but I do understand it a bit. defining an abstract calss (interface?) of Function that exposes members like Differentiate, Evaluate, Integrate, Apply, Print, PrintLaTex etc. would make adding new functions very trivial and easy and it would only require inheriting the Function class and providing custom definitions for the required members. For example adding custom evaluation when a function is applied to a vector, a matrix or a scalar (real or complex). One doesn't have to update other functions already defined but build on top of them. Another benefit we get from this is for example we can make a definiton for piece-wise functions and have them evaluate according to certain rules. This however, requires a bit of work rewriting the current implementation of the functions. But since the library is small, this is still doable.

I havn't thought much about solving the second problem but I just wanted to share it with you.

I came across these problems when I tried to make the library interoperable with Sympy; a full-fledged CAS written in python.I was only able to open a little bridge between sympy and this library where you can do interesting things from within the library:

cos(x)**8
|> Trigonometric.contract
|> Sympy.integrate x
//  (35*x)/128 + (7*sin(2*x))/32 + (7*sin(4*x))/128 + sin(6*x)/96 + sin(8*x)/1024

Another thing to think about is way for defining Assumptions. for example (a+b)(a+b)/(a+b) will simplify to just (a+b) but forgetting the fact that this is defined only when a does not equal -b. i. e. It could be something like this using piece-wise functions:

let f = simplify <| (a+b)(a+b)/(a+b)

then f would be this: Piecewise(a+b, a+b <> 0, Undefined) which means the function f returns a + b when a + b <> 0 or it returns Undefined otherwise.

I am wondering if we could compile SymPy to .NET using IronPython. This would erase the need for the user to install a Python Environment (which is not possible on some devices).

@Zaid-Ajaj May I ask why you decide to close the issue?

@FoggyFinder Maintainers seem to have no interest in this issue. It has been almost one and half years since I opened it

I certainly have interest in this. I appreciate the reasoning, thoughts and time you've put into this, and agree mostly. My time and live priorities are a different matter though; sorry for not following up with more than a thumbs-up!

Please allow me to reopen it, since it is still relevant.