// 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; }
// 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; }
// 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); }
// This constructor makes an index that points into a Quantity List public CQtyPointerList(ref CQuantityList thatQuantityList) : base() { int i; for (i = 0; i < thatQuantityList.Count; ++i) { CQtyPointer thisQtyPointer = new CQtyPointer(thatQuantityList[i]); Add(thisQtyPointer); } Sort(); }
// This constructor makes an index that points into a Quantity List public CFactorList(ref CQuantityList thatQuantityList) : base() { int i; for (i = 0; i < thatQuantityList.Count; ++i) { CFactor thisFactor = new CFactor(thatQuantityList[i]); Add(thisFactor); } Sort(); }
// 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); } }
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; }
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(); }
// This is a candidate group to define a quantity. // 1. Determine if the quantity already exists. // 2. If new then determine if it has enough members and sufficient diversity // to define a new quantity. // 3. Assign the quantity to every matrix cell in this group. public void QualifyGroup(int intFirst, int intCount, CQuantityList myQuantityList) { CStringList labelList = new CStringList(); bool bGoodQuantity = true; bool bIsExact = false; // set flag if this is new quantity for (int i = intFirst; i < intFirst + intCount; ++i) { CMatrixCell myMatrixCell = this[i]; if (myMatrixCell.IsExact) { bIsExact = true; } CQuantity qtyX = myMatrixCell.PtrX.Qty; CQuantity qtyY = myMatrixCell.PtrY.Qty; if (!qtyX.IsInteger) { labelList.Add(qtyX.Label); } if (!qtyY.IsInteger) { labelList.Add(qtyY.Label); } } if (labelList.Count > 1) { // This is a qualifying quantity double dblLog = this[intFirst].Number.Log; int intQtyIndex = myQuantityList.FindEquivalent(this[intFirst].Number); bool bNewQuantity = (intQtyIndex < 0); bGoodQuantity = true; CQuantity thisQuantity; if (bNewQuantity) { string strLabel = "X_" + myQuantityList.Count.ToString(); thisQuantity = new CQuantity(myQuantityList, strLabel, dblLog, false); thisQuantity.IsExact = bIsExact; myQuantityList.Add(thisQuantity); } else { thisQuantity = myQuantityList[intQtyIndex]; } CSymbol symbolInverse = thisQuantity.SymbolInverse(); CQuantity inverseQuantity = thisQuantity.Inverse(symbolInverse.Label); int intInverse = myQuantityList.FindEquivalent(inverseQuantity); bool bNewInverse = (intInverse < 0); if (bNewInverse) { myQuantityList.Add(inverseQuantity); inverseQuantity.SetInverse(ref thisQuantity); } else { // inverse quantity already exists in the list inverseQuantity = myQuantityList[intInverse]; if (bNewQuantity) { if (inverseQuantity.IsInteger) { // never add inverses to integers bGoodQuantity = false; myQuantityList.RemoveAt(thisQuantity.Index); } else { thisQuantity.Symbol = inverseQuantity.SymbolInverse(); thisQuantity.SetInverse(ref inverseQuantity); thisQuantity.IsExact = inverseQuantity.IsExact; } } } if (bGoodQuantity) { // assign the quantity to every matrix cell in the group for (int i = intFirst; i < intFirst + intCount; ++i) { CMatrixCell myMatrixCell = this[i]; myMatrixCell.PtrQty = new CQtyPointer(thisQuantity); } } } }
// 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); } } }