예제 #1
0
        /// <summary>
        /// Distributes the sign from power.
        /// </summary>
        /// <returns>IBase.</returns>
        public override IBase DistributeSignFromPower()
        {
            if (IsEmpty())
            {
                return(new SumDifferenceSet());
            }
            SumDifferenceSet newSet = CloneSet();

            //for (int i = 0; i < _units.Count; i++)
            //{
            //    if (_operators[i] == Query.EMPTY.ToString())
            //    {
            //        newSet._units[i].FlipSign();
            //    }
            //    else if (_operators[i] == Query.ADD.ToString())
            //    {
            //        newSet._operators[i] = Query.SUBTRACT.ToString();
            //    }
            //    else if (_operators[i] == Query.SUBTRACT.ToString())
            //    {
            //        newSet._operators[i] = Query.ADD.ToString();
            //    }
            //}

            return(newSet);
        }
예제 #2
0
        protected SumDifferenceSet combinePowers(SumDifferenceSet newSet)
        {
            for (int i = 0; i < newSet.Count - 1; i++)
            {
                bool  baseAIsNegative = newSet._unitOperatorPair[i].Unit.GetSign().IsNegative();
                IBase baseA           = newSet._unitOperatorPair[i].Unit.GetBase();
                IBase powerA          = newSet._unitOperatorPair[i].Unit.GetPower() ?? new PrimitiveUnit(1);
                IBase baseB           = newSet._unitOperatorPair[i + 1].Unit.GetBase();
                IBase powerB          = newSet._unitOperatorPair[i + 1].Unit.GetPower() ?? new PrimitiveUnit(1);
                bool  baseSignIsSame  = newSet._unitOperatorPair[i].Unit.GetSign().Equals(newSet._unitOperatorPair[i + 1].Unit.GetSign());

                bool isSum           = (newSet._unitOperatorPair[i + 1].OperatorEquals(Query.ADD));
                bool baseIsSame      = baseA.GetBase().Equals(baseB.GetBase());
                bool exponentIsSame  = powerA.GetBase().Equals(powerB.GetBase());
                bool powerSignIsSame = powerA.GetSign().Equals(powerB.GetSign());

                // (1a) Same Base, Same exponent, Same exponent sign
                if (baseIsSame && exponentIsSame && powerSignIsSame)
                {
                    if ((isSum && baseSignIsSame) ||
                        (!isSum && !baseSignIsSame))
                    { // Add Exponent Same Sign
                        ProductQuotientSet newBasePower = new ProductQuotientSet(2);
                        newBasePower.MultiplyItem(new ProductQuotientSet(baseA, powerA));
                        newSet = new SumDifferenceSet(newBasePower, null, baseAIsNegative);
                    }
                    else
                    { // Subtract Exponent Same Sign
                        newSet = new SumDifferenceSet(0);
                    }
                }

                // (1b) Same Base, Same exponent, Different sign
                // (2) Same Base, Different exponent (ignore sign)
                // (3) Different Base, Same exponent (ignore sign)
                // (4) Different Base, Different exponent (ignore sign)
                if (!baseIsSame && !exponentIsSame)
                {
                    // Do Nothing
                }
            }

            // Calculate if numeric
            IBase power = newSet.GetPower();

            if (power == null || !power.IsNumber())
            {
                return(newSet);
            }

            power  = new PrimitiveUnit(power.Calculate());
            newSet = new SumDifferenceSet(
                new ProductQuotientSet(newSet.GetBase(), power, newSet.SignIsNegative())
                );

            return(newSet);
        }
예제 #3
0
        private static IBase parseAsSumDifference(string value)
        {
            string           newValue         = string.Empty;
            char             lastOperand      = Query.EMPTY;
            SumDifferenceSet sumDifferenceSet = null;

            aggregateAndCombineItems(value, ref sumDifferenceSet, ref lastOperand, ref newValue);

            return(finalizeSumDifferenceSet(sumDifferenceSet, newValue, lastOperand));
        }
예제 #4
0
        /// <summary>
        /// Extracts the sign.
        /// </summary>
        /// <param name="isRecursive">if set to <c>true</c> [is recursive].</param>
        /// <returns>IBase.</returns>
        public override IBase ExtractSign(bool isRecursive = false)
        {
            if (IsEmpty())
            {
                return(new SumDifferenceSet());
            }
            SumDifferenceSet newSet = CloneSet();

            return(extractSign(newSet, isRecursive));
        }
