Skip to content

Commit

Permalink
Simplify usage of exponents on measures.
Browse files Browse the repository at this point in the history
  • Loading branch information
atmoos committed Nov 6, 2023
1 parent ad12f15 commit 3f43982
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 47 deletions.
35 changes: 17 additions & 18 deletions source/Quantities.Benchmark/CreateQuantities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,29 @@
using Quantities.Units.Si;
using Quantities.Units.Si.Derived;
using Quantities.Units.Si.Metric;
using Quantities.Dimensions;

namespace Quantities.Benchmark;

internal readonly struct DummyQuant
internal readonly struct DummyQuantity
{
private readonly Double value;
public Double Value => this.value;
public DummyQuant(in Double value) => this.value = value;
public DummyQuantity(in Double value) => this.value = value;
}

public sealed class DummyObject : ICastOperators<DummyObject, Double>
{
private readonly DummyQuant value;
private DummyObject(in DummyQuant value) => this.value = value;
public static DummyObject Of(in Double value) => new(new DummyQuant(in value));
private readonly DummyQuantity value;
private DummyObject(in DummyQuantity value) => this.value = value;
public static DummyObject Of(in Double value) => new(new DummyQuantity(in value));
public static implicit operator Double(DummyObject obj) => obj.value.Value;
}

public readonly struct DummyStruct : ICastOperators<DummyStruct, Double>
{
private readonly DummyQuant value;
private DummyStruct(in DummyQuant value) => this.value = value;
public static DummyStruct Of(in Double value) => new(new DummyQuant(in value));
private readonly DummyQuantity value;
private DummyStruct(in DummyQuantity value) => this.value = value;
public static DummyStruct Of(in Double value) => new(new DummyQuantity(in value));
public static implicit operator Double(DummyStruct obj) => obj.value.Value;
}

Expand Down Expand Up @@ -82,13 +81,13 @@ .NET SDK 7.0.113
| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
|------------------------------- |----------:|----------:|----------:|------:|--------:|-------:|----------:|------------:|
| CreateObject | 6.340 ns | 0.0561 ns | 0.0497 ns | 1.00 | 0.00 | 0.0057 | 24 B | 1.00 |
| CreateStruct | 1.643 ns | 0.0202 ns | 0.0189 ns | 0.26 | 0.00 | - | - | 0.00 |
| CreateScalarQuantity | 5.738 ns | 0.0110 ns | 0.0098 ns | 0.90 | 0.01 | - | - | 0.00 |
| CreateScalarQuantityWithoutOpt | 4.704 ns | 0.0108 ns | 0.0090 ns | 0.74 | 0.01 | - | - | 0.00 |
| CreateQuotientQuantity | 15.821 ns | 0.0588 ns | 0.0491 ns | 2.50 | 0.02 | - | - | 0.00 |
| CreateProductQuantity | 16.747 ns | 0.3553 ns | 0.3802 ns | 2.64 | 0.06 | - | - | 0.00 |
| CreateCachedProductQuantity | 5.459 ns | 0.1217 ns | 0.1138 ns | 0.86 | 0.02 | - | - | 0.00 |
| CreateScalarPowerQuantity | 14.589 ns | 0.0475 ns | 0.0397 ns | 2.30 | 0.02 | - | - | 0.00 |
| CreateSquarePowerQuantity | 5.511 ns | 0.0224 ns | 0.0198 ns | 0.87 | 0.01 | - | - | 0.00 |
| CreateObject | 6.458 ns | 0.0909 ns | 0.0850 ns | 1.00 | 0.00 | 0.0057 | 24 B | 1.00 |
| CreateStruct | 1.635 ns | 0.0607 ns | 0.0596 ns | 0.25 | 0.01 | - | - | 0.00 |
| CreateScalarQuantity | 5.428 ns | 0.0489 ns | 0.0457 ns | 0.84 | 0.01 | - | - | 0.00 |
| CreateScalarQuantityWithoutOpt | 4.546 ns | 0.0143 ns | 0.0119 ns | 0.71 | 0.01 | - | - | 0.00 |
| CreateQuotientQuantity | 15.384 ns | 0.0957 ns | 0.0849 ns | 2.39 | 0.03 | - | - | 0.00 |
| CreateProductQuantity | 15.997 ns | 0.3390 ns | 0.3628 ns | 2.47 | 0.04 | - | - | 0.00 |
| CreateCachedProductQuantity | 5.515 ns | 0.0123 ns | 0.0115 ns | 0.85 | 0.01 | - | - | 0.00 |
| CreateScalarPowerQuantity | 13.346 ns | 0.0560 ns | 0.0467 ns | 2.07 | 0.02 | - | - | 0.00 |
| CreateSquarePowerQuantity | 5.402 ns | 0.0391 ns | 0.0347 ns | 0.84 | 0.01 | - | - | 0.00 |
*/
12 changes: 6 additions & 6 deletions source/Quantities/Core/IFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ public interface IFactory<out TSelf>
}

