implement operator + for all Units
This commit is contained in:
parent
d2bef311c0
commit
d5c5239744
|
@ -4,7 +4,7 @@ using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Generate]
|
[Sum]
|
||||||
public readonly partial struct Angle
|
public readonly partial struct Angle
|
||||||
{
|
{
|
||||||
public static String Unit => "rad";
|
public static String Unit => "rad";
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Sum
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Angle
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct Angle
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Generate]
|
[Sum]
|
||||||
public readonly partial struct ApparentPower
|
public readonly partial struct ApparentPower
|
||||||
{
|
{
|
||||||
public static String Unit => "VA";
|
public static String Unit => "VA";
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Sum
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct ApparentPower
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct ApparentPower
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units.Composite;
|
namespace InnovEnergy.Lib.Units.Composite;
|
||||||
|
|
||||||
public record Ac1Phase
|
public record Ac1Phase
|
||||||
(
|
(
|
||||||
Voltage Voltage,
|
Voltage Voltage,
|
||||||
Current Current,
|
Current Current,
|
||||||
Angle Phi,
|
Angle Phi,
|
||||||
Frequency Frequency
|
Frequency Frequency
|
||||||
) :
|
)
|
||||||
AcPhase(Voltage, Current, Phi);
|
: AcPhase(Voltage, Current, Phi)
|
||||||
|
{
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "RedundantCast")]
|
||||||
|
public static Ac1Phase operator +(Ac1Phase left, Ac1Phase right)
|
||||||
|
{
|
||||||
|
var f = (left.Frequency + right.Frequency) / 2m; // TODO: check that l & r approximately equal
|
||||||
|
var acPhase = (AcPhase)left + (AcPhase)right;
|
||||||
|
return new Ac1Phase(acPhase.Voltage, acPhase.Current, acPhase.Phi, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,24 @@ using static DecimalMath.DecimalEx;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units.Composite;
|
namespace InnovEnergy.Lib.Units.Composite;
|
||||||
|
|
||||||
public record Ac3Phase(AcPhase L1, AcPhase L2, AcPhase L3, Decimal Frequency)
|
public record Ac3Phase(AcPhase L1, AcPhase L2, AcPhase L3, Frequency Frequency)
|
||||||
{
|
{
|
||||||
public ApparentPower ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower;
|
public ApparentPower ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower;
|
||||||
public ReactivePower ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower;
|
public ReactivePower ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower;
|
||||||
public Power ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower;
|
public Power ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower;
|
||||||
|
|
||||||
public Angle Phi => ATan2(ReactivePower, ActivePower);
|
public Angle Phi => ATan2(ReactivePower, ActivePower);
|
||||||
|
|
||||||
|
|
||||||
|
public static Ac3Phase operator +(Ac3Phase left, Ac3Phase right)
|
||||||
|
{
|
||||||
|
var f = (left.Frequency + right.Frequency) / 2m; // TODO: check that l & r approximately equal
|
||||||
|
|
||||||
|
var l1 = left.L1 + right.L1;
|
||||||
|
var l2 = left.L2 + right.L2;
|
||||||
|
var l3 = left.L3 + right.L3;
|
||||||
|
|
||||||
|
return new Ac3Phase(l1, l2, l3, f);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,8 +15,40 @@ public record AcPhase : Phase
|
||||||
|
|
||||||
public Angle Phi { get; }
|
public Angle Phi { get; }
|
||||||
|
|
||||||
public ApparentPower ApparentPower => Math.Abs(Voltage.Value * Current.Value) ;
|
public ApparentPower ApparentPower => Voltage.Value * Current.Value ;
|
||||||
public Power ActivePower => ApparentPower.Value * PowerFactor;
|
public Power ActivePower => ApparentPower.Value * PowerFactor;
|
||||||
public ReactivePower ReactivePower => ApparentPower.Value * Sin(Phi);
|
public ReactivePower ReactivePower => ApparentPower.Value * Sin(Phi);
|
||||||
public Decimal PowerFactor => Cos(Phi);
|
public Decimal PowerFactor => Cos(Phi);
|
||||||
|
|
||||||
|
|
||||||
|
public static AcPhase operator +(AcPhase left, AcPhase right)
|
||||||
|
{
|
||||||
|
// the Voltages of two phases are expected to be in phase and equal
|
||||||
|
|
||||||
|
var v = (left.Voltage + right.Voltage) / 2m; // TODO: check that l & r approximately equal
|
||||||
|
|
||||||
|
// currents (RMS) can be different and out of phase
|
||||||
|
// https://www.johndcook.com/blog/2020/08/17/adding-phase-shifted-sine-waves/
|
||||||
|
|
||||||
|
// IF
|
||||||
|
// left(t) = ILeft sin(ωt)
|
||||||
|
// right(t) = IRight sin(ωt + φ).
|
||||||
|
// sum(t) = left(t) + right(t) = ISum sin(ωt + ψ).
|
||||||
|
// THEN
|
||||||
|
|
||||||
|
// ψ = arctan( IRight * sin(φ) / (ILeft + IRight cos(φ)) ).
|
||||||
|
// C = IRight * sin(φ) / sin(ψ).
|
||||||
|
|
||||||
|
// in this calc left(t) has zero phase shift.
|
||||||
|
// we can shift both waves by -left.Phi, so
|
||||||
|
// φ := right.phi - left.phi
|
||||||
|
|
||||||
|
|
||||||
|
var phi = right.Phi - left.Phi;
|
||||||
|
|
||||||
|
var phiSum = ATan2(right.Current * Sin(phi), left.Current + right.Current * Cos(phi));
|
||||||
|
var iSum = right.Current * Sin(phi) / Sin(phiSum);
|
||||||
|
|
||||||
|
return new AcPhase(v, iSum, phiSum);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,4 +3,13 @@ namespace InnovEnergy.Lib.Units.Composite;
|
||||||
public record DcPhase(Voltage Voltage, Current Current) : Phase(Voltage, Current)
|
public record DcPhase(Voltage Voltage, Current Current) : Phase(Voltage, Current)
|
||||||
{
|
{
|
||||||
public Power Power => Current * Voltage;
|
public Power Power => Current * Voltage;
|
||||||
|
|
||||||
|
public static DcPhase operator +(DcPhase left, DcPhase right)
|
||||||
|
{
|
||||||
|
var v = (left.Voltage + right.Voltage) / 2m;
|
||||||
|
var i = left.Current + right.Current;
|
||||||
|
|
||||||
|
return new DcPhase(v, i);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
|
||||||
[Generate]
|
[Sum]
|
||||||
public readonly partial struct Current
|
public readonly partial struct Current
|
||||||
{
|
{
|
||||||
public static String Unit => "A";
|
public static String Unit => "A";
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Sum
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Current
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct Current
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,17 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
[Equal]
|
||||||
[Generate]
|
|
||||||
public readonly partial struct Frequency
|
public readonly partial struct Frequency
|
||||||
{
|
{
|
||||||
public static String Unit => "Hz";
|
public static String Unit => "Hz";
|
||||||
public static String Symbol => "f";
|
public static String Symbol => "f";
|
||||||
|
|
||||||
public Frequency(Decimal value) => Value = value;
|
public Frequency(Decimal value)
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
throw new ArgumentException(nameof(Frequency) + " cannot be negative", nameof(value));
|
||||||
|
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Equal
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Frequency
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct Frequency
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
namespace InnovEnergy.Lib.Units.Generator;
|
namespace InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Struct)]
|
[AttributeUsage(AttributeTargets.Struct)]
|
||||||
internal class GenerateAttribute: Attribute
|
internal class EqualAttribute: Attribute
|
||||||
{}
|
{}
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Struct)]
|
||||||
|
internal class MeanAttribute: Attribute
|
||||||
|
{}
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Struct)]
|
||||||
|
internal class SumAttribute: Attribute
|
||||||
|
{}
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Type
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Template
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,12 @@
|
||||||
scriptDir=$( dirname -- "$0"; )
|
scriptDir=$( dirname -- "$0"; )
|
||||||
cd "$scriptDir/.." || exit
|
cd "$scriptDir/.." || exit
|
||||||
|
|
||||||
for file in $(grep -l '\[Generate\]' *.cs)
|
for match in $(grep -e '\[Sum\]\|\[Equal\]\|\[Mean\]' -o *.cs | tr -d '[]')
|
||||||
do
|
do
|
||||||
filename=$(basename -- "$file")
|
path="${match%:*}"
|
||||||
class="${filename%.*}"
|
type="${match#*:}"
|
||||||
echo "generating $filename"
|
file=$(basename -- "$path")
|
||||||
sed "s/Template/$class/g" "./Generator/Template.txt" > "./$class.generated.cs"
|
class="${file%.*}"
|
||||||
|
echo "generating $file"
|
||||||
|
sed "s/Template/$class/g; s/Type/$type/" "./Generator/Template.txt" > "./$class.generated.cs"
|
||||||
done
|
done
|
|
@ -3,7 +3,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Generate]
|
[Sum]
|
||||||
public readonly partial struct Power
|
public readonly partial struct Power
|
||||||
{
|
{
|
||||||
public static String Unit => "W";
|
public static String Unit => "W";
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Sum
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
using T = ReactivePower;
|
using T = Power;
|
||||||
|
|
||||||
public readonly partial struct ReactivePower
|
public readonly partial struct Power
|
||||||
{
|
{
|
||||||
public Decimal Value { get; }
|
public Decimal Value { get; }
|
||||||
public override String ToString() => Value + Unit;
|
public override String ToString() => Value + Unit;
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct ReactivePower
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct ReactivePower
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Generate]
|
[Sum]
|
||||||
public readonly partial struct ReactivePower
|
public readonly partial struct ReactivePower
|
||||||
{
|
{
|
||||||
public static String Unit => "var";
|
public static String Unit => "var";
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Sum
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
using T = Power;
|
using T = ReactivePower;
|
||||||
|
|
||||||
public readonly partial struct Power
|
public readonly partial struct ReactivePower
|
||||||
{
|
{
|
||||||
public Decimal Value { get; }
|
public Decimal Value { get; }
|
||||||
public override String ToString() => Value + Unit;
|
public override String ToString() => Value + Unit;
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Power
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct Power
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Generate]
|
[Sum]
|
||||||
public readonly partial struct Resistance
|
public readonly partial struct Resistance
|
||||||
{
|
{
|
||||||
public static String Unit => "Ω";
|
public static String Unit => "Ω";
|
||||||
|
@ -13,7 +13,5 @@ public readonly partial struct Resistance
|
||||||
|
|
||||||
// U=RI
|
// U=RI
|
||||||
public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value * current.Value);
|
public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value * current.Value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Sum
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Resistance
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct Resistance
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,15 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Generate]
|
using T=Temperature;
|
||||||
|
|
||||||
|
[Mean]
|
||||||
public readonly partial struct Temperature
|
public readonly partial struct Temperature
|
||||||
{
|
{
|
||||||
public static String Unit => "°C";
|
public static String Unit => "°C";
|
||||||
public static String Symbol => "T";
|
public static String Symbol => "T";
|
||||||
|
|
||||||
public Temperature(Decimal value) => Value = value;
|
public Temperature(Decimal value) => Value = value;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Mean
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Temperature
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct Temperature
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Generate]
|
[Equal]
|
||||||
public readonly partial struct Voltage
|
public readonly partial struct Voltage
|
||||||
{
|
{
|
||||||
public static String Unit => "V";
|
public static String Unit => "V";
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
|
||||||
|
#define Equal
|
||||||
|
|
||||||
|
using static System.Math;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
@ -16,10 +19,39 @@ public readonly partial struct Voltage
|
||||||
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
|
||||||
|
|
||||||
// addition
|
// addition
|
||||||
|
|
||||||
|
#if Sum
|
||||||
|
|
||||||
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
public static T operator +(T left, T right) => new T(left.Value + right.Value);
|
||||||
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
public static T operator -(T left, T right) => new T(left.Value - right.Value);
|
||||||
public static T operator -(T t) => new T(-t.Value);
|
public static T operator -(T t) => new T(-t.Value);
|
||||||
|
|
||||||
|
#elif Mean
|
||||||
|
|
||||||
|
public static T operator +(T left, T right) => new T((left.Value + right.Value)/2m);
|
||||||
|
|
||||||
|
#elif Equal
|
||||||
|
|
||||||
|
public static T operator +(T left, T right)
|
||||||
|
{
|
||||||
|
var d = Max(Abs(left.Value), Abs(right.Value));
|
||||||
|
|
||||||
|
if (d != 0m)
|
||||||
|
return new T(0m);
|
||||||
|
|
||||||
|
var relativeError = Abs(left.Value - right.Value) / d;
|
||||||
|
|
||||||
|
const Decimal maxRelativeError = 0.05m;
|
||||||
|
|
||||||
|
if (relativeError > maxRelativeError)
|
||||||
|
throw new Exception($"{nameof(left)} and {nameof(right)} must be approximately equal.\n" +
|
||||||
|
$"Difference > {maxRelativeError * 100}% detected\n" +
|
||||||
|
$"{nameof(left)} : {left}\n" +
|
||||||
|
$"{nameof(right)}: {right}");
|
||||||
|
|
||||||
|
return new T((left.Value + right.Value) / 2m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
|
|
||||||
|
@ -43,4 +75,4 @@ public readonly partial struct Voltage
|
||||||
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
|
||||||
public override Int32 GetHashCode() => Value.GetHashCode();
|
public override Int32 GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue