Beispiel #1
0
 // construct from either value or log
 public CQuantity(CQuantityList thatQuantityList, string strThatLabel, double dblToken, bool bIsValue)
 {
     Init(thatQuantityList);
     _symbol    = new CSymbol(strThatLabel);
     _number    = new CNumber(dblToken, bIsValue);
     _isInteger = _number.IsInteger;
 }
Beispiel #2
0
        public void RepairIndices()
        {
            int q;

            for (q = 0; q < this.Count; ++q)
            {
                CQuantity thisQuantity = this[q];
                thisQuantity.ResetIndex();
                thisQuantity.ResetInverse();
            }
            for (q = 0; q < this.Count; ++q)
            {
                CQuantity thisQuantity = this[q];
                if (thisQuantity.Index == -1)
                {
                    thisQuantity.Index = q;
                    double  dblInverseLog   = -thisQuantity.Log;
                    CNumber inverseNumber   = new CNumber(dblInverseLog, false);
                    int     intInverseIndex = this.FindEquivalent(inverseNumber);
                    if (intInverseIndex > -1)
                    {
                        CQuantity inverseQty = this[intInverseIndex];
                        if (inverseQty.Index == -1)
                        {
                            inverseQty.Index = intInverseIndex;
                        }
                        thisQuantity.SetInverse(ref inverseQty);
                    }
                }
                thisQuantity.ExpressionList.Sort();
            }
        }
Beispiel #3
0
        // this constructor initializes from a line of QuantityValues.txt
        public CQuantity(CQuantityList thatQuantityList, string strLine)
        {
            Init(thatQuantityList);
            string strThatLabel = ParseLine(ref strLine);
            string strToken     = ParseLine(ref strLine);
            string strExactFlag = ParseLine(ref strLine);

            _symbol = new CSymbol(strThatLabel);
            if (strToken == "")
            {
                _number = new CNumber();
            }
            else
            {
                _number      = new CNumber(strToken, true);
                _uncertainty = new CNumber(_number.Uncertainty);
                _lowfence    = new CNumber(_number.Value - _uncertainty.Value, true);
                _highfence   = new CNumber(_number.Value + _uncertainty.Value, true);
            }
            _isExact         = strExactFlag.ToUpper() == "X";
            _isComputational = strExactFlag.ToUpper() == "C";
            _isQED           = strExactFlag.ToUpper() == "Q";
            _isSuppressed    = strExactFlag.ToUpper() == "S";
            _isInteger       = _number.IsInteger;
        }
Beispiel #4
0
 // construct integer quantity from label and value
 public CQuantity(CQuantityList thatQuantityList, bool bIsInteger, string strThatLabel, double dblToken)
 {
     Init(thatQuantityList);
     _isExact   = true;
     _isInteger = true;
     _symbol    = new CSymbol(strThatLabel);
     _number    = new CNumber(dblToken, true);
 }
Beispiel #5
0
 public void ApplyUncertainty(double dblUncertainty)
 {
     _uncertainty = new CNumber(dblUncertainty);
     if (_uncertainty.Value > 0)
     {
         _lowfence  = new CNumber(_number.Value - _uncertainty.Value, true);
         _highfence = new CNumber(_number.Value + _uncertainty.Value, true);
     }
 }
Beispiel #6
0
        public CNumber MultiplyIntegers(CQuantity thatQuantity)
        {
            CNumber numberProduct = null;

            if (_isInteger && thatQuantity._isInteger)
            {
                double dblValue = this.Value * thatQuantity.Value;
                numberProduct = new CNumber(dblValue, true);
            }
            return(numberProduct);
        }
Beispiel #7
0
        // Multiply integers.
        // Called by CFactoryList.Normalize().
        public CNumber MultiplyIntegers(CFactor thatFactor)
        {
            CNumber numberProduct = null;

            if (this.Qty.IsInteger && thatFactor.Qty.IsInteger)
            {
                double dblValue = this.Qty.Value * thatFactor.Qty.Value;
                numberProduct = new CNumber(dblValue, true);
            }
            return(numberProduct);
        }
