/// <summary> /// Adding quantities with different storage types /// </summary> /// <typeparam name="Q">Second Quantity Type</typeparam> /// <param name="firstQuantity"></param> /// <param name="secondQuantity"></param> /// <returns></returns> public static AnyQuantity <T> Add <Q>(AnyQuantity <T> firstQuantity, AnyQuantity <Q> secondQuantity) { if (firstQuantity.Equals(secondQuantity)) { AnyQuantity <T> AQ = null; try { AQ = QuantityDimension.QuantityFrom <T>(firstQuantity.Dimension); //exception happen when adding two derived quantities together } catch (QuantityNotFoundException) { //keep the first quantity configuration. AQ = (AnyQuantity <T>)firstQuantity.Clone(); } T firstVal = (firstQuantity.Value); Q secondVal = (secondQuantity.Value); //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = MultiplyScalarByGeneric <Q>(stof.ConversionFactor, secondVal); } var expr = Expression.Add(Expression.Constant(firstVal), Expression.Constant(secondVal)); // Construct Lambda function which return one object. Expression <Func <T> > cq = Expression.Lambda <Func <T> >(expr); // compile the function Func <T> aqf = cq.Compile(); // execute the function T result = aqf(); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //assign the unit of first quantity to the result. AQ.Unit = firstQuantity.Unit; } AQ.Value = result; return(AQ); } else { throw new QuantitiesNotDimensionallyEqualException(); } }
public void TestBaryeUnit() { Barye u = new Barye(); UnitPathStack up = u.PathToDefaultUnit(); Assert.AreEqual(0.1, up.ConversionFactor); }
public void PathToDefaultUnitTest() { //from pico Gram to default Kilo Gram Unit target = new Gram(); ((MetricUnit)target).UnitPrefix = MetricPrefix.None; UnitPathStack actual = target.PathToDefaultUnit(); double expected = System.Math.Pow(10, -3); Assert.AreEqual(expected, actual.ConversionFactor); target = new Metre(); ((MetricUnit)target).UnitPrefix = MetricPrefix.Tera; actual = target.PathToDefaultUnit(); expected = System.Math.Pow(10, 12); Assert.AreEqual(expected, actual.ConversionFactor); target = new Unit(typeof(QuantitySystem.Quantities.Volume <>)); actual = target.PathToDefaultUnit(); expected = 1; Assert.AreEqual(expected, actual.ConversionFactor); target = new QuantitySystem.Units.Metric.Litre(); //((SIUnit)target).UnitPrefix = SIPrefix.Kilo; actual = target.PathToDefaultUnit(); // from Litre to m^3 expected = 1e-3; Assert.AreEqual(expected, actual.ConversionFactor); target = new QuantitySystem.Units.Metric.Litre(); ((MetricUnit)target).UnitPrefix = MetricPrefix.Kilo; actual = target.PathToDefaultUnit(); // from Litre to m^3 expected = 1; Assert.AreEqual(expected, actual.ConversionFactor); target = new QuantitySystem.Units.Metric.Bar(); //((SIUnit)target).UnitPrefix = SIPrefix.Kilo; actual = target.PathToDefaultUnit(); // from Litre to m^3 expected = 1e+5; Assert.AreEqual(expected, actual.ConversionFactor); target = new QuantitySystem.Units.Metric.Cgs.Dyne(); actual = target.PathToDefaultUnit(); expected = 1e-5; Assert.AreEqual(expected, actual.ConversionFactor); }
public void PathFromUnitTest() { double expected = 63360; Mile mil = new Mile(); Inch i = new Inch(); UnitPathStack actual = i.PathFromUnit(mil); Assert.AreEqual(expected, actual.ConversionFactor); }
public void PathToDefaultUnitTest() { //scenario 1: Mile To Foot UnitPathStack expected = new UnitPathStack(); expected.Push( new UnitPathItem { Unit = new Mile(), Numerator = 1, Denominator = 1 } ); expected.Push( new UnitPathItem { Unit = new Yard(), Numerator = 1760, Denominator = 1 } ); expected.Push( new UnitPathItem { Unit = new Foot(), Numerator = 3, Denominator = 1 } ); Mile mil = new Mile(); UnitPathStack actual = mil.PathToDefaultUnit(); Assert.AreEqual(expected, actual); Inch f = new Inch(); UnitPathStack up = f.PathToDefaultUnit(); Assert.AreEqual(1 / 12.0, up.ConversionFactor); }
public void PathFromDefaultUnitTest() { MetricUnit target = new Gram(); target.UnitPrefix = MetricPrefix.Milli; UnitPathStack actual = target.PathFromDefaultUnit(); double expected = System.Math.Pow(10, 6); Assert.AreEqual(expected, actual.ConversionFactor); target = new Metre(); target.UnitPrefix = MetricPrefix.Tera; actual = target.PathFromDefaultUnit(); expected = System.Math.Pow(10, -12); Assert.AreEqual(expected, actual.ConversionFactor); }
public void PathFromDefaultUnitTest() { //scenario 1: Mile To Foot UnitPathStack expected = new UnitPathStack(); expected.Push( new UnitPathItem { Unit = new Foot(), Numerator = 1, Denominator = 1 } ); expected.Push( new UnitPathItem { Unit = new Yard(), Numerator = 1, Denominator = 3 } ); expected.Push( new UnitPathItem { Unit = new Mile(), Numerator = 1, Denominator = 1760 } ); Mile mil = new Mile(); UnitPathStack actual = mil.PathFromDefaultUnit(); Assert.AreEqual(expected, actual); }
public void PathToUnitTest() { double expected = 63360; Mile mil = new Mile(); Inch i = new Inch(); UnitPathStack actual = mil.PathToUnit(i); Assert.AreEqual(expected, actual.ConversionFactor); Gram g = new Gram(); g.UnitPrefix = MetricPrefix.None; Gram Mg = new Gram(); Mg.UnitPrefix = MetricPrefix.Mega; actual = g.PathToUnit(Mg); Assert.AreEqual(1e-6, actual.ConversionFactor); Metre mr = new Metre(); actual = i.PathToUnit(mr); Assert.AreEqual(0.0254, actual.ConversionFactor); //now the idea is to make any combination of units to go to any combination of units QuantityDimension qd = QuantityDimension.ParseMLT("M1L0T-1"); Unit u = Unit.DiscoverUnit(qd); Assert.AreEqual("<kg/s>", u.Symbol); Assert.AreEqual(qd, u.UnitDimension); }
public static bool Inequality(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { if (firstQuantity.Equals(secondQuantity)) { if (typeof(T) == typeof(decimal) || typeof(T) == typeof(double) || typeof(T) == typeof(float) || typeof(T) == typeof(int) || typeof(T) == typeof(short)) { #region Premitive //use direct calculations double firstVal = (double)(object)firstQuantity.Value; double secondVal = (double)(object)secondQuantity.Value; //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = stof.ConversionFactor * secondVal; } return(firstVal != secondVal); #endregion } else { #region Custom Types T firstVal = (firstQuantity.Value); T secondVal = (secondQuantity.Value); //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = MultiplyScalarByGeneric(stof.ConversionFactor, secondVal); } var expr = Expression.NotEqual(Expression.Constant(firstVal), Expression.Constant(secondVal)); // Construct Lambda function which return one object. Expression <Func <bool> > cq = Expression.Lambda <Func <bool> >(expr); // compile the function Func <bool> aqf = cq.Compile(); // execute the function bool result = aqf(); return(result); #endregion } } else { throw new QuantitiesNotDimensionallyEqualException(); } }
public static AnyQuantity <T> Subtract(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { if (firstQuantity.Equals(secondQuantity)) { AnyQuantity <T> AQ = null; try { AQ = QuantityDimension.QuantityFrom <T>(firstQuantity.Dimension); //exception happen when adding two derived quantities together } catch (QuantityNotFoundException) { //keep the first quantity configuration. AQ = (AnyQuantity <T>)firstQuantity.Clone(); } if (typeof(T) == typeof(decimal) || typeof(T) == typeof(double) || typeof(T) == typeof(float) || typeof(T) == typeof(int) || typeof(T) == typeof(short)) { //use direct calculations double firstVal = (double)(object)firstQuantity.Value; double secondVal = (double)(object)secondQuantity.Value; //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = stof.ConversionFactor * secondVal; } ////sum the values double result = firstVal - secondVal; if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //assign the unit of first quantity to the result. AQ.Unit = (Unit)firstQuantity.Unit.Clone(); } AQ.Value = (T)(object)result; return(AQ); } else { T firstVal = (firstQuantity.Value); T secondVal = (secondQuantity.Value); //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = MultiplyScalarByGeneric(stof.ConversionFactor, secondVal); } var expr = Expression.Subtract(Expression.Constant(firstVal), Expression.Constant(secondVal)); // Construct Lambda function which return one object. Expression <Func <T> > cq = Expression.Lambda <Func <T> >(expr); // compile the function Func <T> aqf = cq.Compile(); // execute the function T result = aqf(); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //assign the unit of first quantity to the result. AQ.Unit = firstQuantity.Unit; } AQ.Value = result; return(AQ); } } else { throw new QuantitiesNotDimensionallyEqualException(); } }