예제 #5
0
        protected override ProductQuotientSet simplifyFractional <T>(T newSetGeneric)
        {
            if (!(newSetGeneric is SumDifferenceSet))
            {
                return(new ProductQuotientSet(newSetGeneric));
            }
            SumDifferenceSet newSet = newSetGeneric as SumDifferenceSet;

            if (newSet.Count < 2)
            {
                return(new ProductQuotientSet(newSet));
            }

            ProductQuotientSet leftSet = fractionSet(newSet, 0);

            for (int i = 1; i < newSet.Count; i++)
            {
                ProductQuotientSet rightSet = fractionSet(newSet, i);
                IBase unitA = unitSet(leftSet, 0);
                IBase unitB = unitSet(leftSet, 1);
                IBase unitC = unitSet(rightSet, 0);
                IBase unitD = unitSet(rightSet, 1);

                ProductQuotientSet numeratorSetLeft = new ProductQuotientSet(unitA);
                numeratorSetLeft.MultiplyItem(unitD);
                numeratorSetLeft = simplifyNumeric <ProductQuotientSet>(numeratorSetLeft);
                ProductQuotientSet numeratorSetRight = new ProductQuotientSet(unitC);
                numeratorSetRight.MultiplyItem(unitB);
                numeratorSetRight = simplifyNumeric <ProductQuotientSet>(numeratorSetRight);

                ProductQuotientSet denominatorSet = new ProductQuotientSet(unitB);
                denominatorSet.MultiplyItem(unitD);
                denominatorSet = simplifyNumeric <ProductQuotientSet>(denominatorSet);

                SumDifferenceSet numeratorSet = new SumDifferenceSet(numeratorSetLeft);
                if (newSet._unitOperatorPair[i].OperatorEquals(Query.ADD))
                {
                    numeratorSet.SumItem(numeratorSetRight);
                }
                else if (newSet._unitOperatorPair[i].OperatorEquals(Query.SUBTRACT))
                {
                    numeratorSet.SubtractItem(numeratorSetRight);
                }
                numeratorSet = simplifyNumeric <SumDifferenceSet>(numeratorSet);

                leftSet = new ProductQuotientSet(numeratorSet);
                leftSet.DivideItem(denominatorSet);
            }

            string             simplifiedFraction = Query.SimplifiedFraction(leftSet.Label());
            ProductQuotientSet set = new ProductQuotientSet(simplifiedFraction);

            return((ProductQuotientSet)set.SimplifyUnitsOfOne());
        }
예제 #6
0
        /// <summary>
        /// Extracts the sign from power.
        /// </summary>
        /// <returns>IBase.</returns>
        public override IBase ExtractSignFromPower()
        {
            if (IsEmpty())
            {
                return(new SumDifferenceSet());
            }
            SumDifferenceSet newSet = CloneSet();
            IBase            power  = newSet.GetPower()?.ExtractSign();

            newSet.addPower(power);
            return(newSet);
        }
예제 #7
0
        private static SumDifferenceSet finalizeSumDifferenceSet(SumDifferenceSet sumDifferenceSet,
                                                                 string newValue,
                                                                 char lastOperand)
        {
            IBase newValuePrimitive = parseToObject(newValue);

            if (sumDifferenceSet == null)
            {
                return(new SumDifferenceSet(newValuePrimitive));
            }
            sumDifferenceSet.AppendItemToGroup(lastOperand, newValuePrimitive);

            return(sumDifferenceSet);
        }
예제 #8
0
        /// <summary>
        /// Subtracts the symbolic.
        /// </summary>
        /// <param name="value1">The value1.</param>
        /// <param name="value2">The value2.</param>
        /// <returns>SumDifferenceSet.</returns>
        protected static SumDifferenceSet subtractSymbolic(IBase value1, IBase value2)
        {
            SumDifferenceSet set;

            if (value1 is SumDifferenceSet differenceSet)
            {
                set = differenceSet.CloneSet();
            }
            else
            {
                set = new SumDifferenceSet(value1);
            }
            set.SubtractItem(value2);
            return(set);
        }
예제 #9
0
        /// <summary>
        /// Inverts all operators (flips all + &amp; - operators).
        /// </summary>
        /// <param name="newSet">The new set.</param>
        /// <returns>MPT.SymbolicMath.SumDifferenceSet.</returns>
        protected SumDifferenceSet invertOperators(SumDifferenceSet newSet)
        {
            for (int i = 0; i < newSet.Count; i++)
            {
                if (newSet._unitOperatorPair[i].OperatorEquals(Query.ADD))
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateOperator(Query.SUBTRACT);
                }
                else if (newSet._unitOperatorPair[i].OperatorEquals(Query.SUBTRACT))
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateOperator(Query.ADD);
                }
            }

            return(newSet);
        }