Beispiel #8
0
 // Simplify integer to an integer power.
 // Resultant power is either 1 or 1/n.
 public void ApplyPowerToInteger()
 {
     if (Qty.IsInteger)
     {
         int           intValue        = (int)Qty.Number.Value;
         CRatio        thisRatio       = new CRatio(intValue);
         bool          bSuccess        = thisRatio.ApplyPower(ref _ratioPower);
         CNumber       numberToPower   = new CNumber(thisRatio);
         CQuantityList theQuantityList = this.Qty.QuantityList;
         // Because the calculated quantity value has changed, the factor qty must be replaced.
         this.Qty = theQuantityList.ReplaceIntegerQuantity(numberToPower);
     }
 }
Beispiel #9
0
        // return index of equivalent if found, else -1
        public int FindEquivalent(CNumber thatNumber)
        {
            int intIndex = -1;

            for (int i = 0; i < this.Count; ++i)
            {
                if (this[i].IsEquivalent(thatNumber))
                {
                    intIndex = i;
                    break;
                }
            }
            return(intIndex);
        }
Beispiel #10
0
        // Called in the process of normalizing expressions and factorlists
        public CQuantity ReplaceIntegerQuantity(CNumber thatNumber)
        {
            CQuantity thisQuantity = null;
            int       intIndex     = this.FindEquivalent(thatNumber);

            if (intIndex > -1)
            {
                thisQuantity = this[intIndex];
            }
            else
            {
                thisQuantity = new CQuantity(this, true, thatNumber.Value.ToString(), thatNumber.Value);
                this.Add(thisQuantity);
            }
            return(thisQuantity);
        }
Beispiel #11
0
 private void Init(CQuantityList thatQuantityList)
 {
     _intIndex                = -1;
     _isExact                 = false;
     _isComputational         = false;
     _isQED                   = false;
     _isSuppressed            = false;
     _isInteger               = false;
     _uncertainty             = new CNumber(0);
     _lowfence                = new CNumber();
     _highfence               = new CNumber();
     _candidate               = new CNumber();
     _expressionList          = new CExpressionList();
     _candidateExpressionList = new CExpressionList();
     _inverseQty              = null;
     _quantityList            = thatQuantityList;
 }
Beispiel #12
0
 // Deep copy. Used in CQuantity::CalculateSubstitution and in deep copy constructors.
 public CQuantity(CQuantity thatQuantity)
 {
     Init(thatQuantity.QuantityList);
     _symbol          = new CSymbol(thatQuantity._symbol);
     _number          = new CNumber(thatQuantity._number);
     _uncertainty     = new CNumber(thatQuantity._uncertainty);
     _lowfence        = new CNumber(thatQuantity._lowfence);
     _highfence       = new CNumber(thatQuantity._highfence);
     _intIndex        = thatQuantity._intIndex;
     _inverseQty      = thatQuantity.InverseQty;
     _expressionList  = new CExpressionList(thatQuantity._expressionList);
     _isExact         = thatQuantity._isExact;
     _isComputational = thatQuantity._isComputational;
     _isQED           = thatQuantity._isQED;
     _isSuppressed    = thatQuantity._isSuppressed;
     _isInteger       = thatQuantity.IsInteger;
 }
Beispiel #13
0
 // Calculate a new candidate value for this quantity as
 // an average of its expressions. Perform all calculations
 // using the log to limit propagation of truncation errors.
 public void CalcCandidate()
 {
     if (!_isExact && _expressionList.Count > 0)
     {
         _candidate.Log = _expressionList.AverageLog();
         // keep the calculated value within the fences
         if (_uncertainty.Value != 0)
         {
             if (_candidate.Log < _lowfence.Log)
             {
                 _candidate.Log = _lowfence.Log;
             }
             else if (_candidate.Log > _highfence.Log)
             {
                 _candidate.Log = _highfence.Log;
             }
         }
     }
     else
     {
         _candidate = new CNumber(_number);
     }
 }
