Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Symbolics.Tests/Compilation/Compilation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ module Compilation =

let expr9 = x + 1
(Compile.compileExpression1OrThrow expr9 symX).Invoke(1.0) --> 2.0

let expr10 = min2 x y
(Compile.compileExpression2OrThrow expr10 symX symY).Invoke(12.5, 5.7) --> System.Math.Min(12.5, 5.7)

let expr11 = max2 x y
(Compile.compileExpression2OrThrow expr11 symX symY).Invoke(12.5, 5.7) --> System.Math.Max(12.5, 5.7)

let expr1' = x
(Compile.compileComplexExpression1OrThrow expr1' symX).Invoke(toComplex 3.0) --> toComplex 3.0
Expand Down
8 changes: 8 additions & 0 deletions src/Symbolics.Tests/Visual/Infix.fs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ module Infix =
Infix.parseOrUndefined "sin x-1" ==> "Undefined"
Infix.parseOrUndefined "sin -x" ==> "sin - x"
Infix.parseOrUndefined "sin" ==> "sin"

Infix.parseOrUndefined "min(x,y)" ==> "min(x,y)"
Infix.parseOrUndefined "min ( x , y )" ==> "min(x,y)"
Infix.parseOrUndefined " min ( - x, - y ) " ==> "min(-x,-y)"

Infix.parseOrUndefined "max(x,y)" ==> "max(x,y)"
Infix.parseOrUndefined "max ( x , y )" ==> "max(x,y)"
Infix.parseOrUndefined " max ( - x, - y ) " ==> "max(-x,-y)"

Infix.parseOrUndefined "atan2(x,y)" ==> "atan2(x,y)"
Infix.parseOrUndefined "atan2 ( x , y )" ==> "atan2(x,y)"
Expand Down
10 changes: 10 additions & 0 deletions src/Symbolics/Approximation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ module Approximation =
let atan = function
| Real a -> Real (Trig.Atan a)
| Complex a -> Complex (Trig.Atan a)
let min x y =
match x, y with
| Real a, Real b -> Real (Math.Min (a, b))
| _ -> failwith "not supported"
let max x y =
match x, y with
| Real a, Real b -> Real (Math.Max (a, b))
| _ -> failwith "not supported"
let atan2 x y =
match x, y with
| Real a, Real b -> Real (Math.Atan2 (a, b))
Expand Down Expand Up @@ -257,6 +265,8 @@ module Approximation =

let applyN f xs =
match f, xs with
| Min, [x; y] -> min x y
| Max, [x; y] -> max x y
| Atan2, [x; y] -> atan2 x y
| Log, [b; x] -> log b x
| BesselJ, [nu; x] -> besselj nu x
Expand Down
2 changes: 2 additions & 0 deletions src/Symbolics/Calculus.fs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ module Calculus =
| Function (AiryAiPrime, x) -> (differentiate symbol x) * x * airyai(x)
| Function (AiryBi, x) -> (differentiate symbol x) * airybiprime(x)
| Function (AiryBiPrime, x) -> (differentiate symbol x) * x * airybi(x)
| FunctionN (Min, _) -> failwith "not supported"
| FunctionN (Max, _) -> failwith "not supported"
| FunctionN (Atan2, [x; y]) -> differentiate symbol (tan (x / y))
| FunctionN (Log, [b; x]) -> differentiate symbol ((ln x) / (ln b))
| FunctionN (BesselJ, [nu; x]) -> (differentiate symbol x) * ((besselj (nu - 1Q) x) - (besselj (nu + 1Q) x)) / 2Q
Expand Down
2 changes: 2 additions & 0 deletions src/Symbolics/Evaluate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ module Evaluate =

let fapplyN f xs =
match f, xs with
| Min, [Real x; Real y] -> Real (Math.Min(x, y))
| Max, [Real x; Real y] -> Real (Math.Max(x, y))
| Atan2, [Real x; Real y] -> Real (Math.Atan2(x, y))
| Atan2, [Complex x; Real y] -> Complex (Complex.atan (x / (complex y 0.0)))
| Atan2, [Complex x; Complex y] -> Complex (Complex.atan (x / y))
Expand Down
7 changes: 7 additions & 0 deletions src/Symbolics/Expression.fs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,8 @@ module Operators =
| Number n when n.IsNegative -> Function (Atan, Number -n) |> negate // atan(-x) = -atan(x)
| Product ((Number n)::ax) when n.IsNegative -> Function (Atan, multiply (Number -n) (Product ax)) |> negate
| x -> Function (Atan, x)
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])
let arccsc : Expression -> Expression = function
| Undefined | ComplexInfinity -> undefined
Expand Down Expand Up @@ -858,6 +860,8 @@ module Operators =