public interface IScalar<out TQuantity, in TDimension>
where TQuantity : struct, IScalar<TQuantity, TDimension>, TDimension
where TQuantity : IScalar<TQuantity, TDimension>, TDimension
where TDimension : IDimension
{
public TQuantity To<TUnit>(in Scalar<TUnit> other) where TUnit : TDimension, IUnit;
public static abstract TQuantity Of<TUnit>(in Double value, in Scalar<TUnit> measure) where TUnit : TDimension, IUnit;
}

public interface IQuotient<out TQuantity, in TDimension, in TNominatorDimension, in TDenominatorDimension> : IScalar<TQuantity, TDimension>
where TQuantity : struct, IQuotient<TQuantity, TDimension, TNominatorDimension, TDenominatorDimension>, TDimension
where TQuantity : IQuotient<TQuantity, TDimension, TNominatorDimension, TDenominatorDimension>, TDimension
where TDimension : IQuotient<TNominatorDimension, TDenominatorDimension>
where TNominatorDimension : IDimension
where TDenominatorDimension : IDimension
Expand All @@ -33,7 +33,7 @@ public static abstract TQuantity Of<TNominator, TDenominator>(in Double value, i
}

public interface IProduct<out TQuantity, in TDimension, in TLeftDimension, in TRightDimension> : IScalar<TQuantity, TDimension>
where TQuantity : struct, IProduct<TQuantity, TDimension, TLeftDimension, TRightDimension>, TDimension
where TQuantity : IProduct<TQuantity, TDimension, TLeftDimension, TRightDimension>, TDimension
where TDimension : IProduct<TLeftDimension, TRightDimension>
where TLeftDimension : IDimension
where TRightDimension : IDimension
Expand All @@ -47,7 +47,7 @@ public static abstract TQuantity Of<TLeft, TRight>(in Double value, in Product<T
}

public interface ISquare<out TQuantity, in TDimension, in TLinear> : IAlias<TQuantity, TDimension, TLinear>
where TQuantity : struct, ISquare<TQuantity, TDimension, TLinear>, TDimension
where TQuantity : ISquare<TQuantity, TDimension, TLinear>, TDimension
where TDimension : ISquare<TLinear>
where TLinear : IDimension, ILinear
{
Expand All @@ -56,7 +56,7 @@ public interface ISquare<out TQuantity, in TDimension, in TLinear> : IAlias<TQua
}

public interface ICubic<out TQuantity, in TDimension, in TLinear> : IAlias<TQuantity, TDimension, TLinear>
where TQuantity : struct, ICubic<TQuantity, TDimension, TLinear>, TDimension
where TQuantity : ICubic<TQuantity, TDimension, TLinear>, TDimension
where TDimension : ICubic<TLinear>
where TLinear : IDimension, ILinear
{
Expand All @@ -65,7 +65,7 @@ public interface ICubic<out TQuantity, in TDimension, in TLinear> : IAlias<TQuan
}

public interface IAlias<out TQuantity, in TDimension, in TLinear>
where TQuantity : struct, IAlias<TQuantity, TDimension, TLinear>, TDimension
where TQuantity : IAlias<TQuantity, TDimension, TLinear>, TDimension
where TDimension : IDimension
where TLinear : IDimension, ILinear
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
internal interface IExponent
{
public static abstract Int32 E { get; }
public static abstract String Representation { get; }
}

internal readonly struct Square : IExponent
{
public static Int32 E => 2;
public static String Representation => "²";

}

internal readonly struct Cubic : IExponent
{
public static Int32 E => 3;
public static String Representation => "³";
}
36 changes: 17 additions & 19 deletions source/Quantities/Measures/Measures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using Quantities.Prefixes;
using Quantities.Units;

using static Quantities.Measures.Convenience;

namespace Quantities.Measures;