Beispiel #14
0
        // return the evaluated log as a formatted string
        public string LogToString()
        {
            CNumber thisNumber = new CNumber(Log, false);

            return(thisNumber.LogToString());
        }
Beispiel #15
0
        // return the evaluated value as a formatted string
        public string ValueToString()
        {
            CNumber thisNumber = new CNumber(Value, true);

            return(thisNumber.ToString());
        }
Beispiel #16
0
        public void Normalize()
        {
            int intNumIndex, intDenomIndex = 0;

            _numerator.Normalize();
            _denominator.Normalize();
            if (_numerator.Count > 0 && _denominator.Count > 0)
            {
                for (intNumIndex = _numerator.Count - 1; intNumIndex > -1; --intNumIndex)
                {
                    // if dupe is found in denominator then adjust both numerator and denominator
                    CFactor numeratorFactor = _numerator[intNumIndex];
                    intDenomIndex = _denominator.Find(numeratorFactor.Label);
                    if (intDenomIndex > -1)
                    {
                        CFactor denominatorFactor = _denominator[intDenomIndex];
                        numeratorFactor.DivideLike(denominatorFactor);
                        _denominator.RemoveAt(intDenomIndex);
                        _isLogValid = false;
                    }
                    // if inverse is found in denominator then adjust both numerator and denominator
                    intDenomIndex = _denominator.Find(numeratorFactor.Qty.InverseLabel);
                    if (intDenomIndex > -1)
                    {
                        CFactor   denominatorFactor = _denominator[intDenomIndex];
                        CQuantity inverseQty        = denominatorFactor.Qty.InverseQty;
                        denominatorFactor.Qty = inverseQty;
                        numeratorFactor.MultiplyLike(denominatorFactor);
                        _denominator.RemoveAt(intDenomIndex);
                        _isLogValid = false;
                    }
                }
            }
            // if numerator factor has negative power swap it to denominator
            for (intNumIndex = _numerator.Count - 1; intNumIndex > -1; --intNumIndex)
            {
                CFactor numeratorFactor = _numerator[intNumIndex];
                if (numeratorFactor.Power == 0)
                {
                    _numerator.RemoveAt(intNumIndex);
                }
                else if (numeratorFactor.Power < 0)
                {
                    _numerator.RemoveAt(intNumIndex);
                    numeratorFactor.FlipPower();
                    _denominator.Add(numeratorFactor);
                    _isLogValid = false;
                }
            }
            // if denominator factor has negative power swap it to numerator
            for (intDenomIndex = _denominator.Count - 1; intDenomIndex > -1; --intDenomIndex)
            {
                CFactor denominatorFactor = _denominator[intDenomIndex];
                if (denominatorFactor.Power == 0)
                {
                    _denominator.RemoveAt(intDenomIndex);
                }
                else if (denominatorFactor.Power < 0)
                {
                    _denominator.RemoveAt(intDenomIndex);
                    denominatorFactor.FlipPower();
                    _numerator.Add(denominatorFactor);
                    _isLogValid = false;
                }
            }
            // net out integers between numerator and denominator
            int intNumeratorIndex   = _numerator.FindInteger();
            int intDenominatorIndex = _denominator.FindInteger();

            if (intNumeratorIndex > -1 && intDenominatorIndex > -1)
            {
                CFactor numeratorFactor   = _numerator[intNumeratorIndex];
                CFactor denominatorFactor = _denominator[intDenominatorIndex];
                if (numeratorFactor.RatioPower.Equals(1) && denominatorFactor.RatioPower.Equals(1))
                {
                    int intNumeratorValue   = (int)numeratorFactor.Qty.Value;
                    int intDenominatorValue = (int)denominatorFactor.Qty.Value;

                    // Putting both integers into a CRatio has the effect of reducing them
                    CRatio        ratioThis         = new CRatio(intNumeratorValue, intDenominatorValue);
                    double        dblNumerator      = (double)ratioThis.Numerator;
                    double        dblDenominator    = (double)ratioThis.Denominator;
                    CNumber       numberNumerator   = new CNumber(dblNumerator);
                    CNumber       numberDenominator = new CNumber(dblDenominator);
                    CQuantityList theQuantityList   = numeratorFactor.Qty.QuantityList;

                    numeratorFactor.Qty   = theQuantityList.ReplaceIntegerQuantity(numberNumerator);
                    denominatorFactor.Qty = theQuantityList.ReplaceIntegerQuantity(numberDenominator);
                }
            }
            _numerator.Normalize();
            _denominator.Normalize();
            SetSymbolCount();
        }