let applyN (f: FunctionN) (xs: Expression list) : Expression =
match f, xs with
| Min, [x;y] -> min2 x y
| Max, [x;y] -> max2 x y
| Atan2, [x;y] -> arctan2 x y
| Log, [b; x] -> log b x
| BesselJ, [nu; x] -> besselj nu x
Expand Down Expand Up @@ -959,6 +963,9 @@ type Expression with

static member HankelH1 (n, x) = Operators.hankelh1 n x // Hankel Function of the First Kind
static member HankelH2 (n, x) = Operators.hankelh2 n x // Hankel Function of the Second Kind

static member Min (x, y) = Operators.min2 x y
static member Max (x, y) = Operators.max2 x y

static member Apply (f, x) = Operators.apply f x
static member ApplyN (f, xs) = Operators.applyN f xs
Expand Down
2 changes: 2 additions & 0 deletions src/Symbolics/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type Function =

type FunctionN =
| Log
| Min
| Max
| Atan2
| BesselJ // Bessel function of the first kind
| BesselY // Bessel function of the second kind
Expand Down
18 changes: 15 additions & 3 deletions src/Symbolics/Typed/Linq.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module Linq =
| Product ax -> product <| List.map denominator ax
| _ -> one

let private toLambda (expr : MathNet.Symbolics.Expression) (args : Symbol list) (valueType : Type) (mathType : Type) constant value add mul div pow atan2 log abs besselj bessely besseli besselk besseliratio besselkratio hankelh1 hankelh2 : LambdaExpression option =
let private toLambda (expr : MathNet.Symbolics.Expression) (args : Symbol list) (valueType : Type) (mathType : Type) constant value add mul div pow min max atan2 log abs besselj bessely besseli besselk besseliratio besselkratio hankelh1 hankelh2 : LambdaExpression option =
let valueTypeArr1 = [| valueType |]
let valueTypeArr2 = [| valueType; valueType |]
let argName = function |Symbol(n) -> n
Expand Down Expand Up @@ -96,6 +96,14 @@ module Linq =
let f = convertFunc func
let e = convertExpr par
Option.map2 id f e
| FunctionN(Min, [x;y]) ->
let exprX = convertExpr x
let exprY = convertExpr y
Option.map2 min exprX exprY
| FunctionN(Max, [x;y]) ->
let exprX = convertExpr x
let exprY = convertExpr y
Option.map2 max exprX exprY
| FunctionN(Atan2, [x;y]) ->
let exprX = convertExpr x
let exprY = convertExpr y
Expand Down Expand Up @@ -209,6 +217,8 @@ module Linq =
let mathCall1 (name : string) (a : Expression) = Expression.Call(mathType.GetMethod(name, [| valueType |]), a) :> Expression
let mathCall2 (name : string) (a : Expression) (b : Expression) = Expression.Call(mathType.GetMethod(name, [| valueType; valueType |]), a, b) :> Expression
let pow = mathCall2 "Pow"
let min = mathCall2 "Min"
let max = mathCall2 "Max"
let atan2 = mathCall2 "Atan2"
let log a b = mathCall2 "Log" b a
let abs = mathCall1 "Abs"
Expand All @@ -220,7 +230,7 @@ module Linq =
let besselkratio = mathCall2 "BesselKRatio"
let hankelh1 = mathCall2 "HankelH1"
let hankelh2 = mathCall2 "HankelH2"
toLambda expr args valueType mathType constant value add mul div pow atan2 log abs besselj bessely besseli besselk besseliratio besselkratio hankelh1 hankelh2
toLambda expr args valueType mathType constant value add mul div pow min max atan2 log abs besselj bessely besseli besselk besseliratio besselkratio hankelh1 hankelh2

