mathnet / mathnet-symbolics Goto Github PK
View Code? Open in Web Editor NEWMath.NET Symbolics
Home Page: http://symbolics.mathdotnet.com
License: MIT License
Math.NET Symbolics
Home Page: http://symbolics.mathdotnet.com
License: MIT License
I want to create a fractal generator that works on complex values.
var z = Expr.Variable("z");
Func<Complex32, Complex32> f = (z * z + z - 6*cos(z*z+z-1)).Compile("z");
Complex32 z = 2 + 3 * Complex32.ImaginaryOne;
Console.WriteLine(f(z));
Is there any workaround to handle this?
Unable to build on Mono 3.12, get F# errors FS0001 insdie the Trignonometic module
Today I updated my local master with the latest origin/master. However, there are no tests in the Test Explorer of Visual Studio. I did followings:
git fetch upstream
git rebase upstream/master
and then run restore.cmd
in the Command Prompt
Am I missing something? Is Expecto.VisualStudio.TestAdapter
needed to be installed?
Quoting the README file:
This project does not aim to become a full computer algebra system
It does make it clear what the project does not aim to be. However, it doesn't say much about what the aims to be. It does say it is a basic Computer Algebra library, but I am not sure what that exactly means. Is it going to support differentiation? Integration?
Having said that, I am wondering why is the aim not to become a full Computer Algebra system? Surely this cannot happen overnight, but why not aim to do this over the long term?
Running tests on a Windows configured to a Brazil locale fails one test because the system uses comma for separating the integer and fractionary parts in a floating-point number, instead of a dot. Test output:
1) Failed : Tests.Constant Expressions
String lengths are both 5. Strings differ at index 1.
Expected: "3.2*x"
But was: "3,2*x"
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.
MathNet.Symbolics.fsx
and MathNet.Numerics.fsx
(for MathNet.Numerics.FSharp) files are absent in according packages folders.
Among others:
sqrt(-1)
sqrt(-1)
and related powersIs there any plan to support the continued fraction (CF)?
Examples I want to cover with CF:
References:
The following code snippet produces (0,-0.33333)
rather than (0.33333,-0.33333)
.
using System;
using static MathNet.Symbolics.SymbolicExpression;
using static System.Console;
using static System.Numerics.Complex;
using Complex = System.Numerics.Complex;
namespace MathNetSymbolicsCompile
{
class Program
{
static readonly Complex i = ImaginaryOne;
static void Main(string[] args)
{
var z = Variable("z");
Func<Complex, Complex> f = (z).CompileComplex("z");
Complex c = 1/3 - i/3 ;
WriteLine(f(c));
}
}
}
The following information might be irrelevant.
I successfully tested it with Xamarin.Forms for UWP, Android and iOS. It is really multi platform library.
Any plans to support .Net Core / Standard? I would love to use this library in my core application (MathNet Numerics in use already).
When evaluating 1/(1/d + a)
with d = 0.0 (and a = 2.0), it returns "not supported". Rational.simplify is required in order to get correct answer, 0.0. However, sometimes, the simplify is very time-consuming job for very long and complex expressions.
Simply, by adding following ComplexInfinity-related rules in the Evaluate module, we can get correct answer.
In fact, Expression has many auto-simplification rules in invert, add, multiply and functions. Is there nice way to re-use the rules of Expression in Evaluate?
The following code snippet does not compile because there are no suitable operators for Complex and SymbolicExpression operands in z * z + i/2
.
using System;
using static MathNet.Symbolics.SymbolicExpression;
using static System.Console;
using static System.Numerics.Complex;
using Complex = System.Numerics.Complex;
namespace MathNetSymbolicsCompile
{
class Program
{
static readonly Complex i = ImaginaryOne;
static void Main(string[] args)
{
var z = Variable("z");
Func<Complex, Complex> f = Parse("z * z + i/2").CompileComplex("z");
Complex c = 1 / 2 - i / 3;
WriteLine(f(c));
}
}
}
Any comments are welcome!
Hello Christoph,
From your source code it seems to me that there is no support for matrix algebra and calculus in the library, is this correct?
Introducing matrix algebra is a pain, I have found, because all of a sudden some product expressions are commutative and others aren't.
Regards,
Eric.
Is there a need for the existence of the Implicit Operator for string in Expression?
mathnet-symbolics/src/Symbolics/Expression.fs
Line 485 in 96a21c9
As this may lead to weird results
For example:
string example = "1a/)";
Expression test = example;
Console.WriteLine(Infix.Format(test)); // => 1a/)
Console.WriteLine(LaTeX.Format(test)); // => {1a/)}
I want to use these lib,but found noting about help documents to these lib.
This Symbolics says that "Expressions always appear in a simplified form according to a set of rules."
If so, how about adding some known rules to the trigonometric functions? For some m/n*pi
(with integer m and n), trigonometric functions can be simply expressed as algebraic numbers. For example, sin(pi/3)
returns sqrt(3)/2
. However, we can't handle all of cases, so, if we limit to just a few cases, we can easily apply this rule with lookup tables.
Rules can be added:
(1) Argument that are rational multiple of pi can be expressed in algebraic numbers: sin(11/12*pi) = (sqrt(3) - 1)/(2*sqrt(2))
, ...
(2) Hence, exponential function can be rewritten as cos and sin terms: exp(m/n*pi*j) = cos(m/n*pi) + j*sin(m/n*pi)
, where j is imaginary unit
(3) Argument that are multiple of j can be expressed in terms of hyperbolic functions: sin(z*j) = j*sinh(z)
, ...
Are there plans to include other operators, like summations (\Sigma), products (\Pi), integrals and so on? What about equations and systems of equations? I'm interested in experimenting with sums and recurrence relations, so it would be good to have the basics available in the library.
I can send a PR with the operators at least, but I wanted to ask first if this is in scope, and where should I add them.
Is there a way to register C# functions to be identified by Infix/Expression?
For example, I would like to parse and evaluate inverse hyperbolic sine function, "ArcSinh(z)" , but it is not yet implemented in the Symbolics.
The way MathNet.Symbolics handles division with infinite and undefined values is a bit incorrect in my opinion: 1/0
evaluates to ComplexInfinity, when I would really expect it to be PositiveInfinity, or even better Undefined, as it does not exist.
The way this kind of cases are handled currently is like a half-assed limit, which is not really ideal. IMO, we should have a separate Limit
module which handles the computation of limits (including situations like infinities), while the expressions alone simplify into Undefined values.
Thanks for the excellent package. When I use the C# example code, most parsing works fine. However, parsing sqrt(x), sinh(x), cosh(x), and tanh(x) all throw parsing errors. Other function, such as sin(x), cos(x), tan(x) all parse fine.
Hello,
First of all, congratulations for Math.Net. It's a wonderful project. You've done a great job.
I'm trying to use Symbolics in a project where I need to parse a standard syntax in order to import expressions.
I didn't find anything about LATEX parsing, but I found a method for parsing MathML: SymbolicExpression.ParseMathML. I tried to use it with some wellformed MathML code, but it always return undefined. What is the matter? Is something wrong in what I do?
Here is an example of MathML code I used
<math display="block"> <mrow> <munderover> <mo>∑<!-- ∑ --></mo> <mrow> <mi>n</mi> <mo>=</mo> <mn>1</mn> </mrow> <mi mathvariant="normal">∞<!-- ∞ --></mi> </munderover> </mrow> <mrow> <mfrac> <mn>1</mn> <msup> <mi>n</mi> <mn>2</mn> </msup> </mfrac> </mrow> <mo>=</mo> <mrow> <mfrac> <msup> <mi>π<!-- π --></mi> <mn>2</mn> </msup> <mn>6</mn> </mfrac> </mrow> </math>
Thanks in advance for any help.
Thanks for building the library, it’s been really useful.
I recently updated to v0.18 in some of our tools. They’ve been security flagged by automated tools for review due to the SHA-1 signing on mathnet symbolics.
I checked, and it looks like the signtool.exe being used can do more secure hashing algorithms e.g. one of the SHA-2 with the /fd flag:
https://msdn.microsoft.com/en-us/library/windows/desktop/jj835835(v=vs.85).aspx
Is it possible to upgrade? It looks to work but I don’t have the corresponding certificate to confirm.
I'm not sure in target of the module NumericLiteralQ
.
The four from five functions is duplicate from the module Operators
The last one function FromString
is simple, so maybe better just remove this module?
The Antiderivative module is not yet implemented in this product. I am not sure how easily the Risch algorithm or others can be added, but I think it may be a long way to go. So as a workaround, we can think about approximation theory.
Like the Taylor series, we can approximate functions with orthogonal polynomials such as Chebyshev's. In this way, we can easily get an indefinite integral of the function as in Matlab's ChebFun library.
I'd like to know what you think about this.
Hi,
Is there a way to modify how the latex formatting is done. I'd love to get "\cdot" for the multication operator. And I'd love to force the formatting to respect the order. For exemple :
string expr = "L1*U1+L2";
var latex = Expr.Parse(expr).ToLaTeX();
Gives "L2 + L1U1"
I want "U1\cdot U1 +L2"
Best regards.
If I try to install the library using Nuget in a Xamarin project I get the following error:
Attempting to gather dependency information for package 'MathNet.Symbolics.0.15.0' with respect to project 'SciCalc', targeting 'MonoAndroid,Version=v6.0'
Gathering dependency information took 16,96 sec
Attempting to resolve dependencies for package 'MathNet.Symbolics.0.15.0' with DependencyBehavior 'Highest'
Resolving dependency information took 0 ms
Resolving actions to install package 'MathNet.Symbolics.0.15.0'
Resolved actions to install package 'MathNet.Symbolics.0.15.0'
Found package 'MathNet.Symbolics 0.15.0' in 'C:\Users\berto\documents\visual studio 2017\Projects\SciCalc\packages'.
Install failed. Rolling back...
Package 'MathNet.Symbolics.0.15.0 : FParsec [1.0.1, ), FSharp.Core [3.1.2.5, ), MathNet.Numerics [3.8.0, ), MathNet.Numerics.FSharp [3.8.0, )' does not exist in project 'SciCalc'
Executing nuget actions took 17,8 ms
Could not install package 'MathNet.Symbolics 0.15.0'. You are trying to install this package into a project that targets 'MonoAndroid,Version=v6.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
Time Elapsed: 00:00:16.9977911
========== Finished ==========
Now, I tried using the precompiled versions directly and they work fine, so I guess it's just a matter of correctly configuring the nuspec files.
I think the differential formulas of the inverse trigonometric functions are incorrect. I'm not familiar with F#, but Calculus.fs
needs to be modified as follows:
let rec differentiate symbol = function
...
| Function (Asin, x) -> (1Q / sqrt(1Q - pow x 2Q)) * (differentiate symbol x)
| Function (Acos, x) -> (-1Q / sqrt(1Q - pow x 2Q)) * (differentiate symbol x)
| Function (Atan, x) -> (1Q / (1Q + pow x 2Q)) * (differentiate symbol x)
No. | Input | Return | Expected |
---|---|---|---|
(a) | -1Q**2 | 1 | -1 |
(b) | negate (one**two) | -1 | -1 |
(c) | 0 - 1Q**2 | -1 | -1 |
(d) | -(x+y)**2 | (x + y)^2 | -(x + y)^2 |
(e) | -1*(x+y)**2 | -(x + y)^2 | -(x + y)^2 |
Excel calculates -1^2
as 1
, but we have to think it as -(1^2)
.
Error in the output when using Infix.print and LaTeX.print in the case of complex degree.
Example:
open MathNet.Symbolics
let str = "2*x^(2*y) + exp^(3*y)"
let expr = str |> Infix.parseOrUndefined
expr |> Infix.print |> printfn "%s"
expr |> LaTeX.print |> printfn "%s"
Print:
exp^3*y + 2*x^2*y
exp^3y + 2x^2y
Thus, not enough parentheses.
P.S. Infix.printStrict works good.
Hello, my problem is the following: I am working with unity3d in C # language and when I want to declare a variable, I need to specify the type of variable first, it does not allow me to place the word "var", and try all the types of variable that the program but I always get that you can not convert any type to the expression type.
how should I do it? Thanks for the help
It seems, that currently formatting for display floating numbers (type approximation) not very convenient.
open MathNet.Symbolics
let culture = System.Globalization.CultureInfo.InvariantCulture
"0.4095999999999994*x+13.5387777776*y"
|> Infix.parseOrUndefined
|> Infix.format
|> printfn "%s" // => 0.409599999999999*x + 13.5387777776*y
I think that better round off a number to 5-6 decimals before formatting:
open System
let test_f1 = 0.409123554
let test_f2 = 0.4123
//current
test_f1.ToString(culture) |> printfn "%s" // => 0.409123554
test_f2.ToString(culture) |> printfn "%s" // => 0.4123
//one option
test_f1 |> printfn "%f" // => 0.409124
test_f2 |> printfn "%f" // => 0.412300
//second option
let round6 (v : float) = Math.Round(v, 6)
(test_f1 |> round6).ToString(culture)
|> printfn "%s" // => 0.409124
(test_f2 |> round6).ToString(culture)
|> printfn "%s" // => 0.4123
I like both options though second more usual for me
Thank you for changing it to allow sqrt, etc. I just switched from 0.9 to 1.0 to test this, and I can't get the "Evaluate.Evaluate()" function to work in C#. This function previously accepted two arguments (symbols, expression), but now it seems to accept just one argument (symbols). I'm not familiar with f#, so it is hard to tell how to provide the expression argument to the evaluate function.
Thanks.
Using C# nuget package MathNet.Symbolics, ver 0.20.0
Parsing this expression "29^11^7" leads to freeze.
Tried with
Infix.ParseOrUndefined("29^11^7");
and
SymbolicExpression.Parse("29^11^7")
When tried to put parenthesis it works fine
"(29^11)^7"
I do some tests to understand how Approximation works by using SymbolicExpression.Parse(infix).
Infix string | Expression | RealValue | Note |
---|---|---|---|
1.2 | Approximation (Real 1.2) | 1.2 | |
1.0 + 1/5 | Approximation (Real 1.2) | 1.2 | |
1 + 1.0/5 | Number 6/5N | 1.2 | Bug? |
1 + 1/5 | Number 6/5N | 1.2 | |
6/5 | Number 6/5N | 1.2 | |
6.0/5 | Approximation (Real 1.2) | 1.2000000000000002 | |
6.0/5 - 6/5 | Approximation ... | 2.2204460492503131E-16 | Machine Epsilon |
When an inexact number, or a number with explicit decimal point is given in an expression, it should be approximated. It is strange that real 1.0 / 5Q
returns 1/5
not 0.2
. The problem is that the active pattern One
is used in multiply
.
real 1.0 / 5Q
-> multiply Approximation(Real 1.0) Number1/5N
-> multiply One Number1/5N
-> Number1/5N
.
Maybe it makes sense to expand section "Math.NET Symbolics with C#" in documentation with example with VB.NET, C++/CLI ?
Infix.parse has troubles parsing the E-notation Infix.Format (and also FormatStrict) generates:
2*soll_14_0_0 + 0.05*soll_14_1_0 + (-6)*x_0_0_0 + (-6.40869140625E-05)*x_0_1_0
^Expecting: infix operator or ')'
So the issue is that it is currently not possible to format and then re-parse infix expressions.
Is there a faster or at least different way to serialize expressions to workaround the issue in the meanwhile?
Best regards,
Patricck
Consider using the Algebraic.Expand method to expand a binomial like the following: (1+(2*3^(1/2))x)^2
- I would expect an answer of the form 1 + (4*3^(1/2))x + 12x^2
, but instead I get '43^(1/2)' and '43x^2' in each case (having run through LaTeX.Format) - it is clear that there is a missing multiplication sign here. Not sure if this is my usage or an issue with the library.
The output for LaTeX
is similar as in Infix.format. But this format looks not always beautiful.
For example:
let value = "(cos(tan(sqrt(x))))/(2*sqrt(x)*cos(sqrt(x))^2) "
let expr = value |> Infix.parseOrUndefined
let format = expr |> Infix.format
let latex = expr |> LaTeX.format
//\frac{\frac{1}{2}{x}^{\left(-\frac{1}{2}\right)}\cos{\tan{\sqrt[2]{x}}}}{{\left(\cos{\sqrt[2]{x}}\right)}^{2}}
Question: might make sense to change the formatting to the more familiar form for the LaTeX
?
This issue originated from this question.
The InFix.Parse
method should support handling of cases like
Infix.ParseOrThrow("1.5*apples + oranges");
Right now the expression Infix.parse "pi"
returns ParsedResult
of an identifier (i.e. symbol "pi"
) .
updating the identifier
parser solves this problem
let identifier : Expression parser =
let isIdentifierFirstChar c = isLetter c
let isIdentifierChar c = isLetter c || isDigit c
many1Satisfy2L isIdentifierFirstChar isIdentifierChar "identifier" .>> ws
|>> function // differentating between constants and identifiers
| "pi" -> Expression.Constant Pi
| "e" -> Expression.Constant E
| "oo" | "inf" -> Expression.Constant PositiveInfinity // 'oo' from sympy
| "j" -> Expression.Constant I
| id -> Expression.Symbol id
now it works:
Infix.parse "pi"
// val it : ParseResult = ParsedExpression π
It seems that support for function Ctg
is missing. I think it makes sense to add it. I can do it, but I would like to know which option is better:
tg
when parsing (so, add ctg
to the class Pseudo)it seems that tensor algebra is completely missing as of now, so I am wondering how the plans are to include support for higher calculus.
I guess it might be useful to also have some graphical visualization of tensors, similar to penrose's graphical notation.
References
I think hardcoding "x" more than once should be avoided because it is error prone. It potentially causes runtime errors.
var x = Expr.Variable("x");
Func<double, double> f = (x * x + x - 6).Compile("x");
Console.WriteLine(f(0));
My suggestion is as follows:
var x = Expr.Variable("x");
Func<double, double> f = (x * x + x - 6).Compile(x);
Console.WriteLine(f(0));
Any comments are welcome. Thank you.
Hi,
Is there a way to define a finite real sequence indexed by integers. I'd like to evaluate an expression such as "u(1)+u(2)" where u is defined by an explicit sequence of real numbers such as u(1)= 12 and u(2)= 25. I don't want to create a finite set a expr u1, u2... More Func object need an algebraic expression.
Best regards.
For symbolic computation, treating 2/3 as 0 is not so elegant. Should we write 2.0/3 or 2/3.0 or 2.0/3.0 to avoid "flooring" in symbolic computation?
var x = Variable("x");
Func<double, double> f = (x+2/3).Compile("x");// it will be interpreted as f = x + floor(2/3) = x
double c = 1.0 / 3;
f(c).ToString(); // produces 0.333333
Any suggestions are always welcome! Thank you!
Here's a simple Mathematica evaluation:
Note that l[f[x]] // Simplify
returns the same expression as m[x] // Simplify
.
Here's the equivalent in Symbolics/C#:
Expression f(Expression x) => 2 - x;
Expression g(Expression x) => 2 / x;
Expression h(Expression x) => f(g(x));
Expression l(Expression x) => g(h(x));
Expression m(Expression x) => h(h(x));
{
var x = Expression.Symbol("x");
Console.WriteLine(Infix.Format(Rational.Simplify(x, l(f(x)))));
Console.WriteLine(Infix.Format(Rational.Simplify(x, m(x))));
}
It outputs the following:
(2 - x)/(1 - x)
(-2 + x)/(-1 + x)
Is there a simplification routine in Symbolics which will simplify both cases to the same expression?
Thanks!
(PS: I've been experimenting a bit with Symbolics in C# and its a really nice system. Thanks Christoph!)
Currently, it seems that there are three different simplify functions in different modules - Rational, Trigonometric and Exponential. I would like to have an all-in-one simplify function to make things easier.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.