simplify units, give up on idea of automatic aggregation
This commit is contained in:
parent
d7852e45c9
commit
c3b1484e99
|
@ -4,7 +4,7 @@ using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Sum]
|
[Generate]
|
||||||
public readonly partial struct Angle
|
public readonly partial struct Angle
|
||||||
{
|
{
|
||||||
public static String Unit => "rad";
|
public static String Unit => "rad";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -2,7 +2,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Sum]
|
[Generate]
|
||||||
public readonly partial struct ApparentPower
|
public readonly partial struct ApparentPower
|
||||||
{
|
{
|
||||||
public static String Unit => "VA";
|
public static String Unit => "VA";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -6,20 +6,20 @@ public record Ac1Bus : AcPhase
|
||||||
{
|
{
|
||||||
public Frequency Frequency { get; init; }
|
public Frequency Frequency { get; init; }
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "RedundantCast")]
|
// [SuppressMessage("ReSharper", "RedundantCast")]
|
||||||
public static Ac1Bus operator |(Ac1Bus left, Ac1Bus right)
|
// public static Ac1Bus operator |(Ac1Bus left, Ac1Bus right)
|
||||||
{
|
// {
|
||||||
var f = left.Frequency | right.Frequency;
|
// var f = left.Frequency | right.Frequency;
|
||||||
var p = (AcPhase)left | (AcPhase)right;
|
// var p = (AcPhase)left | (AcPhase)right;
|
||||||
|
//
|
||||||
return new Ac1Bus
|
// return new Ac1Bus
|
||||||
{
|
// {
|
||||||
Frequency = f,
|
// Frequency = f,
|
||||||
Current = p.Current,
|
// Current = p.Current,
|
||||||
Voltage = p.Voltage,
|
// Voltage = p.Voltage,
|
||||||
Phi = p.Phi
|
// Phi = p.Phi
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,45 +22,45 @@ public record AcPhase : IBus
|
||||||
public Angle Phi { get; init; }
|
public Angle Phi { get; init; }
|
||||||
|
|
||||||
public ApparentPower ApparentPower => Voltage.Value * Current.Value ;
|
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 ReactivePower ReactivePower => ApparentPower.Value * Sin(Phi);
|
||||||
public Number PowerFactor => Cos(Phi);
|
public Decimal PowerFactor => Cos(Phi);
|
||||||
|
|
||||||
|
|
||||||
public static AcPhase operator |(AcPhase left, AcPhase right)
|
// public static AcPhase operator |(AcPhase left, AcPhase right)
|
||||||
{
|
// {
|
||||||
// the Voltages of two phases are expected to be in phase and equal
|
// // the Voltages of two phases are expected to be in phase and equal
|
||||||
|
//
|
||||||
var v = left.Voltage | right.Voltage;
|
// var v = left.Voltage | right.Voltage;
|
||||||
|
//
|
||||||
// currents (RMS) can be different and out of phase
|
// // currents (RMS) can be different and out of phase
|
||||||
// https://www.johndcook.com/blog/2020/08/17/adding-phase-shifted-sine-waves/
|
// // https://www.johndcook.com/blog/2020/08/17/adding-phase-shifted-sine-waves/
|
||||||
|
//
|
||||||
// IF
|
// // IF
|
||||||
// left(t) = ILeft sin(ωt)
|
// // left(t) = ILeft sin(ωt)
|
||||||
// right(t) = IRight sin(ωt + φ).
|
// // right(t) = IRight sin(ωt + φ).
|
||||||
// sum(t) = left(t) + right(t) = ISum sin(ωt + ψ).
|
// // sum(t) = left(t) + right(t) = ISum sin(ωt + ψ).
|
||||||
|
//
|
||||||
// THEN
|
// // THEN
|
||||||
// ψ = arctan( IRight * sin(φ) / (ILeft + IRight cos(φ)) ).
|
// // ψ = arctan( IRight * sin(φ) / (ILeft + IRight cos(φ)) ).
|
||||||
// C = IRight * sin(φ) / sin(ψ).
|
// // C = IRight * sin(φ) / sin(ψ).
|
||||||
|
//
|
||||||
// in this calculation left(t) has zero phase shift.
|
// // in this calculation left(t) has zero phase shift.
|
||||||
// we can shift both waves by -left.Phi, so
|
// // we can shift both waves by -left.Phi, so
|
||||||
// φ := right.phi - left.phi
|
// // φ := right.phi - left.phi
|
||||||
|
//
|
||||||
|
//
|
||||||
var phi = right.Phi - left.Phi;
|
// var phi = right.Phi - left.Phi;
|
||||||
var phiSum = ATan2(right.Current * Sin(phi), left.Current + right.Current * Cos(phi));
|
// var phiSum = ATan2(right.Current * Sin(phi), left.Current + right.Current * Cos(phi));
|
||||||
var iSum = right.Current * Sin(phi) / Sin(phiSum);
|
// var iSum = right.Current * Sin(phi) / Sin(phiSum);
|
||||||
|
//
|
||||||
return new AcPhase
|
// return new AcPhase
|
||||||
{
|
// {
|
||||||
Voltage = v,
|
// Voltage = v,
|
||||||
Current = iSum,
|
// Current = iSum,
|
||||||
Phi = phiSum
|
// Phi = phiSum
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,8 +2,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,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
using InnovEnergy.Lib.Time.Unix;
|
using InnovEnergy.Lib.Time.Unix;
|
||||||
using InnovEnergy.Lib.Units.Generator;
|
using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Sum]
|
[Generate]
|
||||||
public readonly partial struct Energy
|
public readonly partial struct Energy
|
||||||
{
|
{
|
||||||
public static String Unit => "kWh";
|
public static String Unit => "kWh";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -2,7 +2,8 @@ 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";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
namespace InnovEnergy.Lib.Units.Generator;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Struct)]
|
|
||||||
internal class EqualAttribute: Attribute
|
|
||||||
{}
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
|
internal class GenerateAttribute : Attribute
|
||||||
|
{}
|
|
@ -1,5 +0,0 @@
|
||||||
namespace InnovEnergy.Lib.Units.Generator;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Struct)]
|
|
||||||
internal class MeanAttribute: Attribute
|
|
||||||
{}
|
|
|
@ -1,5 +0,0 @@
|
||||||
namespace InnovEnergy.Lib.Units.Generator;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Struct)]
|
|
||||||
internal class SumAttribute: Attribute
|
|
||||||
{}
|
|
|
@ -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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
scriptDir=$( dirname -- "$0"; )
|
scriptDir=$( dirname -- "$0"; )
|
||||||
cd "$scriptDir/.." || exit
|
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
|
do
|
||||||
path="${match%:*}"
|
path="${match%:*}"
|
||||||
type="${match#*:}"
|
type="${match#*:}"
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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<Number>
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +1,12 @@
|
||||||
|
using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
using T = Percent;
|
[Generate]
|
||||||
|
public readonly partial struct Percent
|
||||||
public readonly struct Percent
|
|
||||||
{
|
{
|
||||||
public static String Unit => "%";
|
public static String Unit => "%";
|
||||||
public static String Symbol => "%"; // ??
|
public static String Symbol => "%"; // ??
|
||||||
|
|
||||||
public Percent(Decimal value) => Value = value;
|
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();
|
|
||||||
}
|
}
|
|
@ -1,10 +1,9 @@
|
||||||
|
|
||||||
using InnovEnergy.Lib.Time.Unix;
|
using InnovEnergy.Lib.Time.Unix;
|
||||||
using InnovEnergy.Lib.Units.Generator;
|
using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Sum]
|
[Generate]
|
||||||
public readonly partial struct Power
|
public readonly partial struct Power
|
||||||
{
|
{
|
||||||
public static String Unit => "W";
|
public static String Unit => "W";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -3,7 +3,7 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Sum]
|
[Generate]
|
||||||
public readonly partial struct ReactivePower
|
public readonly partial struct ReactivePower
|
||||||
{
|
{
|
||||||
public static String Unit => "var";
|
public static String Unit => "var";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -3,9 +3,8 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
|
||||||
// TODO: op parallel is wrong
|
|
||||||
|
|
||||||
[Sum]
|
[Generate]
|
||||||
public readonly partial struct Resistance
|
public readonly partial struct Resistance
|
||||||
{
|
{
|
||||||
public static String Unit => "Ω";
|
public static String Unit => "Ω";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
|
||||||
|
|
||||||
public readonly struct State : IReadOnlyList<String>
|
|
||||||
{
|
|
||||||
public IReadOnlyList<String> Values { get; }
|
|
||||||
|
|
||||||
public State(IReadOnlyList<String> 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<String>)values){}
|
|
||||||
public State(params State[] states) : this((IReadOnlyList<String>)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<String> s) => new((IReadOnlyList<String>)s);
|
|
||||||
public static implicit operator State(String[] s) => new((IReadOnlyList<String>)s);
|
|
||||||
public static implicit operator State(List<Enum> 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<String> 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<T> From<T>(T t) where T : Enum
|
|
||||||
{
|
|
||||||
return new State<T>(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
|
||||||
|
|
||||||
public readonly struct State<T> : IReadOnlyList<T> where T:Enum
|
|
||||||
{
|
|
||||||
public IReadOnlyList<T> Values { get; }
|
|
||||||
|
|
||||||
public State(IReadOnlyList<T> values) => Values = values;
|
|
||||||
|
|
||||||
public State(params T[] values) : this((IReadOnlyList<T>)values){}
|
|
||||||
public State(params State<T>[] states) : this((IReadOnlyList<T>)states.SelectMany(s => s.Values).ToList()){}
|
|
||||||
|
|
||||||
public static implicit operator State<T>(T s) => new((IReadOnlyList<T>)s);
|
|
||||||
public static implicit operator State<T>(List<T> s) => new((IReadOnlyList<T>)s);
|
|
||||||
public static implicit operator State<T>(T[] s) => new((IReadOnlyList<T>)s);
|
|
||||||
|
|
||||||
public static State<T> operator |(State<T> left, State<T> right) => new State<T>(left, right);
|
|
||||||
|
|
||||||
public IEnumerator<T> 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];
|
|
||||||
}
|
|
|
@ -2,14 +2,14 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
using T=Temperature;
|
using T = Temperature;
|
||||||
|
|
||||||
[Mean]
|
|
||||||
|
[Generate]
|
||||||
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,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
|
@ -21,18 +21,14 @@ public static class Units
|
||||||
public static Byte DisplaySignificantDigits { get; set; } = 3;
|
public static Byte DisplaySignificantDigits { get; set; } = 3;
|
||||||
public static Byte JsonSignificantDigits { get; set; } = 3;
|
public static Byte JsonSignificantDigits { get; set; } = 3;
|
||||||
|
|
||||||
|
public static Current A (this Decimal value) => value;
|
||||||
public const Decimal MaxRelativeError = 0.05m; // 5%
|
public static Voltage V (this Decimal value) => value;
|
||||||
|
public static Power W (this Decimal value) => value;
|
||||||
public static Current A (this Decimal value) => new Current(value);
|
public static ReactivePower Var (this Decimal value) => value;
|
||||||
public static Voltage V (this Decimal value) => new Voltage(value);
|
public static ApparentPower Va (this Decimal value) => value;
|
||||||
public static Power W (this Decimal value) => new Power(value);
|
public static Resistance Ohm (this Decimal value) => value;
|
||||||
public static ReactivePower Var (this Decimal value) => new ReactivePower(value);
|
public static Frequency Hz (this Decimal value) => value;
|
||||||
public static ApparentPower Va (this Decimal value) => new ApparentPower(value);
|
public static Angle Rad (this Decimal value) => value;
|
||||||
public static Resistance Ohm (this Decimal value) => new Resistance(value);
|
public static Temperature Celsius(this Decimal value) => value;
|
||||||
public static Frequency Hz (this Decimal value) => new Frequency(value);
|
public static Energy KWh (this Decimal value) => value;
|
||||||
public static Angle Rad (this Decimal value) => new Angle(value);
|
|
||||||
public static Temperature Celsius(this Decimal value) => new Temperature(value);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,7 +2,8 @@ using InnovEnergy.Lib.Units.Generator;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Units;
|
namespace InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
[Equal]
|
|
||||||
|
[Generate]
|
||||||
public readonly partial struct Voltage
|
public readonly partial struct Voltage
|
||||||
{
|
{
|
||||||
public static String Unit => "V";
|
public static String Unit => "V";
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#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
|
#define Generate
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
using System.Text.Json;
|
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(scalar * t.Value);
|
||||||
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);
|
||||||
|
|
||||||
// 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
|
// 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;
|
||||||
|
|
Loading…
Reference in New Issue