예제 #10
0
        /// <summary>
        /// Simplifies the specified is recursive.
        /// </summary>
        /// <param name="isRecursive">if set to <c>true</c> [is recursive].</param>
        /// <returns>IBase.</returns>
        public override IBase Simplify(bool isRecursive = false)
        {
            if (IsEmpty())
            {
                return(new SumDifferenceSet());
            }
            SumDifferenceSet newSet = CloneSet();

            // Simplify base & power items
            if (isRecursive)
            {
                for (int i = 0; i < newSet.Count; i++)
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateUnit(newSet._unitOperatorPair[i].Unit.Simplify(isRecursive: true));
                }
            }

            // Simplified Group
            // TODO: Simplified Group
            //newSet = SimplifyOperandGroups(isRecursive);

            // Sort Numeric vs. Variable
            // TODO: Sort Numeric vs. Variable
            //newSet = SortNumericBeforeVariables(isRecursive);

            // Combine powers
            newSet = combinePowers(newSet);

            // Simplify Signs
            newSet = extractSign(newSet, isRecursive);
            newSet = (SumDifferenceSet)newSet.ExtractSignFromPower();

            // Simplified Fractional
            //newSet = new SumDifferenceSet(simplifyFractional(newSet));

            // Combine Numeric
            // TODO: Combine Numeric
            //newSet = CombineNumeric(isRecursive);

            // Combine Variables
            // TODO: Simplified Variables
            //newSet = CombineVariables(isRecursive);

            return(newSet);
        }
예제 #11
0
        public override object Clone()
        {
            IBase            unit   = Count > 0 ? _unitOperatorPair[0].Unit : null;
            SumDifferenceSet newSet = new SumDifferenceSet(unit, _power, SignIsNegative());

            for (int i = 1; i < Count; i++)
            {
                if (_unitOperatorPair[i].OperatorEquals(Query.ADD))
                {
                    newSet.SumItem(_unitOperatorPair[i].Unit);
                }
                if (_unitOperatorPair[i].OperatorEquals(Query.SUBTRACT))
                {
                    newSet.SubtractItem(_unitOperatorPair[i].Unit);
                }
            }

            return(newSet);
        }
예제 #12
0
        private static void aggregateAndCombineItems(
            string value,
            ref SumDifferenceSet sumDifferenceSet,
            ref char lastOperand,
            ref string newValue)
        {
            int continueIndex = -1;

            for (int i = 0; i < value.Length; i++)
            {
                if (i < continueIndex)
                {
                    continue;
                }
                IBase newValuePrimitive;
                if (isGroupByProductQuotient(value, i, lastOperand))
                {   // newValuePrimitive needs to be formulated from all values leading up to next SumDifference
                    newValuePrimitive = newValueFromProductQuotientGroup(value, i, out continueIndex, newValue);
                }
                else if (addNewSumDifference(newValue, value, i))
                {
                    newValuePrimitive = parseToObject(newValue);
                }
                else if (isGroupByBrackets(value, i))
                {
                    newValuePrimitive = newValueFromBracketGroup(value, i, out continueIndex, newValue);
                }
                else
                {
                    newValuePrimitive = null;
                }

                sumDifferenceSet = (SumDifferenceSet)updateSet <SumDifferenceSet>(
                    value, i,
                    ref newValue,
                    ref lastOperand,
                    sumDifferenceSet,
                    newValuePrimitive);
            }
        }
예제 #13
0
        /// <summary>
        /// Distributes the sign.
        /// </summary>
        /// <returns>IBase.</returns>
        public override IBase DistributeSign()
        {
            SumDifferenceSet newSet = CloneSet();

            for (int i = 0; i < Count; i++)
            {
                if (_unitOperatorPair[i].OperatorEquals(Query.EMPTY))
                {
                    newSet._unitOperatorPair[i].Unit.FlipSign();
                }
                else if (_unitOperatorPair[i].OperatorEquals(Query.ADD))
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateOperator(Query.SUBTRACT);
                }
                else if (_unitOperatorPair[i].OperatorEquals(Query.SUBTRACT))
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateOperator(Query.ADD);
                }
            }

            return(newSet);
        }
