Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
Measurement.cs
1using System;
2using System.Reflection;
3using System.Text;
8
10{
14 public sealed class Measurement : FieldElement, IComparable, IPhysicalQuantity // Not a proper field, as division is not the inversion of multiplication
15 {
19 public static readonly Measurement ZeroElement = new Measurement(0, Unit.Empty, 0);
20
24 public static readonly Measurement OneElement = new Measurement(1, Unit.Empty, 1);
25
26 private static readonly Measurements associatedField = new Measurements();
27
28 private double magnitude;
29 private double error;
30 private Unit unit;
31
38 public Measurement(double Magnitude, Unit Unit, double Error)
39 {
40 this.magnitude = Magnitude;
41 this.unit = Unit;
42 this.error = Math.Abs(Error);
43 }
44
48 public double Magnitude
49 {
50 get => this.magnitude;
51 set => this.magnitude = value;
52 }
53
57 public Unit Unit
58 {
59 get => this.unit;
60 set => this.unit = value;
61 }
62
66 public double Error
67 {
68 get => this.error;
69 set => this.error = value;
70 }
71
75 public PhysicalQuantity Estimate => new PhysicalQuantity(this.magnitude, this.unit);
76
80 public PhysicalQuantity Max => new PhysicalQuantity(this.magnitude + this.error, this.unit);
81
85 public PhysicalQuantity Min => new PhysicalQuantity(this.magnitude - this.error, this.unit);
86
92
94 public override string ToString()
95 {
96 StringBuilder sb = new StringBuilder();
97
98 sb.Append(Expression.ToString(this.magnitude));
99 if (!this.unit.IsEmpty)
100 {
101 sb.Append(' ');
102 sb.Append(this.unit.ToString());
103 }
104
105 if (this.error != 0)
106 {
107 sb.Append(" ± ");
108 sb.Append(Expression.ToString(this.error));
109
110 if (!this.unit.IsEmpty)
111 {
112 sb.Append(' ');
113 sb.Append(this.unit.ToString());
114 }
115 }
116
117 return sb.ToString();
118 }
119
123 public override IField AssociatedField => associatedField;
124
128 public override object AssociatedObjectValue => this;
129
136 {
137 if (Element is Measurement E)
138 {
139 Unit Unit = Unit.Multiply(this.unit, E.unit, out int ResidueExponential);
140 double Magnitude = this.magnitude * E.magnitude;
141 if (ResidueExponential != 0)
142 Magnitude *= Math.Pow(10, ResidueExponential);
143
144 double Error1 = this.error / this.magnitude;
145 double Error2 = E.error / E.magnitude;
146 double Error = (Error1 + Error2) * Magnitude;
147
148 return new Measurement(Magnitude, Unit, Error);
149 }
150 else if (Element.AssociatedObjectValue is double d)
151 return new Measurement(this.magnitude * d, this.unit, this.error * d);
152 else
153 return null;
154 }
155
160 public override IRingElement Invert()
161 {
162 Unit Unit = this.unit.Invert(out int ResidueExponential);
163 double Magnitude = 1 / this.magnitude;
164 if (ResidueExponential != 0)
165 Magnitude *= Math.Pow(10, ResidueExponential);
166
167 double Error = this.error / this.magnitude * Magnitude;
168
169 return new Measurement(Magnitude, Unit, Error);
170 }
171
178 {
179 if (Element is Measurement E)
180 {
181 if (!Unit.TryConvert(E.magnitude, E.unit, this.unit, out double d))
182 return null;
183
184 double Magnitude = this.magnitude + d;
185
186 if (!Unit.TryConvert(E.error, E.unit, this.unit, out d))
187 return null;
188
189 return new Measurement(Magnitude, this.unit, this.error + d);
190 }
191 else if (Element.AssociatedObjectValue is double d)
192 return new Measurement(this.magnitude + d, this.unit, this.error);
193 else
194 return null;
195 }
196
201 public override IGroupElement Negate()
202 {
203 return new Measurement(-this.magnitude, this.unit, this.error);
204 }
205
207 public override bool Equals(object obj)
208 {
209 if (!(obj is Measurement E))
210 return false;
211
212 if (this.unit.Equals(E.unit, true))
213 return this.magnitude == E.magnitude && this.error == E.error;
214 else
215 {
216 double m1 = this.magnitude;
217 this.unit.ToReferenceUnits(ref m1);
218
219 double m2 = E.magnitude;
220 E.unit.ToReferenceUnits(ref m2);
221
222 if (m1 != m2)
223 return false;
224
225 m1 = this.error;
226 this.unit.ToReferenceUnits(ref m1);
227
228 m2 = E.error;
229 E.unit.ToReferenceUnits(ref m2);
230
231 return m1 == m2;
232 }
233 }
234
236 public override int GetHashCode()
237 {
238 int Result = this.magnitude.GetHashCode();
239 Result ^= Result << 5 ^ this.unit.GetHashCode();
240 Result ^= Result << 5 ^ this.error.GetHashCode();
241 return Result;
242 }
243
248
253
260 public override bool TryConvertTo(Type DesiredType, out object Value)
261 {
262 if (DesiredType == typeof(byte))
263 {
264 if (this.magnitude >= byte.MinValue && this.magnitude <= byte.MaxValue)
265 {
266 Value = (byte)this.magnitude;
267 return true;
268 }
269 }
270 else if (DesiredType == typeof(decimal))
271 {
272 Value = (decimal)this.magnitude;
273 return true;
274 }
275 else if (DesiredType == typeof(double))
276 {
277 Value = (double)this.magnitude;
278 return true;
279 }
280 else if (DesiredType == typeof(short))
281 {
282 if (this.magnitude >= short.MinValue && this.magnitude <= short.MaxValue)
283 {
284 Value = (short)this.magnitude;
285 return true;
286 }
287 }
288 else if (DesiredType == typeof(int))
289 {
290 if (this.magnitude >= int.MinValue && this.magnitude <= int.MaxValue)
291 {
292 Value = (int)this.magnitude;
293 return true;
294 }
295 }
296 else if (DesiredType == typeof(long))
297 {
298 if (this.magnitude >= long.MinValue && this.magnitude <= long.MaxValue)
299 {
300 Value = (long)this.magnitude;
301 return true;
302 }
303 }
304 else if (DesiredType == typeof(sbyte))
305 {
306 if (this.magnitude >= sbyte.MinValue && this.magnitude <= sbyte.MaxValue)
307 {
308 Value = (sbyte)this.magnitude;
309 return true;
310 }
311 }
312 else if (DesiredType == typeof(float))
313 {
314 Value = (float)this.magnitude;
315 return true;
316 }
317 else if (DesiredType == typeof(ushort))
318 {
319 if (this.magnitude >= ushort.MinValue && this.magnitude <= ushort.MaxValue)
320 {
321 Value = (ushort)this.magnitude;
322 return true;
323 }
324 }
325 else if (DesiredType == typeof(uint))
326 {
327 if (this.magnitude >= uint.MinValue && this.magnitude <= uint.MaxValue)
328 {
329 Value = (uint)this.magnitude;
330 return true;
331 }
332 }
333 else if (DesiredType == typeof(ulong))
334 {
335 if (this.magnitude >= ulong.MinValue && this.magnitude <= ulong.MaxValue)
336 {
337 Value = (ulong)this.magnitude;
338 return true;
339 }
340 }
341 else if (DesiredType.GetTypeInfo().IsAssignableFrom(typeof(Measurement).GetTypeInfo()))
342 {
343 Value = this;
344 return true;
345 }
346
347 return Expression.TryConvert(this, DesiredType, out Value);
348 }
349
353 public int CompareTo(object obj)
354 {
355 if (!(obj is Measurement Q))
356 throw new ScriptException("Values not comparable.");
357
358 int i;
359
360 if (this.unit.Equals(Q.unit, true))
361 {
362 i = this.magnitude.CompareTo(Q.magnitude);
363 if (i != 0)
364 return i;
365
366 return this.error.CompareTo(Q.error);
367 }
368
369 if (!Unit.TryConvert(Q.magnitude, Q.unit, this.unit, out double d))
370 throw new ScriptException("Values not comparable.");
371
372 i = this.magnitude.CompareTo(d);
373 if (i != 0)
374 return i;
375
376 if (!Unit.TryConvert(Q.error, Q.unit, this.unit, out d))
377 throw new ScriptException("Values not comparable.");
378
379 return this.error.CompareTo(d);
380 }
381
388 public static bool TryParse(string s, out Measurement Value)
389 {
390 int i = s.IndexOf('±');
391 if (i < 0)
392 i = s.IndexOf("+-");
393
394 if (i >= 0)
395 {
396 string s1 = s.Substring(0, i).Trim();
397 string s2 = s.Substring(i + 1).Trim();
398
400 {
401 if (Unit.TryConvert(E.Magnitude, E.Unit, Q.Unit, out double Error))
402 {
403 Value = new Measurement(Q.Magnitude, Q.Unit, Error);
404 return true;
405 }
406 }
407 else if (Expression.TryParse(s1, out double d1) && Expression.TryParse(s2, out double d2))
408 {
409 Value = new Measurement(d1, Unit.Empty, d2);
410 return true;
411 }
412 }
413
414 Value = null;
415 return false;
416 }
417
418 }
419}
Base class for all types of elements.
Definition: Element.cs:13
abstract object AssociatedObjectValue
Associated object value.
Definition: Element.cs:46
Base class for all types of field elements.
Definition: FieldElement.cs:10
Base class for script exceptions.
Class managing a script expression.
Definition: Expression.cs:39
static bool TryParse(string s, out double Value)
Tries to parse a double-precision floating-point value.
Definition: Expression.cs:4517
static bool TryConvert(object Value, Type DesiredType, out object Result)
Tries to convert an object Value to an object of type DesiredType .
Definition: Expression.cs:5268
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Definition: Expression.cs:4496
static readonly Measurement ZeroElement
Zero element (0)
Definition: Measurement.cs:19
override IAbelianGroupElement Add(IAbelianGroupElement Element)
Tries to add an element to the current element.
Definition: Measurement.cs:177
override bool Equals(object obj)
Compares the element to another. If elements are equal.
Definition: Measurement.cs:207
PhysicalQuantity Min
Estimate of measurement
Definition: Measurement.cs:85
int CompareTo(object obj)
IComparable.CompareTo
Definition: Measurement.cs:353
override bool TryConvertTo(Type DesiredType, out object Value)
Converts the value to a .NET type.
Definition: Measurement.cs:260
override int GetHashCode()
Calculates a hash code of the element. Hash code.
Definition: Measurement.cs:236
override ICommutativeRingWithIdentityElement One
Returns the identity element of the commutative ring with identity.
Definition: Measurement.cs:252
override IAbelianGroupElement Zero
Returns the zero element of the group.
Definition: Measurement.cs:247
override IField AssociatedField
Associated Field.
Definition: Measurement.cs:123
override object AssociatedObjectValue
Associated object value.
Definition: Measurement.cs:128
override ICommutativeRingElement Multiply(ICommutativeRingElement Element)
Tries to multiply an element to the current element.
Definition: Measurement.cs:135
override IGroupElement Negate()
Negates the element.
Definition: Measurement.cs:201
PhysicalQuantity Max
Estimate of measurement
Definition: Measurement.cs:80
Measurement(double Magnitude, Unit Unit, double Error)
Physical quantity.
Definition: Measurement.cs:38
static readonly Measurement OneElement
Unit element (1)
Definition: Measurement.cs:24
PhysicalQuantity ToPhysicalQuantity()
Converts underlying object to a physical quantity.
static bool TryParse(string s, out Measurement Value)
Tries to parse a string to a physical quantity.
Definition: Measurement.cs:388
override IRingElement Invert()
Inverts the element, if possible.
Definition: Measurement.cs:160
PhysicalQuantity Estimate
Estimate of measurement
Definition: Measurement.cs:75
Pseudo-field of physical measurements.
Definition: Measurements.cs:12
static bool TryParse(string s, out PhysicalQuantity Value)
Tries to parse a string to a physical quantity.
Represents a unit.
Definition: Unit.cs:15
static bool TryConvert(double From, Unit FromUnit, Unit ToUnit, out double To)
Tries to convert a magnitude in one unit to a magnitude in another.
Definition: Unit.cs:1201
override string ToString()
Definition: Unit.cs:517
bool IsEmpty
If the unit is empty. (A unit of only a prefix, but no factors, is not empty.)
Definition: Unit.cs:415
Unit Invert(out int ResidueExponent)
Inverts the unit.
Definition: Unit.cs:444
override bool Equals(object obj)
Definition: Unit.cs:456
static readonly Unit Empty
Empty unit.
Definition: Unit.cs:436
static Unit Multiply(Unit Left, Unit Right, out int ResidueExponent)
Multiplies two units with each other.
Definition: Unit.cs:617
override int GetHashCode()
Definition: Unit.cs:506
Unit ToReferenceUnits(ref double Magnitude)
Converts the unit to a series of reference unit factors. (Unrecognized units will be assumed to be re...
Definition: Unit.cs:807
Basic interface for all types of abelian group elements.
Basic interface for all types of commutative ring elements.
Basic interface for all types of commutative ring with identity elements.
Basic interface for all types of group elements.
Definition: IGroupElement.cs:9
Basic interface for all types of ring elements.
Definition: IRingElement.cs:10
Basic interface for all types of fields.
Definition: IField.cs:9
Interface for objects that can be represented as a physical quantity.