file interface IOps
Expand Down Expand Up @@ -165,7 +163,7 @@ public static void Write(IWriter writer)
private static readonly String dimension = typeof(TDim).Name.ToLowerInvariant();
static Dimension IMeasure.D { get; } = TLinear.D.Pow(TDim.E);
public static Polynomial Poly { get; } = TLinear.Poly.Pow(TDim.E);
public static String Representation { get; } = $"{TLinear.Representation}{TDim.Representation}";
public static String Representation { get; } = $"{TLinear.Representation}{Tools.ExpToString(TDim.E)}";
public static Result Multiply<TOtherMeasure>() where TOtherMeasure : IMeasure => HigherOrderOps<Power<TDim, TLinear>, TLinear, TOtherMeasure>.Product;
public static Result Divide<TOtherMeasure>() where TOtherMeasure : IMeasure => HigherOrderOps<Power<TDim, TLinear>, TLinear, TOtherMeasure>.Quotient;
public static void Write(IWriter writer)
Expand Down Expand Up @@ -260,7 +258,7 @@ public static Result Multiply<TArgument>() where TArgument : IMeasure
return new(polyProduct, Measure.Of<Identity>());
}
Measure? measure;
if (product is Scalar scalar && (measure = Pow<TLeft>(scalar.E)) != null) {
if (product is Scalar scalar && (measure = scalar.As<TLeft>()) != null) {
return new(polyProduct / TLeft.Poly, measure);
}
return new(Polynomial.One, Measure.Of<Product<Product<TLeft, TRight>, TArgument>>());
Expand All @@ -273,7 +271,7 @@ public static Result Divide<TArgument>() where TArgument : IMeasure
return new(polyQuotient, Measure.Of<Identity>());
}
Measure? measure;
if (quotient is Scalar scalar && (measure = Pow<TLeft>(scalar.E)) != null) {
if (quotient is Scalar scalar && (measure = scalar.As<TLeft>()) != null) {
return new(polyQuotient / TLeft.Poly, measure);
}
return new(Polynomial.One, Measure.Of<Quotient<Product<TLeft, TRight>, TArgument>>());
Expand All @@ -293,7 +291,7 @@ public static Result Divide<TArgument>() where TArgument : IMeasure
return new(polyQuotient, Measure.Of<Identity>());
}
Measure? measure;
if (quotient is Scalar scalar && (measure = Pow<TNominator>(scalar.E)) != null) {
if (quotient is Scalar scalar && (measure = scalar.As<TNominator>()) != null) {
return new(polyQuotient / TNominator.Poly, measure);
}
return new(Polynomial.One, Measure.Of<Quotient<TNominator, Product<TDenominator, TArgument>>>());
Expand All @@ -306,7 +304,7 @@ public static Result Divide<TArgument>() where TArgument : IMeasure
public static Result Multiply<TArgument>() where TArgument : IMeasure
{
Dimension target = THigher.D * TArgument.D;
Measure? measure = Pow<TLinear>(target.E);
Measure? measure = target.As<TLinear>();
if (measure is null) {
return new(Polynomial.One, Measure.Of<Product<THigher, TArgument>>());
}
Expand All @@ -316,7 +314,7 @@ public static Result Multiply<TArgument>() where TArgument : IMeasure
public static Result Divide<TArgument>() where TArgument : IMeasure
{
Dimension target = THigher.D / TArgument.D;
Measure? measure = Pow<TLinear>(target.E);
Measure? measure = target.As<TLinear>();
if (measure is null) {
return new(Polynomial.One, Measure.Of<Quotient<THigher, TArgument>>());
}
Expand All @@ -327,15 +325,15 @@ public static Result Divide<TArgument>() where TArgument : IMeasure

file static class Convenience
{
public static Measure? Pow<TLinear>(Int32 exp)
where TLinear : IMeasure => exp switch {
3 => Measure.Of<Power<Cubic, TLinear>>(),
2 => Measure.Of<Power<Square, TLinear>>(),
1 => Measure.Of<TLinear>(),
0 => Measure.Of<Identity>(),
-1 => Measure.Of<Quotient<Identity, TLinear>>(),
-2 => Measure.Of<Quotient<Identity, Power<Square, TLinear>>>(),
-3 => Measure.Of<Quotient<Identity, Power<Cubic, TLinear>>>(),
_ => null
};
public static Measure? As<TLinear>(this Dimension d)
where TLinear : IMeasure => d.E switch {
3 => Measure.Of<Power<Cubic, TLinear>>(),
2 => Measure.Of<Power<Square, TLinear>>(),
1 => Measure.Of<TLinear>(),
0 => Measure.Of<Identity>(),
-1 => Measure.Of<Quotient<Identity, TLinear>>(),
-2 => Measure.Of<Quotient<Identity, Power<Square, TLinear>>>(),
-3 => Measure.Of<Quotient<Identity, Power<Cubic, TLinear>>>(),
_ => null
};
}

0 comments on commit 3f43982

Please sign in to comment.