├── .gitattributes
├── .gitignore
├── ComputerAlgebra.Plotting
├── ComputerAlgebra.Plotting.csproj
└── Plotting
│ ├── Plot.cs
│ ├── Series.cs
│ └── SeriesCollection.cs
├── ComputerAlgebra.sln
├── ComputerAlgebra
├── ComputerAlgebra.csproj
├── Expression
│ ├── Arrow.cs
│ ├── Atom.cs
│ ├── Binary.cs
│ ├── Call.cs
│ ├── Constant.cs
│ ├── Equal.cs
│ ├── Expression.cs
│ ├── Functions
│ │ ├── ExprFunction.cs
│ │ ├── Function.cs
│ │ ├── LutFunction.cs
│ │ ├── NativeFunction.cs
│ │ ├── StmtFunction.cs
│ │ └── UnknownFunction.cs
│ ├── Matrix.cs
│ ├── Power.cs
│ ├── Product
│ │ ├── Multiply.cs
│ │ └── Product.cs
│ ├── Sets
│ │ ├── FiniteSet.cs
│ │ ├── Rings.cs
│ │ └── Set.cs
│ ├── Substitute.cs
│ ├── Sum
│ │ ├── Add.cs
│ │ ├── LinearCombination.cs
│ │ ├── Polynomial.cs
│ │ └── Sum.cs
│ ├── Unary.cs
│ ├── Variable.cs
│ └── Visitors
│ │ ├── CachedRecursiveVisitor.cs
│ │ ├── RecursiveVisitor.cs
│ │ └── Visitor.cs
├── Extensions
│ ├── AlgebraicEquivalents.cs
│ ├── DSolve.cs
│ ├── DependsOn.cs
│ ├── Differentiate.cs
│ ├── Evaluate.cs
│ ├── Expand.cs
│ ├── Factor.cs
│ ├── Integrate.cs
│ ├── LaTeX.cs
│ ├── LaplaceTransform.cs
│ ├── NSolve.cs
│ ├── Parse.cs
│ ├── PrettyString.cs
│ ├── Resolve.cs
│ ├── Simplify.cs
│ ├── SolutionSet.cs
│ ├── Solve.cs
│ ├── Substitute.cs
│ └── SystemOfEquations.cs
├── LinqCompiler
│ ├── CodeGen.cs
│ ├── CompileExpression.cs
│ ├── CompileExtension.cs
│ ├── CompileStatement.cs
│ ├── DeclContext.cs
│ ├── GlobalExpr.cs
│ ├── Module.cs
│ └── StandardMath.cs
├── Namespace
│ ├── DynamicNamespace.cs
│ ├── Global
│ │ ├── ExpFunction.cs
│ │ ├── GlobalNamespace.cs
│ │ ├── IfFunction.cs
│ │ ├── LnFunction.cs
│ │ └── SqrtFunction.cs
│ ├── Namespace.cs
│ ├── NamespaceSet.cs
│ ├── ObjectNamespace.cs
│ └── TypeNamespace.cs
├── Statement
│ ├── Assignment.cs
│ ├── Block.cs
│ ├── BreakContinue.cs
│ ├── DoWhile.cs
│ ├── For.cs
│ ├── If.cs
│ ├── Return.cs
│ ├── Statement.cs
│ ├── Visitors
│ │ └── Visitor.cs
│ └── While.cs
├── Transform
│ ├── AlgebraTransform.cs
│ ├── CachedTransform.cs
│ ├── LinearTransform.cs
│ ├── PatternTransform.cs
│ ├── SubstituteTransform.cs
│ ├── Transform.cs
│ └── TransformSet.cs
└── Utils
│ ├── BigFloat.cs
│ ├── BigIntegerExtensions.cs
│ ├── BigRational.cs
│ ├── Combinatorics.cs
│ ├── CustomAttribute.cs
│ ├── DefaultDictionary.cs
│ ├── DictionaryExtensions.cs
│ ├── EnumerableExtensions.cs
│ ├── ExpressionConverter.cs
│ ├── LazyExpression.cs
│ ├── ListExtensions.cs
│ ├── MatchContext.cs
│ ├── Real.cs
│ ├── RealConverter.cs
│ ├── ReferenceEqualityComparer.cs
│ └── StringVisitor.cs
├── Console
├── Console.csproj
└── Program.cs
├── Demo
├── Intro
│ ├── App.config
│ ├── Intro.csproj
│ └── Program.cs
├── LotkaVolterra
│ ├── App.config
│ ├── LotkaVolterra.csproj
│ └── Program.cs
└── LotkaVolterraCpp
│ ├── LotkaVolterraCpp.vcxproj
│ ├── LotkaVolterraCpp.vcxproj.filters
│ └── Main.cpp
├── LICENSE
├── README.md
└── Tests
├── Program.cs
└── Tests.csproj
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # Visual Studio 2015/2017 cache/options directory
20 | .vs/
21 |
22 | # External tool builders
23 | .externalToolBuilders/
24 |
25 | # Locally stored "Eclipse launch configurations"
26 | *.launch
27 |
28 | # CDT-specific
29 | .cproject
30 |
31 | # PDT-specific
32 | .buildpath
33 |
34 |
35 | #################
36 | ## Visual Studio
37 | #################
38 |
39 | ## Ignore Visual Studio temporary files, build results, and
40 | ## files generated by popular Visual Studio add-ons.
41 |
42 | # User-specific files
43 | *.suo
44 | *.user
45 | *.sln.docstates
46 |
47 | # Build results
48 | [Dd]ebug/
49 | [Rr]elease/
50 | *_i.c
51 | *_p.c
52 | *.ilk
53 | *.meta
54 | *.obj
55 | *.pch
56 | *.pdb
57 | *.pgc
58 | *.pgd
59 | *.rsp
60 | *.sbr
61 | *.tlb
62 | *.tli
63 | *.tlh
64 | *.tmp
65 | *.vspscc
66 | .builds
67 | *.dotCover
68 |
69 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
70 | #packages/
71 |
72 | # Visual C++ cache files
73 | ipch/
74 | *.aps
75 | *.ncb
76 | *.opensdf
77 | *.sdf
78 |
79 | # Visual Studio profiler
80 | *.psess
81 | *.vsp
82 |
83 | # ReSharper is a .NET coding add-in
84 | _ReSharper*
85 |
86 | # Installshield output folder
87 | [Ee]xpress
88 |
89 | # DocProject is a documentation generator add-in
90 | DocProject/buildhelp/
91 | DocProject/Help/*.HxT
92 | DocProject/Help/*.HxC
93 | DocProject/Help/*.hhc
94 | DocProject/Help/*.hhk
95 | DocProject/Help/*.hhp
96 | DocProject/Help/Html2
97 | DocProject/Help/html
98 |
99 | # Click-Once directory
100 | publish
101 |
102 | # Others
103 | [Bb]in
104 | [Oo]bj
105 | sql
106 | TestResults
107 | *.Cache
108 | ClientBin
109 | stylecop.*
110 | ~$*
111 | *.dbmdl
112 | Generated_Code #added for RIA/Silverlight projects
113 |
114 | # Backup & report files from converting an old project file to a newer
115 | # Visual Studio version. Backup files are not needed, because we have git ;-)
116 | _UpgradeReport_Files/
117 | Backup*/
118 | UpgradeLog*.XML
119 |
120 |
121 |
122 | ############
123 | ## Windows
124 | ############
125 |
126 | # Windows image file caches
127 | Thumbs.db
128 |
129 | # Folder config file
130 | Desktop.ini
131 |
132 |
133 | #############
134 | ## Python
135 | #############
136 |
137 | *.py[co]
138 |
139 | # Packages
140 | *.egg
141 | *.egg-info
142 | dist
143 | build
144 | eggs
145 | parts
146 | bin
147 | var
148 | sdist
149 | develop-eggs
150 | .installed.cfg
151 |
152 | # Installer logs
153 | pip-log.txt
154 |
155 | # Unit test / coverage reports
156 | .coverage
157 | .tox
158 |
159 | #Translations
160 | *.mo
161 |
162 | #Mr Developer
163 | .mr.developer.cfg
164 |
165 | # Mac crap
166 | .DS_Store
167 |
--------------------------------------------------------------------------------
/ComputerAlgebra.Plotting/ComputerAlgebra.Plotting.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Library
4 | net6.0-windows
5 | true
6 | ComputerAlgebra.Plotting
7 | ComputerAlgebra.Plotting
8 | Copyright © 2020
9 | 1.0.0.0
10 | 1.0.0.0
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ComputerAlgebra.Plotting/Plotting/Series.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using Matrix2D = System.Drawing.Drawing2D.Matrix;
6 |
7 | namespace ComputerAlgebra.Plotting
8 | {
9 | public enum PointStyle
10 | {
11 | None,
12 | Square,
13 | Circle,
14 | Cross,
15 | }
16 |
17 | ///
18 | /// A data series.
19 | ///
20 | public abstract class Series
21 | {
22 | private string name = "y[x]";
23 | public string Name { get { return name; } set { name = value; } }
24 |
25 | private Pen pen = null;
26 | public Pen Pen { get { return pen != null ? pen : Pens.Transparent; } set { pen = value; } }
27 |
28 | protected PointStyle pointStyle = PointStyle.Square;
29 | public PointStyle PointStyle { get { return pointStyle; } set { pointStyle = value; } }
30 |
31 | public abstract List Evaluate(double x0, double x1);
32 |
33 | public void Paint(Matrix2D T, double x0, double x1, Graphics G)
34 | {
35 | Pen pen = Pen;
36 | List points = Evaluate(x0, x1);
37 | foreach (PointF[] i in points)
38 | {
39 | T.TransformPoints(i);
40 | G.DrawLines(pen, i);
41 | }
42 | }
43 |
44 | protected static float ToFloat(double x)
45 | {
46 | if (x > 1e6)
47 | return 1e6f;
48 | else if (x < -1e6)
49 | return -1e6f;
50 | else
51 | return (float)x;
52 | }
53 | }
54 |
55 | ///
56 | /// Data series derived from a lambda function.
57 | ///
58 | public class Function : Series
59 | {
60 | protected Func f;
61 | public Function(Func f) { this.f = f; }
62 |
63 | public override List Evaluate(double x0, double x1)
64 | {
65 | int N = 2048;
66 |
67 | List points = new List();
68 |
69 | List run = new List();
70 | for (int i = 0; i <= N; ++i)
71 | {
72 | double x = ((x1 - x0) * i) / N + x0;
73 | float fx = ToFloat(f(x));
74 |
75 | if (double.IsNaN(fx) || float.IsInfinity(fx))
76 | {
77 | if (run.Count > 1)
78 | points.Add(run.ToArray());
79 | run.Clear();
80 | }
81 | else
82 | {
83 | run.Add(new PointF((float)x, fx));
84 | }
85 | }
86 | if (run.Count > 1)
87 | points.Add(run.ToArray());
88 |
89 | return points;
90 | }
91 | }
92 |
93 | ///
94 | /// Explicit point list.
95 | ///
96 | public class Scatter : Series
97 | {
98 | protected PointF[] points;
99 | public Scatter(KeyValuePair[] Points)
100 | {
101 | points = Points.Select(i => new PointF((float)i.Key, ToFloat(i.Value))).ToArray();
102 | }
103 |
104 | public override List Evaluate(double x0, double x1)
105 | {
106 | return new List() { points.ToArray() };
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/ComputerAlgebra/ComputerAlgebra.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 | Library
5 | ComputerAlgebra
6 | ComputerAlgebra
7 | Copyright © 2020
8 | 1.0.0.0
9 | 1.0.0.0
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Arrow.cs:
--------------------------------------------------------------------------------
1 | namespace ComputerAlgebra
2 | {
3 | ///
4 | /// Represents an x -> y expression.
5 | ///
6 | public class Arrow : Binary
7 | {
8 | protected Arrow(Expression L, Expression R) : base(Operator.Arrow, L, R) { }
9 | public static Arrow New(Expression L, Expression R) { return new Arrow(L, R); }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Atom.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace ComputerAlgebra
6 | {
7 | ///
8 | /// An Expression class that has Atoms = { this }. Atom classes will always compare to other atoms successfully.
9 | ///
10 | public abstract class Atom : Expression
11 | {
12 | protected virtual int TypeRank { get { return 3; } }
13 |
14 | public override sealed IEnumerable Atoms { get { yield return this; } }
15 |
16 | // object
17 | public override abstract int GetHashCode();
18 | public override int CompareTo(Expression R)
19 | {
20 | if (R is Atom RA)
21 | return TypeRank.CompareTo(RA.TypeRank);
22 |
23 | return base.CompareTo(R);
24 | }
25 | }
26 |
27 | ///
28 | /// Atom with a name.
29 | ///
30 | public class NamedAtom : Atom
31 | {
32 | private ulong cmp;
33 |
34 | private string name;
35 | public string Name { get { return name; } }
36 |
37 | protected NamedAtom(string Name)
38 | {
39 | name = Name;
40 |
41 | // Put the first few characters in an integer for fast comparisons.
42 | cmp = 0;
43 | int length = Marshal.SizeOf(cmp) / 2;
44 | for (int i = 0; i < Math.Min(name.Length, length); ++i)
45 | cmp |= (ulong)name[i] << ((length - i - 1) * 16);
46 | }
47 |
48 | public override int GetHashCode() { return name.GetHashCode(); }
49 | public override bool Equals(Expression E)
50 | {
51 | NamedAtom A = E as NamedAtom;
52 | if (E is null || A is null)
53 | return base.Equals(E);
54 | return Equals(name, A.name);
55 | }
56 | public override int CompareTo(Expression R)
57 | {
58 | if (R is NamedAtom RA)
59 | {
60 | int c = TypeRank.CompareTo(RA.TypeRank);
61 | if (c != 0) return c;
62 |
63 | // Try comparing the first 4 chars of the name.
64 | c = cmp.CompareTo(RA.cmp);
65 | if (c != 0)
66 | return c;
67 |
68 | // First 4 chars match, need to use the full compare.
69 | return String.Compare(name, RA.name, StringComparison.Ordinal);
70 | }
71 |
72 | return base.CompareTo(R);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Constant.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ComputerAlgebra
4 | {
5 | public class Constant : Atom
6 | {
7 | protected Real x;
8 | public Real Value { get { return x; } }
9 |
10 | protected Constant(Real x) { this.x = x; }
11 |
12 | private static readonly Constant NegativeOne = new Constant(-1);
13 | private static readonly Constant Zero = new Constant(0);
14 | private static readonly Constant One = new Constant(1);
15 |
16 | public static Constant New(int x)
17 | {
18 | if (x == -1) return NegativeOne;
19 | if (x == 0) return Zero;
20 | if (x == 1) return One;
21 | return new Constant(x);
22 | }
23 | public static Constant New(double x) { return new Constant(x); }
24 | public static Constant New(decimal x) { return new Constant(x); }
25 | public static Constant New(Real x) { return new Constant(x); }
26 | public static Constant New(bool x) { return x ? One : Zero; }
27 | public static Expression New(object x)
28 | {
29 | if (x is int i) return New(i);
30 | if (x is double dbl) return New(dbl);
31 | if (x is decimal d) return New(d);
32 | if (x is bool b) return New(b);
33 | if (x is Real r) return New(r);
34 | throw new InvalidCastException();
35 | }
36 |
37 | public override bool IsInteger() { return x.IsInteger(); }
38 | public override bool EqualsZero() { return x.EqualsZero(); }
39 | public override bool EqualsOne() { return x.EqualsOne(); }
40 | public override bool IsFalse() { return EqualsZero(); }
41 | public override bool IsTrue() { return !EqualsZero(); }
42 |
43 | public static implicit operator Real(Constant x) { return x.x; }
44 |
45 | public static implicit operator Constant(Real x) { return Constant.New(x); }
46 | public static implicit operator Constant(BigRational x) { return Constant.New(x); }
47 | public static implicit operator Constant(decimal x) { return Constant.New(x); }
48 | public static implicit operator Constant(double x) { return Constant.New(x); }
49 | public static implicit operator Constant(int x) { return Constant.New(x); }
50 |
51 | // Atom.
52 | protected override int TypeRank { get { return 3; } }
53 |
54 | // object interface.
55 | public override int GetHashCode() { return x.GetHashCode(); }
56 |
57 | // Note that this is *not* an arithmetic comparison, it is a canonicalization ordering.
58 | public override int CompareTo(Expression R)
59 | {
60 | if (R is Constant RC)
61 | return Real.Abs(RC.Value).CompareTo(Real.Abs(Value));
62 | return base.CompareTo(R);
63 | }
64 | public override bool Equals(Expression E)
65 | {
66 | if (E is Constant C)
67 | return Value.Equals(C.Value);
68 | return base.Equals(E);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Equal.cs:
--------------------------------------------------------------------------------
1 | namespace ComputerAlgebra
2 | {
3 | ///
4 | /// Represents an x == y expression.
5 | ///
6 | public class Equal : Binary
7 | {
8 | protected Equal(Expression L, Expression R) : base(Operator.Equal, L, R) { }
9 | public static Equal New(Expression L, Expression R) { return new Equal(L, R); }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Functions/ExprFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace ComputerAlgebra
6 | {
7 | ///
8 | /// Function defined by an expression.
9 | ///
10 | public class ExprFunction : Function
11 | {
12 | private Expression body;
13 | ///
14 | /// Get the body of this function.
15 | ///
16 | public Expression Body { get { return body; } }
17 |
18 | private IEnumerable parameters;
19 | public override IEnumerable Parameters { get { return parameters; } }
20 |
21 | private ExprFunction(string Name, Expression Body, IEnumerable Params) : base(Name)
22 | {
23 | if (Body is null)
24 | throw new ArgumentNullException("Body");
25 |
26 | body = Body;
27 | parameters = Params;
28 | }
29 |
30 | ///
31 | /// Create a new anonymous function defined by an expression.
32 | ///
33 | ///
34 | ///
35 | ///
36 | public static ExprFunction New(Expression Body, IEnumerable Params) { return new ExprFunction("", Body, Params.Buffer()); }
37 | public static ExprFunction New(Expression Body, params Variable[] Params) { return New(Body, Params.AsEnumerable()); }
38 |
39 | ///
40 | /// Create a new named function defined by an expression.
41 | ///
42 | ///
43 | ///
44 | ///
45 | ///
46 | public static ExprFunction New(string Name, Expression Body, IEnumerable Params) { return new ExprFunction(Name, Body, Params.Buffer()); }
47 | public static ExprFunction New(string Name, Expression Body, params Variable[] Params) { return New(Name, Body, Params.AsEnumerable()); }
48 |
49 | public override Expression Call(IEnumerable Args) { return body.Evaluate(parameters.Zip(Args, (a, b) => Arrow.New(a, b))); }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Functions/Function.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace ComputerAlgebra
5 | {
6 | ///
7 | /// Base class for a function.
8 | ///
9 | public abstract class Function : NamedAtom
10 | {
11 | protected Function(string Name) : base(Name) { }
12 |
13 | ///
14 | /// Enumerate the parameters of this function.
15 | ///
16 | public abstract IEnumerable Parameters { get; }
17 |
18 | ///
19 | /// Evaluate this function with the given arguments.
20 | ///
21 | ///
22 | ///
23 | public abstract Expression Call(IEnumerable Args);
24 | public Expression Call(params Expression[] Args) { return Call(Args.AsEnumerable()); }
25 |
26 | ///
27 | /// Check if this function could be called with the given parameters.
28 | ///
29 | ///
30 | ///
31 | public virtual bool CanCall(IEnumerable Args) { return CanCall() && Parameters.Count() == Args.Count(); }
32 | public virtual bool CanCall() { return true; }
33 |
34 | ///
35 | /// Check if a call to this function with the given arguments matches an expression.
36 | ///
37 | ///
38 | ///
39 | ///
40 | ///
41 | public virtual bool CallMatches(IEnumerable Arguments, Expression E, MatchContext Matched)
42 | {
43 | if (E is Call EF)
44 | {
45 | if (!Equals(EF.Target))
46 | return false;
47 | if (Arguments.Count() != EF.Arguments.Count())
48 | return false;
49 |
50 | return Matched.TryMatch(() => Arguments.Reverse().Zip(EF.Arguments.Reverse(), (p, e) => p.Matches(e, Matched)).All());
51 | }
52 |
53 | return false;
54 | }
55 |
56 | ///
57 | /// Check if a call to this function with the given arguments is equal to an expression.
58 | ///
59 | ///
60 | ///
61 | ///
62 | public virtual bool CallEquals(IEnumerable Arguments, Expression E)
63 | {
64 | if (E is Call C)
65 | return Equals(C.Target) && Arguments.SequenceEqual(C.Arguments);
66 |
67 | return false;
68 | }
69 |
70 | ///
71 | /// Substitute the variables into the expressions.
72 | ///
73 | ///
74 | ///
75 | ///
76 | public virtual Expression Substitute(Call C, IDictionary x0, bool IsTransform)
77 | {
78 | return ComputerAlgebra.Call.New(C.Target, C.Arguments.Select(i => i.Substitute(x0, IsTransform)));
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Functions/LutFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace ComputerAlgebra
6 | {
7 | ///
8 | /// Function defined by a lookup table with linear interpolation.
9 | ///
10 | public class LutFunction : Function
11 | {
12 | private List parameters;
13 | public override IEnumerable Parameters { get { return parameters; } }
14 |
15 | private SortedDictionary points = new SortedDictionary();
16 |
17 | private LutFunction(string Name, IEnumerable Points) : base(Name)
18 | {
19 | parameters = new List() { Variable.New("x1") };
20 | foreach (Arrow i in Points)
21 | points.Add((double)i.Left, (double)i.Right);
22 | }
23 |
24 | public static LutFunction New(string Name, IEnumerable Points) { return new LutFunction(Name, Points); }
25 |
26 | public override Expression Call(IEnumerable Args)
27 | {
28 | double x = (double)Args.Single();
29 |
30 | throw new NotImplementedException();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ComputerAlgebra/Expression/Functions/NativeFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace ComputerAlgebra
7 | {
8 | ///
9 | /// Attribute for disallowing substition through a function.
10 | ///
11 | [AttributeUsage(AttributeTargets.Parameter)]
12 | public class NoSubstitute : Attribute
13 | {
14 | public NoSubstitute() { }
15 | }
16 |
17 | ///
18 | /// Function defined by a native function.
19 | ///
20 | public class NativeFunction : Function
21 | {
22 | private object _this = null;
23 | ///
24 | /// Object instance of which the method is a member of.
25 | ///
26 | public object This { get { return _this; } }
27 |
28 | private MethodInfo method;
29 | ///
30 | /// Method to call to implement a call to this function.
31 | ///
32 | public MethodInfo Method { get { return method; } }
33 |
34 | public override IEnumerable Parameters { get { return Method.GetParameters().Select(i => Variable.New(i.Name)); } }
35 |
36 | protected NativeFunction(string Name, object This, MethodInfo Method)
37 | : base(Name)
38 | {
39 | _this = This;
40 | method = Method;
41 | }
42 |
43 | ///
44 | /// Create a new Function object implemented by a static method.
45 | ///
46 | ///
47 | ///
48 | public static NativeFunction New(MethodInfo Method) { return new NativeFunction(Method.Name, null, Method); }
49 | ///
50 | /// Create a new Function object implemented by a non-static method.
51 | ///
52 | ///
53 | ///
54 | ///
55 | public static NativeFunction New(object This, MethodInfo Method) { return new NativeFunction(Method.Name, This, Method); }
56 | public static NativeFunction New(string Name, object This, MethodInfo Method) { return new NativeFunction(Name, This, Method); }
57 | ///
58 | /// Create a new Function object implemented by a Delegate.
59 | ///
60 | ///
61 | ///
62 | ///
63 | ///
64 | //public static NativeFunction New(string Name, Delegate Method) { return new NativeFunction(Name, Method, Method.GetMethodInfo()); }
65 | public static NativeFunction New(string Name, T Method) { return new NativeFunction(Name, Method, typeof(T).GetMethod("Invoke")); }
66 |
67 | public override Expression Call(IEnumerable Args)
68 | {
69 | if (!Args.Zip(Method.GetParameters(), (a, p) => p.ParameterType.IsAssignableFrom(a.GetType())).All())
70 | return null;
71 |
72 | try
73 | {
74 | object ret = Method.Invoke(_this, Args.ToArray