public bool WriteValues(string strPath, string strLogPath) { bool bSuccess = true; StreamWriter swValues = null; string strLine; try { swValues = new StreamWriter(strPath); for (int i = 0; i < this.Count; ++i) { CQuantity thisQuantity = this[i].Qty; strLine = thisQuantity.ToString() + "\t" + thisQuantity.Log.ToString(); swValues.WriteLine(strLine); } } catch (Exception e) { bSuccess = false; string strLogEntry = "\r\n Error writing value file:" + e.Message; File.AppendAllText(strLogPath, strLogEntry); } finally { if (swValues != null) { swValues.Close(); } } return(bSuccess); }
// use to remove x = x or x = xabc where abc = 1 public void SuppressTautology(CQuantity thatQuantity) { CQuantity InverseQuantity = thatQuantity.InverseQty; for (int i = this.Count - 1; i > 0; --i) { CExpression thisExpression = this[i]; if (thisExpression.Numerator.Find(thatQuantity.Label) > -1) { this.RemoveAt(i); } else if (thisExpression.Denominator.Find(thatQuantity.Label) > -1) { this.RemoveAt(i); } else if (InverseQuantity != null && thisExpression.Numerator.Find(InverseQuantity.Label) > -1) { this.RemoveAt(i); } else if (InverseQuantity != null && thisExpression.Denominator.Find(InverseQuantity.Label) > -1 && (thisExpression.Numerator.Count > 1 || (thisExpression.Numerator.Count != 0 && thisExpression.Numerator[0].Qty.Value != 1))) { this.RemoveAt(i); } else { // We don't want large integers in expressions bool bRemoved = false; int intIndex = thisExpression.Numerator.FindInteger(); if (intIndex >= 0) { if (thisExpression.Numerator[intIndex].Qty.Value > 256) { this.RemoveAt(i); bRemoved = true; } } if (!bRemoved) { intIndex = thisExpression.Denominator.FindInteger(); if (intIndex >= 0) { if (thisExpression.Denominator[intIndex].Qty.Value > 256) { this.RemoveAt(i); } } } } } }
// Construct the cell as the product or quotient of quantities x and y public CMatrixCell(CQuantity quantityX, CQuantity quantityY, bool bIsProduct) { _isProduct = bIsProduct; _ptrX = new CFactor(quantityX); _ptrY = new CFactor(quantityY); if (_isProduct) { _number = quantityX.Number.Product(quantityY.Number); } else { _number = quantityX.Number.Quotient(quantityY.Number); } _isExact = (quantityX.IsExact && quantityY.IsExact); }
public bool WriteExpressions(string strPath, string strLogPath) { bool bSuccess = true; StreamWriter swExpressions = null; string strLine; try { swExpressions = new StreamWriter(strPath); for (int i = 0; i < this.Count; ++i) { CQuantity thisQuantity = this[i].Qty; strLine = thisQuantity.SimpleLabel + "\t= "; CExpressionList thisExpressionList = thisQuantity.ExpressionList; thisExpressionList.SuppressDupes(); if (thisExpressionList.Count > 0) { strLine += thisExpressionList[0].ToString(); } swExpressions.WriteLine(strLine); for (int j = 1; j < thisExpressionList.Count; ++j) { strLine = "\t= " + thisExpressionList[j].ToString(); swExpressions.WriteLine(strLine); } } } catch (Exception e) { bSuccess = false; string strLogEntry = "\r\n Error writing expression file:" + e.Message; File.AppendAllText(strLogPath, strLogEntry); } finally { if (swExpressions != null) { swExpressions.Close(); } } return(bSuccess); }
// true if this cell resolves to a quantity that is not just a factor of 1 public bool IsMatrixQuantity() { bool bReturn = true; CQuantity qtyX = this.PtrX.Qty; CQuantity qtyY = this.PtrY.Qty; if (this.IsProduct) { if (qtyX.Label == "1" || qtyY.Label == "1") { bReturn = false; } } else { if (qtyY.Label == "1") { bReturn = false; } } return(bReturn); }
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(); }
public CQtyPointer(CQuantity thisQuantity) { this.Qty = thisQuantity; }
// 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); } } }
public CFactor(CQuantity thatQuantity) { Init(); this._qty = thatQuantity; }