Beispiel #17
0
        // Substitute every term of each expression to form potential new expressions
        public void CalculateSubstitution(int intMaxFactors, bool bFirstPass)
        {
            int             intLimit   = _expressionList.Count;
            double          dblLogThis = this.Log;
            CExpressionList thisExpressionList;

            // Integers are never substituted.
            if (!this._isInteger)
            {
                // On first pass initialize from the established expression list.
                // On subsequent passes build on previous candidate list.
                if (bFirstPass)
                {
                    thisExpressionList       = new CExpressionList(_expressionList);
                    _candidateExpressionList = new CExpressionList(_expressionList);
                }
                else
                {
                    thisExpressionList = new CExpressionList(_candidateExpressionList);
                }
                // Limit this to only the expressions that are already in the list.
                intLimit = thisExpressionList.Count;
                // for each expression in this quantity's expression list
                for (int i = 0; i < intLimit; ++i)
                {
                    CExpression baseExpression      = thisExpressionList[i];
                    CNumber     baseNumber          = new CNumber(baseExpression.Log, false);
                    int         intNumeratorLimit   = baseExpression.Numerator.Count;
                    int         intDenominatorLimit = baseExpression.Denominator.Count;
                    // for each factor in the numerator
                    for (int intFactorIndex = 0; intFactorIndex < intNumeratorLimit; ++intFactorIndex)
                    {
                        CFactor   baseFactor   = baseExpression.Numerator[intFactorIndex];
                        CQuantity baseQuantity = new CQuantity(baseFactor.Qty);
                        // Integers are never substituted.
                        // Computational intermediates are never substituted. They are expanded on printout.
                        if (!baseQuantity._isInteger /* && !baseQuantity._isComputational*/)
                        {
                            // for each expression associated with the numerator factor
                            for (int k = 0; k < baseQuantity.ExpressionList.Count; ++k)
                            {
                                CExpression insertExpression = new CExpression(baseQuantity.ExpressionList[k]);
                                if (!insertExpression.ContainsSymbol(this.Symbol))
                                {
                                    CExpression newExpression = new CExpression(baseExpression);
                                    newExpression.SubstituteIntoNumerator(intFactorIndex, insertExpression);
                                    CNumber newNumber = new CNumber(newExpression.Log, false);
                                    if (!baseNumber.IsEquivalent(newNumber))
                                    {
                                        // !!! error
                                        double dblLogTest = newExpression.Log; // testing only
                                    }
                                    newExpression.Normalize();
                                    if (newExpression.SymbolCount <= intMaxFactors)
                                    {
                                        _candidateExpressionList.Add(newExpression);
                                    }
                                }
                            }
                        }
                    }
                    // for each factor in the denominator
                    for (int intFactorIndex = 0; intFactorIndex < intDenominatorLimit; ++intFactorIndex)
                    {
                        CFactor   baseFactor   = baseExpression.Denominator[intFactorIndex];
                        CQuantity baseQuantity = new CQuantity(baseFactor.Qty);
                        // Integers are never substituted.
                        // Computational intermediates are never substituted. They are expanded on printout.
                        if (!baseQuantity._isInteger /* && !baseQuantity._isComputational*/)
                        {
                            for (int k = 0; k < baseQuantity.ExpressionList.Count; ++k)
                            {
                                // for each expression associated with the denominator factor
                                CExpression insertExpression = new CExpression(baseQuantity.ExpressionList[k]);
                                if (!insertExpression.ContainsSymbol(this.Symbol))
                                {
                                    CExpression newExpression = new CExpression(baseExpression);
                                    newExpression.SubstituteIntoDenominator(intFactorIndex, insertExpression);
                                    CNumber newNumber = new CNumber(newExpression.Log, false);
                                    if (!baseNumber.IsEquivalent(newNumber))
                                    {
                                        // !!! error
                                        double dblLogTest = newExpression.Log; // testing only
                                    }
                                    newExpression.Normalize();
                                    if (newExpression.SymbolCount <= intMaxFactors)
                                    {
                                        _candidateExpressionList.Add(newExpression);
                                    }
                                }
                            }
                        }
                    }
                    _candidateExpressionList.SuppressDupes();
                    _candidateExpressionList.SuppressTautology(this);
                }
                GC.Collect();
            }
        }
