/// <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(); } }
/// <summary> /// This is a specific raise to double storage quantity power. /// </summary> /// <param name="quantity"></param> /// <param name="exponent"></param> /// <returns></returns> public static AnyQuantity <T> Power(AnyQuantity <T> quantity, AnyQuantity <double> exponent) { if (!exponent.Dimension.IsDimensionless) { throw new QuantityException("Raising Quantity to a non dimensionless quantity is not implemented", new NotImplementedException()); } // and I am ignoring the units conversion also Unit unit = quantity.Unit.RaiseUnitPower((float)exponent.Value); AnyQuantity <T> result = null; if (unit.QuantityType != typeof(DerivedQuantity <>)) { result = unit.MakeQuantity <T>(RaiseGenericByScalar(quantity.Value, exponent.Value)); } else { result = new DerivedQuantity <T>(unit.UnitDimension); result.Value = RaiseGenericByScalar(quantity.Value, exponent.Value); result.Unit = unit; } Debug.Assert(result.Dimension.Equals(result.Unit.UnitDimension), "Dimensions are not equal after power"); return(result); }
public static AnyQuantity <T> Divide(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { //to preserve the units we make a derivedquantity with passed quantities // then we take the derived unit in temporary store // then we try to get strongly typed Quantity // then assign the unit to the generated quantity. // this way we won't have to know the unit system of the quantity. AnyQuantity <T> sec_qty = (AnyQuantity <T>)secondQuantity.Invert(); //this is a divide process we must make 1/exponenet :) AnyQuantity <T> qresult = (AnyQuantity <T>)ConstructDerivedQuantity(firstQuantity, sec_qty); try { qresult = QuantityDimension.QuantityFrom <T>(qresult.Dimension); } catch (QuantityNotFoundException) { } if (typeof(T) == typeof(decimal) || typeof(T) == typeof(double) || typeof(T) == typeof(float) || typeof(T) == typeof(int) || typeof(T) == typeof(short)) { qresult.Value = (T)(object)(((double)(object)firstQuantity.Value) * ((double)(object)sec_qty.Value)); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, sec_qty.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = (T)(object)(un.GetUnitOverflow() * ((double)(object)qresult.Value)); } } } else { qresult.Value = DivideGenericByGeneric(firstQuantity.Value, secondQuantity.Value); //check if any of the two quantities have a valid unit // to be able to derive the current quantity if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, sec_qty.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = MultiplyScalarByGeneric(un.GetUnitOverflow(), qresult.Value); } } } return(qresult); }
/// <summary> /// Raising power of the same storage types. /// </summary> /// <param name="firstQuantity"></param> /// <param name="secondQuantity"></param> /// <returns></returns> public static AnyQuantity <T> Power(AnyQuantity <T> quantity, AnyQuantity <T> exponent) { if (!(exponent.Dimension.IsDimensionless & quantity.Dimension.IsDimensionless)) { throw new QuantityException("All quantities should be dimensionless, because I don't have a clue about your object power technique", new NotImplementedException()); } AnyQuantity <T> result = new DimensionlessQuantities.DimensionlessQuantity <T>(); result.Value = RaiseGenericByGeneric(quantity.Value, exponent.Value); return(result); }
public override QuantitySystem.Quantities.BaseQuantities.BaseQuantity Invert() { AnyQuantity <T> q = (AnyQuantity <T>)base.Invert(); q.Value = DivideScalarByGeneric(1.0, q.Value); if (q.Unit != null) { q.Unit = this.Unit.Invert(); } return(q); }
public static AnyQuantity <T> Multiply(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { AnyQuantity <T> qresult = (AnyQuantity <T>)ConstructDerivedQuantity <T>(firstQuantity, secondQuantity); try { //correct quantities and units qresult = QuantityDimension.QuantityFrom <T>(qresult.Dimension); } catch (QuantityNotFoundException) { } if (typeof(T) == typeof(decimal) || typeof(T) == typeof(double) || typeof(T) == typeof(float) || typeof(T) == typeof(int) || typeof(T) == typeof(short)) { qresult.Value = (T)(object)(((double)(object)firstQuantity.Value) * ((double)(object)secondQuantity.Value)); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, secondQuantity.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = (T)(object)(un.GetUnitOverflow() * ((double)(object)qresult.Value)); } } } else { qresult.Value = MultiplyGenericByGeneric(firstQuantity.Value, secondQuantity.Value); //check if any of the two quantities have a valid unit // to be able to derive the current quantity if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, secondQuantity.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = MultiplyScalarByGeneric(un.GetUnitOverflow(), qresult.Value); } } } return(qresult); }
public static AnyQuantity <T> Mod(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { AnyQuantity <T> qresult = (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)) { qresult.Value = (T)(object)(((double)(object)firstQuantity.Value) % ((double)(object)secondQuantity.Value)); } else { qresult.Value = ModuloGenericByGeneric(firstQuantity.Value, secondQuantity.Value); } return(qresult); }
/// <summary> /// Parse the input name and return the quantity object from it. /// </summary> /// <typeparam name="T">container type of the value</typeparam> /// <param name="quantityName"></param> /// <returns></returns> public static AnyQuantity <T> Parse(string quantityName) { Type QuantityType = QuantityDimension.QuantityTypeFrom(quantityName); if (QuantityType == null) { throw new QuantityNotFoundException(); } else { //QuantityType = QuantityType.MakeGenericType(typeof(T)); //AnyQuantity<T> qty = (AnyQuantity<T>)Activator.CreateInstance(QuantityType); AnyQuantity <T> qty = QuantityDimension.QuantityFrom <T>(QuantityDimension.DimensionFrom(QuantityType)); return(qty); } }
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(); } }