예제 #14
0
        /// <summary>
        /// Simplifies the variables.
        /// </summary>
        /// <param name="isRecursive">if set to <c>true</c> [is recursive].</param>
        /// <returns>IBaseSet.</returns>
        /// <exception cref="NotImplementedException"></exception>
        public override IBaseSet SimplifyVariables(bool isRecursive = false)
        {
            Dictionary <string, int> variables = ExtractVariableAndValue();

            SumDifferenceSet newSet = null;

            foreach (var variableSet in variables)
            {
                if (variables.Count == 1 && variableSet.Value == 0)
                {
                    return(new ProductQuotientSet(0));
                }
                if (variableSet.Value == 0)
                {
                    continue;
                }

                bool variableIsPositive            = variableSet.Value > 0;
                ProductQuotientSet currentVariable = gatherVariables(variableSet.Key, variableSet.Value);

                if (newSet == null)
                {
                    newSet = new SumDifferenceSet(currentVariable);
                }
                else if (variableIsPositive)
                {
                    newSet.SumItem(currentVariable);
                }
                else
                {
                    currentVariable.FlipSign();
                    newSet.SubtractItem(currentVariable);
                }
            }

            return(newSet == null?CloneSet() : newSet.SimplifyUnitsOfOne());

            throw new NotImplementedException();
        }
예제 #15
0
        protected SumDifferenceSet extractSign(SumDifferenceSet newSet, bool isRecursive = false)
        {
            bool firstValueWasNegative = newSet._unitOperatorPair[0].Unit.SignIsNegative();

            if (isRecursive)
            {
                for (int i = 0; i < newSet.Count; i++)
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateUnit(newSet._unitOperatorPair[i].Unit.ExtractSign(isRecursive: true));
                }
            }

            newSet = factorOutNegativeSigns(newSet);

            if (!firstValueWasNegative)
            {
                return(newSet);
            }

            newSet.FlipSign();
            newSet = invertOperators(newSet);
            return(newSet);
        }
예제 #16
0
        protected IBase getBase(bool getAbsolute = false)
        {
            if (Count == 0)
            {
                return(new SumDifferenceSet());
            }
            IBase            unitBase = getUnit(0, getAbsolute);
            SumDifferenceSet newSet   = new SumDifferenceSet(unitBase);

            for (int i = 1; i < Count; i++)
            {
                if (_unitOperatorPair[i].OperatorEquals(Query.ADD))
                {
                    newSet.SumItem(_unitOperatorPair[i].Unit);
                }
                if (_unitOperatorPair[i].OperatorEquals(Query.SUBTRACT))
                {
                    newSet.SubtractItem(_unitOperatorPair[i].Unit);
                }
            }

            return(newSet);
        }
예제 #17
0
        /// <summary>
        /// Factors the out negative signs (all +- and -- cases).
        /// </summary>
        /// <param name="newSet">The new set.</param>
        /// <returns>MPT.SymbolicMath.SumDifferenceSet.</returns>
        protected SumDifferenceSet factorOutNegativeSigns(SumDifferenceSet newSet)
        {
            for (int i = 0; i < newSet.Count; i++)
            {
                if (!newSet._unitOperatorPair[i].Unit.SignIsNegative())
                {
                    continue;
                }

                // Flip sign of unit and flip operator
                newSet._unitOperatorPair[i].Unit.FlipSign();
                if (newSet._unitOperatorPair[i].OperatorEquals(Query.ADD))
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateOperator(Query.SUBTRACT);
                }
                else if (newSet._unitOperatorPair[i].OperatorEquals(Query.SUBTRACT))
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateOperator(Query.ADD);
                }
            }

            return(newSet);
        }
예제 #18
0
        /// <summary>
        /// Simplifies the units of one.
        /// </summary>
        /// <param name="isRecursive">if set to <c>true</c> [is recursive].</param>
        /// <returns>IBaseSet.</returns>
        public override IBaseSet SimplifyUnitsOfOne(bool isRecursive = true)
        {
            if (IsEmpty())
            {
                return(new SumDifferenceSet());
            }
            SumDifferenceSet newSet = CloneSet();

            if (!isRecursive)
            {
                return(newSet);
            }

            // Simplify
            for (int i = 0; i < newSet.Count; i++)
            {
                if (_unitOperatorPair[i].Unit is IBaseSet unitSet)
                {
                    newSet._unitOperatorPair[i] = newSet._unitOperatorPair[i].UpdateUnit(unitSet.SimplifyUnitsOfOne(isRecursive: true));
                }
            }

            return(newSet);
        }