Beispiel #18
0
        // Sort quantities and then combine dupes by adding powers.
        public void Normalize()
        {
            Sort();
            int i;

            // combine like factors
            for (i = this.Count - 1; i > 0; --i)
            {
                if (this[i].Label == this[i - 1].Label)
                {
                    // n^x * n^y = n^xy
                    this[i - 1].MultiplyLike(this[i]);
                    this.RemoveAt(i);
                }
            }
            // Simplify integer to a power
            for (i = this.Count - 1; i > -1; --i)
            {
                CFactor thisFactor = this[i];
                if (thisFactor.Qty.IsInteger && thisFactor.Power != 1)
                {
                    thisFactor.ApplyPowerToInteger();
                }
            }
            // combine integer factors
            for (i = this.Count - 1; i > 0; --i)
            {
                CFactor thisFactor = this[i];
                CFactor nextFactor = this[i - 1];
                if (thisFactor.IsInteger && nextFactor.IsInteger)
                {
                    // !!! ToDo: deal with root != 1
                    CNumber       numberProduct   = nextFactor.MultiplyIntegers(thisFactor);
                    CQuantityList theQuantityList = thisFactor.Qty.QuantityList;
                    // Because the calculated quantity value has changed, the factor qty must be replaced.
                    nextFactor.Qty = thisFactor.Qty.QuantityList.ReplaceIntegerQuantity(numberProduct);
                    this.RemoveAt(i);
                }
            }
            // combine inverses
            for (i = this.Count - 1; i > 0; --i)
            {
                CFactor thisFactor = this[i];
                if (thisFactor.Power != 0)
                {
                    CQuantity thisQuantity = thisFactor.Qty;
                    if (thisQuantity.InverseQty != null)
                    {
                        CQuantity inverseQty = thisQuantity.InverseQty;
                        int       intInverse = this.Find(inverseQty.Label);
                        if (intInverse > -1)
                        {
                            // n^x * 1/n^y = n^x/n^y = n^(x-y)
                            CFactor inverseFactor = this[intInverse];
                            thisFactor.Qty = inverseFactor.Qty;
                            inverseFactor.DivideLike(thisFactor);
                            this.RemoveAt(i);
                        }
                    }
                }
            }
            // drop factors that equal 1
            for (i = this.Count - 1; i > -1; --i)
            {
                CFactor thisFactor = this[i];
                // x^0 = 1 and log(1) = 0
                // n*1 = n
                if (thisFactor.Power == 0 || thisFactor.Log == 0)
                {
                    this.RemoveAt(i);
                }
            }
        }
Beispiel #19
0
 // This comparison returns true if log is within standard difference
 // of otherNumber.log.
 public bool IsEquivalent(CNumber otherNumber)
 {
     return(_number.IsEquivalent(otherNumber));
 }