Symbol SymbolicateMonome(string formula, int begin, int end, Expression exp) { var symbols = new SymbolList(); int sign = 0; int i = begin - 1; int currentTermBegin = begin; int numValues = 0; int currentDepth = 0; double constMultiplier = 1.0; bool divideNext = false; bool constMultiplierUsed = false; for (;;) { i++; if (i == end || (currentDepth == 0 && i > begin && (formula[i] == '*' || formula[i] == '/'))) { numValues++; // Unless we are dealing with a monome, symbolicate the term Symbol newSymbol = SymbolicateValue(formula, formula[currentTermBegin] == '-' ? currentTermBegin + 1 : currentTermBegin, i, exp); // Check if we can simplify the generated symbol if (newSymbol.IsImmutableConstant() && newSymbol.IsRealValueType()) { // Constants are multiplied/divided together if (divideNext) { constMultiplier /= GetSymbolValue(newSymbol); } else { constMultiplier *= GetSymbolValue(newSymbol); } constMultiplierUsed = true; } else { if (divideNext) { symbols.Append(new Symbol(SymbolType.OperatorDivide)); } newSymbol.Simplify(); symbols.Append(newSymbol); } if (i == end) { break; } divideNext = formula[i] == '/'; currentTermBegin = i + 1; } else if (formula[i] == '(') { currentDepth++; } else if (formula[i] == ')') { currentDepth--; } else if (formula[i] == '-' && currentDepth == 0 && !(i > begin && formula[i - 1] == '^')) { sign++; } } // If the generated monome has negative number of minus signs, then we append *-1 to end of the list, or if the preceding symbol is constant real number that is part of a monome, we multiply it. if (sign % 2 == 1) { constMultiplier = -constMultiplier; } if (constMultiplierUsed || sign % 2 == 1) { // Add the const multiplier to the expression if (symbols.Length > 0 && symbols.first.type == SymbolType.OperatorDivide) { // Put to the begin of the expression we are building symbols.symbols.Insert(0, new Symbol(constMultiplier)); } else if (symbols.Length > 0 && symbols.last.type == SymbolType.SubExpression && symbols.last.IsMonome()) { // Add inside the last subexpression SymbolList leftSideExpression = symbols.last.subExpression; if (leftSideExpression.last.type == SymbolType.RealValue && leftSideExpression.last.IsImmutableConstant()) { leftSideExpression.SetSymbolAtIndex(leftSideExpression.Length - 1, new Symbol(leftSideExpression.last.value * constMultiplier)); } else { leftSideExpression.Append(new Symbol(constMultiplier)); } } else { // Put to the end of the expression we are building symbols.Append(new Symbol(constMultiplier)); } } // Check if the final monome is just a real number, in which case we don't have to return a subexpression type if (symbols.Length == 1 && symbols.first.IsImmutableConstant() && symbols.first.IsRealValueType()) { return(symbols.first.type == SymbolType.RealValue ? symbols.first : new Symbol(GetSymbolValue(symbols.first))); } Symbol s = new Symbol(SymbolType.SubExpression); s.subExpression = symbols; s.Simplify(); return(s); }