-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMathObjectHelper.cs
254 lines (222 loc) · 9.08 KB
/
MathObjectHelper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
* MetaphysicsIndustries.Solus
* Copyright (C) 2006-2022 Metaphysics Industries, Inc., Richard Sartor
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
*/
using System;
using System.Linq;
using MetaphysicsIndustries.Solus.Exceptions;
using MetaphysicsIndustries.Solus.Expressions;
using MetaphysicsIndustries.Solus.Functions;
using MetaphysicsIndustries.Solus.Sets;
using MetaphysicsIndustries.Solus.Values;
using Boolean = System.Boolean;
namespace MetaphysicsIndustries.Solus
{
public static class MathObjectHelper
{
public static bool IsIsScalar(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsScalar(env);
return iss.HasValue && iss.Value;
}
public static bool IsIsBoolean(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsBoolean(env);
return iss.HasValue && iss.Value;
}
public static bool IsIsVector(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsVector(env);
return iss.HasValue && iss.Value;
}
public static bool IsIsMatrix(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsMatrix(env);
return iss.HasValue && iss.Value;
}
public static bool IsIsString(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsString(env);
return iss.HasValue && iss.Value;
}
public static bool IsIsInterval(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsInterval(env);
return iss.HasValue && iss.Value;
}
public static bool IsIsFunction(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsFunction(env);
return iss.HasValue && iss.Value;
}
public static bool IsIsExpression(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsExpression(env);
return iss.HasValue && iss.Value;
}
// TODO: pass to the object; don't rely on inheritance
public static bool IsIsComponentAccess(this IMathObject mo) =>
mo is ComponentAccess;
public static bool IsIsFunctionCall(this IMathObject mo) =>
mo is FunctionCall;
public static bool IsIsIntervalExpression(this IMathObject mo) =>
mo is IntervalExpression;
public static bool IsIsLiteral(this IMathObject mo) =>
mo is Literal;
public static bool IsIsTensorExpression(this IMathObject mo) =>
mo is TensorExpression;
public static bool IsIsMatrixExpression(this IMathObject mo) =>
mo is MatrixExpression;
public static bool IsIsVectorExpression(this IMathObject mo) =>
mo is VectorExpression;
public static bool IsIsVariableAccess(this IMathObject mo) =>
mo is VariableAccess;
public static bool IsIsSet(this IMathObject mo,
SolusEnvironment env)
{
var iss = mo.IsSet(env);
return iss.HasValue && iss.Value;
}
public static Number ToNumber(this IMathObject mo) => (Number) mo;
public static StringValue ToStringValue(this IMathObject mo) =>
(StringValue) mo;
public static IVector ToVector(this IMathObject mo) => (IVector) mo;
public static IMatrix ToMatrix(this IMathObject mo) => (IMatrix) mo;
public static Number ToNumber(this float value) => new Number(value);
public static Number ToNumber(this int value) => new Number(value);
public static Number ToNumber(this long value) => new Number(value);
public static Values.Boolean ToBoolean(this bool value) =>
new Values.Boolean(value);
public static Vector ToVector(this float[] values) =>
new Vector(values);
public static Vector ToVector(this int[] values) =>
new Vector(values.Select(v => (float) v).ToArray());
public static Matrix ToMatrix(this float[,] values) =>
new Matrix(values);
public static StringValue ToStringValue(this string value) =>
new StringValue(value);
public static StringValue ToStringValue(this char value) =>
value.ToString().ToStringValue();
public static float ToFloat(this IMathObject value) =>
value.ToNumber().Value;
public static Values.Boolean ToBoolean(this IMathObject mo) =>
(Values.Boolean)mo;
public static Function ToFunction(this IMathObject mo) =>
(Function)mo;
public static Interval ToInterval(this IMathObject mo) =>
(Interval)mo;
public static ISet ToSet(this IMathObject mo) => (ISet)mo;
public static ISet GetMathType(this IMathObject mo)
{
if (Reals.Value.Contains(mo)) return Reals.Value;
if (Booleans.Value.Contains(mo)) return Booleans.Value;
if (Vectors.R2.Contains(mo))
return Vectors.R2;
if (Vectors.R3.Contains(mo))
return Vectors.R3;
if (AllVectors.Value.Contains(mo))
{
var v = mo.ToVector();
var rcs = Vectors.Get(v.Length);
if (rcs != null && rcs.Contains(mo))
return rcs;
return AllVectors.Value;
}
if (AllMatrices.Value.Contains(mo))
{
var m = mo.ToMatrix();
var ms = Matrices.Get(m.RowCount, m.ColumnCount);
if (ms != null && ms.Contains(mo))
return ms;
return AllMatrices.Value;
}
if (Strings.Value.Contains(mo)) return Strings.Value;
if (Intervals.Value.Contains(mo)) return Intervals.Value;
var rank = mo.GetTensorRank(null);
if (rank.HasValue && rank.Value > 2)
return Tensors.Value;
if (mo.IsIsFunction(null))
{
var f = mo.ToFunction();
if (Sets.Functions.FunctionHasFixedTypes(f))
{
// TODO: reduce allocations
var paramTypes =
f.Parameters.Select(p => p.Type).ToArray();
return Sets.Functions.Get(
f.GetResultType(null, null),
paramTypes);
}
}
if (AllFunctions.Value.Contains(mo))
return AllFunctions.Value;
if (Sets.Sets.Value.Contains(mo))
return Sets.Sets.Value;
if (Sets.Expressions.Value.Contains(mo))
{
if (ComponentAccesses.Value.Contains(mo))
return ComponentAccesses.Value;
if (FunctionCalls.Value.Contains(mo))
return FunctionCalls.Value;
if (IntervalExpressions.Value.Contains(mo))
return IntervalExpressions.Value;
if (Literals.Value.Contains(mo))
return Literals.Value;
if (TensorExpressions.Value.Contains(mo))
return TensorExpressions.Value;
if (MatrixExpressions.Value.Contains(mo))
return MatrixExpressions.Value;
if (VectorExpressions.Value.Contains(mo))
return VectorExpressions.Value;
if (VariableAccesses.Value.Contains(mo))
return VariableAccesses.Value;
}
throw new TypeException(
$"The object type is unknown: {mo.GetType()}");
}
public static IMathObject[] ToMathObjects(this float[] values)
{
return values.Select(
v => (IMathObject) v.ToNumber()).ToArray();
}
public static IMathObject[,] ToMathObjects(this float[,] values)
{
var result = new IMathObject[values.GetLength(0),
values.GetLength(1)];
// TODO: faster
// TODO: row first or column first?
for (var i = 0; i < values.GetLength(0); i++)
{
for (var j = 0; j < values.GetLength(1); j++)
{
result[i, j] = values[i, j].ToNumber();
}
}
return result;
}
}
}