diff --git a/csharp/Lib/Units/Angle.cs b/csharp/Lib/Units/Angle.cs index b8972c826..87a3ed2b4 100644 --- a/csharp/Lib/Units/Angle.cs +++ b/csharp/Lib/Units/Angle.cs @@ -4,7 +4,7 @@ using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Units; -[Sum] +[Generate] public readonly partial struct Angle { public static String Unit => "rad"; diff --git a/csharp/Lib/Units/Angle.generated.cs b/csharp/Lib/Units/Angle.generated.cs index 837f0b2a2..75f16b601 100644 --- a/csharp/Lib/Units/Angle.generated.cs +++ b/csharp/Lib/Units/Angle.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Angle public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/ApparentPower.cs b/csharp/Lib/Units/ApparentPower.cs index 8c92385de..b2a5bba6c 100644 --- a/csharp/Lib/Units/ApparentPower.cs +++ b/csharp/Lib/Units/ApparentPower.cs @@ -2,7 +2,7 @@ using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; -[Sum] +[Generate] public readonly partial struct ApparentPower { public static String Unit => "VA"; diff --git a/csharp/Lib/Units/ApparentPower.generated.cs b/csharp/Lib/Units/ApparentPower.generated.cs index a72053726..7f5a9b9c5 100644 --- a/csharp/Lib/Units/ApparentPower.generated.cs +++ b/csharp/Lib/Units/ApparentPower.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct ApparentPower public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/Composite/Ac1Bus.cs b/csharp/Lib/Units/Composite/Ac1Bus.cs index f2c769f24..b968d72e9 100644 --- a/csharp/Lib/Units/Composite/Ac1Bus.cs +++ b/csharp/Lib/Units/Composite/Ac1Bus.cs @@ -6,20 +6,20 @@ public record Ac1Bus : AcPhase { public Frequency Frequency { get; init; } - [SuppressMessage("ReSharper", "RedundantCast")] - public static Ac1Bus operator |(Ac1Bus left, Ac1Bus right) - { - var f = left.Frequency | right.Frequency; - var p = (AcPhase)left | (AcPhase)right; - - return new Ac1Bus - { - Frequency = f, - Current = p.Current, - Voltage = p.Voltage, - Phi = p.Phi - }; - } + // [SuppressMessage("ReSharper", "RedundantCast")] + // public static Ac1Bus operator |(Ac1Bus left, Ac1Bus right) + // { + // var f = left.Frequency | right.Frequency; + // var p = (AcPhase)left | (AcPhase)right; + // + // return new Ac1Bus + // { + // Frequency = f, + // Current = p.Current, + // Voltage = p.Voltage, + // Phi = p.Phi + // }; + // } } diff --git a/csharp/Lib/Units/Composite/AcPhase.cs b/csharp/Lib/Units/Composite/AcPhase.cs index d590fbdee..8186e01f9 100644 --- a/csharp/Lib/Units/Composite/AcPhase.cs +++ b/csharp/Lib/Units/Composite/AcPhase.cs @@ -22,45 +22,45 @@ public record AcPhase : IBus public Angle Phi { get; init; } public ApparentPower ApparentPower => Voltage.Value * Current.Value ; - public Power ActivePower => ApparentPower.Value * PowerFactor.Value; + public Power ActivePower => ApparentPower.Value * PowerFactor; public ReactivePower ReactivePower => ApparentPower.Value * Sin(Phi); - public Number 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; - - // 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 calculation 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 - { - Voltage = v, - Current = iSum, - Phi = phiSum - }; - } + // 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; + // + // // 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 calculation 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 + // { + // Voltage = v, + // Current = iSum, + // Phi = phiSum + // }; + // } } \ No newline at end of file diff --git a/csharp/Lib/Units/Current.cs b/csharp/Lib/Units/Current.cs index b3c36ee34..07b473c24 100644 --- a/csharp/Lib/Units/Current.cs +++ b/csharp/Lib/Units/Current.cs @@ -2,8 +2,7 @@ using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; - -[Sum] +[Generate] public readonly partial struct Current { public static String Unit => "A"; diff --git a/csharp/Lib/Units/Current.generated.cs b/csharp/Lib/Units/Current.generated.cs index c06cb3ff0..de5242e57 100644 --- a/csharp/Lib/Units/Current.generated.cs +++ b/csharp/Lib/Units/Current.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Current public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/Energy.cs b/csharp/Lib/Units/Energy.cs index 006568b06..ab05ba6c4 100644 --- a/csharp/Lib/Units/Energy.cs +++ b/csharp/Lib/Units/Energy.cs @@ -1,10 +1,9 @@ using InnovEnergy.Lib.Time.Unix; using InnovEnergy.Lib.Units.Generator; - namespace InnovEnergy.Lib.Units; -[Sum] +[Generate] public readonly partial struct Energy { public static String Unit => "kWh"; diff --git a/csharp/Lib/Units/Energy.generated.cs b/csharp/Lib/Units/Energy.generated.cs index 90496238b..f0713a828 100644 --- a/csharp/Lib/Units/Energy.generated.cs +++ b/csharp/Lib/Units/Energy.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Energy public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/Frequency.cs b/csharp/Lib/Units/Frequency.cs index 3041325c2..f34b83334 100644 --- a/csharp/Lib/Units/Frequency.cs +++ b/csharp/Lib/Units/Frequency.cs @@ -2,7 +2,8 @@ using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; -[Equal] + +[Generate] public readonly partial struct Frequency { public static String Unit => "Hz"; diff --git a/csharp/Lib/Units/Frequency.generated.cs b/csharp/Lib/Units/Frequency.generated.cs index 576e7b1a4..fead5a326 100644 --- a/csharp/Lib/Units/Frequency.generated.cs +++ b/csharp/Lib/Units/Frequency.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Equal +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Frequency public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/Generator/EqualAttribute.cs b/csharp/Lib/Units/Generator/EqualAttribute.cs deleted file mode 100644 index c0131044a..000000000 --- a/csharp/Lib/Units/Generator/EqualAttribute.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace InnovEnergy.Lib.Units.Generator; - -[AttributeUsage(AttributeTargets.Struct)] -internal class EqualAttribute: Attribute -{} \ No newline at end of file diff --git a/csharp/Lib/Units/Generator/GenerateAttribute.cs b/csharp/Lib/Units/Generator/GenerateAttribute.cs new file mode 100644 index 000000000..12337cf50 --- /dev/null +++ b/csharp/Lib/Units/Generator/GenerateAttribute.cs @@ -0,0 +1,6 @@ +using System.Text.Json.Serialization; + +namespace InnovEnergy.Lib.Units.Generator; + +internal class GenerateAttribute : Attribute +{} \ No newline at end of file diff --git a/csharp/Lib/Units/Generator/MeanAttribute.cs b/csharp/Lib/Units/Generator/MeanAttribute.cs deleted file mode 100644 index 161da8b0e..000000000 --- a/csharp/Lib/Units/Generator/MeanAttribute.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace InnovEnergy.Lib.Units.Generator; - -[AttributeUsage(AttributeTargets.Struct)] -internal class MeanAttribute: Attribute -{} \ No newline at end of file diff --git a/csharp/Lib/Units/Generator/SumAttribute.cs b/csharp/Lib/Units/Generator/SumAttribute.cs deleted file mode 100644 index c4af9a156..000000000 --- a/csharp/Lib/Units/Generator/SumAttribute.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace InnovEnergy.Lib.Units.Generator; - -[AttributeUsage(AttributeTargets.Struct)] -internal class SumAttribute: Attribute -{} \ No newline at end of file diff --git a/csharp/Lib/Units/Generator/Template.txt b/csharp/Lib/Units/Generator/Template.txt index 38e30aa04..01f7220d4 100644 --- a/csharp/Lib/Units/Generator/Template.txt +++ b/csharp/Lib/Units/Generator/Template.txt @@ -22,40 +22,12 @@ public readonly partial struct Template public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/Generator/generate.sh b/csharp/Lib/Units/Generator/generate.sh index 74cc6a0c4..ec9f7abce 100755 --- a/csharp/Lib/Units/Generator/generate.sh +++ b/csharp/Lib/Units/Generator/generate.sh @@ -4,7 +4,7 @@ scriptDir=$( dirname -- "$0"; ) cd "$scriptDir/.." || exit -for match in $(grep -e '\[Sum\]\|\[Equal\]\|\[Mean\]' -o *.cs | tr -d '[]') +for match in $(grep -e '\[Generate\]' -o *.cs | tr -d '[]') do path="${match%:*}" type="${match#*:}" diff --git a/csharp/Lib/Units/Number.cs b/csharp/Lib/Units/Number.cs deleted file mode 100644 index fdc9b3b42..000000000 --- a/csharp/Lib/Units/Number.cs +++ /dev/null @@ -1,13 +0,0 @@ -using InnovEnergy.Lib.Units.Generator; - - -namespace InnovEnergy.Lib.Units; - -[Sum] -public readonly partial struct Number -{ - public static String Unit => ""; - public static String Symbol => ""; - - public Number(Decimal value) => Value = value; -} \ No newline at end of file diff --git a/csharp/Lib/Units/Number.generated.cs b/csharp/Lib/Units/Number.generated.cs deleted file mode 100644 index 4c6eb5693..000000000 --- a/csharp/Lib/Units/Number.generated.cs +++ /dev/null @@ -1,97 +0,0 @@ -#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum - -using static System.Math; -using System.Text.Json; -using System.Text.Json.Serialization; -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.Units; - -using T = Number; - -[JsonConverter(typeof(NumberConverter))] -public readonly partial struct Number -{ - public Decimal Value { get; } - public override String ToString() => Value.RoundToSignificantDigits(Units.DisplaySignificantDigits) + Unit; - - // scalar multiplication - - public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value); - public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); - public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - - // parallel - - #if Sum - - public static T operator |(T left, T right) => new T(left.Value + right.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 - - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - // conversion - - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - // equality - - public Boolean Equals(T other) => Value == other.Value; - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); - -} - - -internal class NumberConverter : JsonConverter -{ - public override Number Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return new Number(reader.GetDecimal()); - } - - public override void Write(Utf8JsonWriter writer, Number value, JsonSerializerOptions options) - { - var rounded = value.Value.RoundToSignificantDigits(Units.JsonSignificantDigits); - - writer.WriteNumberValue(rounded); - } -} \ No newline at end of file diff --git a/csharp/Lib/Units/Percent.cs b/csharp/Lib/Units/Percent.cs index 577dec8a0..e20bc0c22 100644 --- a/csharp/Lib/Units/Percent.cs +++ b/csharp/Lib/Units/Percent.cs @@ -1,43 +1,12 @@ +using InnovEnergy.Lib.Units.Generator; + namespace InnovEnergy.Lib.Units; -using T = Percent; - -public readonly struct Percent +[Generate] +public readonly partial struct Percent { public static String Unit => "%"; public static String Symbol => "%"; // ?? public Percent(Decimal value) => Value = value; - - // not generated - // TODO: generate? - - public Decimal Value { get; } - public override String ToString() => Value + Unit; - - // scalar multiplication - public static Decimal operator *(Decimal scalar, T t) => scalar * t.Value / 100m; - public static Decimal operator *(T t, Decimal scalar) => scalar * t.Value / 100m; - - // parallel - public static Percent operator |(T left, T right) => new T((left.Value + right.Value) / 2m); - - // compare - public static Boolean operator ==(T left, T right) => left.Value == right.Value; - public static Boolean operator !=(T left, T right) => left.Value != right.Value; - public static Boolean operator > (T left, T right) => left.Value > right.Value; - public static Boolean operator < (T left, T right) => left.Value < right.Value; - public static Boolean operator >=(T left, T right) => left.Value >= right.Value; - public static Boolean operator <=(T left, T right) => left.Value <= right.Value; - - // conversion - public static implicit operator T(Decimal d) => new T(d); - public static implicit operator T(Double d) => new T((Decimal)d); - public static implicit operator T(Int32 i) => new T(i); - public static implicit operator Decimal(T t) => t.Value; - - // equality - public Boolean Equals(T other) => Value == other.Value; - public override Boolean Equals(Object? obj) => obj is T other && Equals(other); - public override Int32 GetHashCode() => Value.GetHashCode(); } \ No newline at end of file diff --git a/csharp/Lib/Units/Power.cs b/csharp/Lib/Units/Power.cs index de4a7f9ab..5eb088024 100644 --- a/csharp/Lib/Units/Power.cs +++ b/csharp/Lib/Units/Power.cs @@ -1,10 +1,9 @@ - using InnovEnergy.Lib.Time.Unix; using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; -[Sum] +[Generate] public readonly partial struct Power { public static String Unit => "W"; diff --git a/csharp/Lib/Units/Power.generated.cs b/csharp/Lib/Units/Power.generated.cs index 1e68ec3a8..dc8ff2446 100644 --- a/csharp/Lib/Units/Power.generated.cs +++ b/csharp/Lib/Units/Power.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Power public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/ReactivePower.cs b/csharp/Lib/Units/ReactivePower.cs index 30d7641b9..a7017cb32 100644 --- a/csharp/Lib/Units/ReactivePower.cs +++ b/csharp/Lib/Units/ReactivePower.cs @@ -3,7 +3,7 @@ using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; -[Sum] +[Generate] public readonly partial struct ReactivePower { public static String Unit => "var"; diff --git a/csharp/Lib/Units/ReactivePower.generated.cs b/csharp/Lib/Units/ReactivePower.generated.cs index f6b694b7a..8e094a9a5 100644 --- a/csharp/Lib/Units/ReactivePower.generated.cs +++ b/csharp/Lib/Units/ReactivePower.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct ReactivePower public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/Resistance.cs b/csharp/Lib/Units/Resistance.cs index ab0bc7bbe..cd12e11a5 100644 --- a/csharp/Lib/Units/Resistance.cs +++ b/csharp/Lib/Units/Resistance.cs @@ -3,9 +3,8 @@ using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; -// TODO: op parallel is wrong -[Sum] +[Generate] public readonly partial struct Resistance { public static String Unit => "Ω"; diff --git a/csharp/Lib/Units/Resistance.generated.cs b/csharp/Lib/Units/Resistance.generated.cs index 6918e60dd..38318e86c 100644 --- a/csharp/Lib/Units/Resistance.generated.cs +++ b/csharp/Lib/Units/Resistance.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Sum +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Resistance public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/State.cs b/csharp/Lib/Units/State.cs deleted file mode 100644 index 88610517c..000000000 --- a/csharp/Lib/Units/State.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections; - -namespace InnovEnergy.Lib.Units; - -public readonly struct State : IReadOnlyList -{ - public IReadOnlyList Values { get; } - - public State(IReadOnlyList values) - { - if (values.Any(v => v.Contains(";"))) - throw new ArgumentException("State values cannot contain the character ;", nameof(values)); - - Values = values; - } - - public State(params String[] values) : this((IReadOnlyList)values){} - public State(params State[] states) : this((IReadOnlyList)states.SelectMany(s => s.Values).ToList()){} - - public static implicit operator State(String s) => new(s); - public static implicit operator State(Enum e) => new(e.ToString()); - public static implicit operator State(Boolean s) => new(s.ToString()); - public static implicit operator State(List s) => new((IReadOnlyList)s); - public static implicit operator State(String[] s) => new((IReadOnlyList)s); - public static implicit operator State(List es) => new(es.Select(e => e.ToString()).ToList()); - public static implicit operator State(Enum[] es) => new(es.Select(e => e.ToString()).ToList()); - - public static State operator |(State left, State right) => new(left, right); - - public IEnumerator GetEnumerator() => Values.GetEnumerator(); - - public override String ToString() => String.Join("; ", Values); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public Int32 Count => Values.Count; - public String this[Int32 index] => Values[index]; - - public static State From(T t) where T : Enum - { - return new State(t); - } -} - - diff --git a/csharp/Lib/Units/StateOfT.cs b/csharp/Lib/Units/StateOfT.cs deleted file mode 100644 index 4a1242dc2..000000000 --- a/csharp/Lib/Units/StateOfT.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections; - -namespace InnovEnergy.Lib.Units; - -public readonly struct State : IReadOnlyList where T:Enum -{ - public IReadOnlyList Values { get; } - - public State(IReadOnlyList values) => Values = values; - - public State(params T[] values) : this((IReadOnlyList)values){} - public State(params State[] states) : this((IReadOnlyList)states.SelectMany(s => s.Values).ToList()){} - - public static implicit operator State(T s) => new((IReadOnlyList)s); - public static implicit operator State(List s) => new((IReadOnlyList)s); - public static implicit operator State(T[] s) => new((IReadOnlyList)s); - - public static State operator |(State left, State right) => new State(left, right); - - public IEnumerator GetEnumerator() => Values.GetEnumerator(); - - public override String ToString() => String.Join("; ", Values); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - public Int32 Count => Values.Count; - public T this[Int32 index] => Values[index]; -} \ No newline at end of file diff --git a/csharp/Lib/Units/Temperature.cs b/csharp/Lib/Units/Temperature.cs index 57e2406a3..24f91a8a8 100644 --- a/csharp/Lib/Units/Temperature.cs +++ b/csharp/Lib/Units/Temperature.cs @@ -2,14 +2,14 @@ using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; -using T=Temperature; +using T = Temperature; -[Mean] + +[Generate] public readonly partial struct Temperature { public static String Unit => "°C"; public static String Symbol => "T"; public Temperature(Decimal value) => Value = value; - } \ No newline at end of file diff --git a/csharp/Lib/Units/Temperature.generated.cs b/csharp/Lib/Units/Temperature.generated.cs index c182f6737..fc61edafa 100644 --- a/csharp/Lib/Units/Temperature.generated.cs +++ b/csharp/Lib/Units/Temperature.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Mean +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Temperature public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value; diff --git a/csharp/Lib/Units/Units.cs b/csharp/Lib/Units/Units.cs index 0ee78882b..3694c0783 100644 --- a/csharp/Lib/Units/Units.cs +++ b/csharp/Lib/Units/Units.cs @@ -21,18 +21,14 @@ public static class Units public static Byte DisplaySignificantDigits { get; set; } = 3; public static Byte JsonSignificantDigits { get; set; } = 3; - - public const Decimal MaxRelativeError = 0.05m; // 5% - - public static Current A (this Decimal value) => new Current(value); - public static Voltage V (this Decimal value) => new Voltage(value); - public static Power W (this Decimal value) => new Power(value); - public static ReactivePower Var (this Decimal value) => new ReactivePower(value); - public static ApparentPower Va (this Decimal value) => new ApparentPower(value); - public static Resistance Ohm (this Decimal value) => new Resistance(value); - public static Frequency Hz (this Decimal value) => new Frequency(value); - public static Angle Rad (this Decimal value) => new Angle(value); - public static Temperature Celsius(this Decimal value) => new Temperature(value); - - + public static Current A (this Decimal value) => value; + public static Voltage V (this Decimal value) => value; + public static Power W (this Decimal value) => value; + public static ReactivePower Var (this Decimal value) => value; + public static ApparentPower Va (this Decimal value) => value; + public static Resistance Ohm (this Decimal value) => value; + public static Frequency Hz (this Decimal value) => value; + public static Angle Rad (this Decimal value) => value; + public static Temperature Celsius(this Decimal value) => value; + public static Energy KWh (this Decimal value) => value; } \ No newline at end of file diff --git a/csharp/Lib/Units/Voltage.cs b/csharp/Lib/Units/Voltage.cs index 9d9df166c..5849a2e56 100644 --- a/csharp/Lib/Units/Voltage.cs +++ b/csharp/Lib/Units/Voltage.cs @@ -2,7 +2,8 @@ using InnovEnergy.Lib.Units.Generator; namespace InnovEnergy.Lib.Units; -[Equal] + +[Generate] public readonly partial struct Voltage { public static String Unit => "V"; diff --git a/csharp/Lib/Units/Voltage.generated.cs b/csharp/Lib/Units/Voltage.generated.cs index 4f5c57f91..56ee32836 100644 --- a/csharp/Lib/Units/Voltage.generated.cs +++ b/csharp/Lib/Units/Voltage.generated.cs @@ -1,5 +1,5 @@ #nullable enable // Auto-generated code requires an explicit '#nullable' directive in source. -#define Equal +#define Generate using static System.Math; using System.Text.Json; @@ -22,40 +22,12 @@ public readonly partial struct Voltage public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value); public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar); - // parallel + // 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 t) => new T(-t.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); - - #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 public static Boolean operator ==(T left, T right) => left.Value == right.Value;