[<CompiledName("FormatComplexLambda")>]
let formatComplexLambda (expr : MathNet.Symbolics.Expression) (args : Symbol list) : LambdaExpression option =
Expand All @@ -242,6 +252,8 @@ module Linq =
let mul = mathCall2 "Multiply"
let div = mathCall2 "Divide"
let pow = mathCall2 "Pow"
let min = mathCall2 "Min"
let max = mathCall2 "Max"
let atan2 a b = mathCall1 "Atan" (div a b)
let log a b =
let ln = mathCall1 "Log"
Expand All @@ -255,4 +267,4 @@ module Linq =
let besselkratio = mathCall2 "BesselKRatio"
let hankelh1 = mathCall2 "HankelH1"
let hankelh2 = mathCall2 "HankelH2"
toLambda expr args valueType mathType constant value add mul div pow atan2 log abs besselj bessely besseli besselk besseliratio besselkratio hankelh1 hankelh2
toLambda expr args valueType mathType constant value add mul div pow min max atan2 log abs besselj bessely besseli besselk besseliratio besselkratio hankelh1 hankelh2
16 changes: 16 additions & 0 deletions src/Symbolics/Typed/TypedExpression.fs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,26 @@ module TypedExpression =
| (ValueType.Real | ValueType.Rational), ValueType.Complex -> ValueType.Complex
| _ -> ValueType.Undefined
TypedExpression.FunctionN (t, (Log, [cb; cx]))
| FunctionN (Min, xs) ->
let cs = xs |> List.map convert
let t = cs |> List.map enrichedType |> List.fold mergeType ValueType.Real
TypedExpression.FunctionN (t, (Min, cs))
| FunctionN (Max, xs) ->
let cs = xs |> List.map convert
let t = cs |> List.map enrichedType |> List.fold mergeType ValueType.Real
TypedExpression.FunctionN (t, (Max, cs))
| FunctionN (Atan2, xs) ->
let cs = xs |> List.map convert
let t = cs |> List.map enrichedType |> List.fold mergeType ValueType.Real
TypedExpression.FunctionN (t, (Atan2, cs))
| FunctionN (Min, xs) ->
let cs = xs |> List.map convert
let t = cs |> List.map enrichedType |> List.fold mergeType ValueType.Real
TypedExpression.FunctionN (t, (Min, cs))
| FunctionN (Max, xs) ->
let cs = xs |> List.map convert
let t = cs |> List.map enrichedType |> List.fold mergeType ValueType.Real
TypedExpression.FunctionN (t, (Max, cs))
| FunctionN ((BesselJ | BesselY | BesselI | BesselK | BesselIRatio | BesselKRatio | HankelH1 | HankelH2) as f, [nu; z]) ->
let cnu = convert nu
let cz = convert z
Expand Down
2 changes: 2 additions & 0 deletions src/Symbolics/Visual/LaTeX.fs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ module private LaTeXFormatter =
| x -> sprintf "\\operatorname{%s}" x
let latexFunctionNName = function
| "log" -> "\\log"
| "min" -> "\\operatorname{min}"
| "max" -> "\\operatorname{max}"
| "atan" -> "\\operatorname{atan2}"
| x -> sprintf "\\operatorname{%s}" x

Expand Down