mathnet / mathnet-symbolics

Math.NET Symbolics
http://symbolics.mathdotnet.com
MIT License
341 stars 66 forks source link

How to add Parsing and Evaluation of the min and max functions #92

Open mpp opened 3 years ago

mpp commented 3 years ago

Hi!

I forked the repo and I'm trying to add min and max functions. I'm completely new to F# and I'm struggling with a compile error (that was obviously not present before my code).

As a total noob I approached the problem by trying to do the same as it was done for the function atan2 as both min and max are functions that take 2 arguments (at least?).

Is this the correct way to do it? Can you give me any suggestion on how to fix the issue?

This is the link to the commit I made: https://github.com/mathnet/mathnet-symbolics/commit/eb7451298da22de72fed3c433d078460aceec698

I get the error

[...]\Workspace\mathnet-symbolics\src\Symbolics\Polynomial.fs(123,69): error FS0001: Type mismatch. Expecting a    'System.Numerics.BigInteger * (Expression * System.Numerics.BigInteger) list -> System.Numerics.BigInteger * (Expression * System.Numerics.BigInteger) list -> System.Numerics.BigInteger * (Expression * System.Numerics.BigInteger) list'    but given a    'BigInteger * (Expression * Expression) list -> BigInteger * (Expression * Expression) list -> System.Numerics.BigInteger * (Expression * Expression) list'    The type 'System.Numerics.BigInteger' does not match the type 'Expression'
    [<CompiledName("CommonMonomialFactors")>]
    let commonMonomialFactors xs =
        let normalizePowers = List.map (fun (r, p) -> pow r (fromInteger p))
        let denormalizePowers = List.map (function
            | PosIntPower (r, (Integer n)) -> (r, n.Numerator)
            | x -> (x, 1I))
        let monomialFactors x =
            let n, xs = Algebraic.factorsInteger x
            n, denormalizePowers xs
        let intersect ((n1:BigInteger),x1) ((n2:BigInteger),x2) =
            let n' = Euclid.GreatestCommonDivisor (n1, n2)
            let x' = x1 |> List.choose (fun (r1, p1) -> x2 |> List.tryPick (fun (r2,p2) -> if r2 = r1 then Some (r1, min p1 p2) else None))
            n', x'
        let (n, x') = xs |> List.map monomialFactors |> List.reduce intersect ///// <- Compile error on _intersect_
        (fromInteger n)::(normalizePowers x') |> product
mpp commented 3 years ago

I found the issue and "solved" it. I had to rename the operators min and max to min2 and max2:

    let min2 (x:Expression) (y:Expression) : Expression = FunctionN (Min, [x;y])
    let max2 (x:Expression) (y:Expression) : Expression = FunctionN (Max, [x;y])
    let arctan2 (x:Expression) (y:Expression) : Expression = FunctionN (Atan2, [x;y])

As they were conflicting with the operators in the Core module.

Is this approach correct and acceptable for a pull request? Are the tests that I added exhaustive?

The code is @ https://github.com/mpp/mathnet-symbolics/commit/d602aae0ed21a942fe56b99c9d525a1a0a935551

pomaton12 commented 6 months ago

Hello, is there a way to get the maximum and minimum value of a polynomial in a given range using this library? example "x^2 -5*x +3" max min in the range 0 < x < 4 in c#