void AddNodeToList(PolynomialNode node, List <PolynomialNode> L)
 {
     for (int i = 0; i < L.Count; i++)
     {
         if (node.Matches(L[i]))
         {
             L[i].Add(node);
             return;
         }
     }
     L.Add(node);
 }
 public bool Matches(PolynomialNode N)
 {
     if (N.Variables.Count != Variables.Count)
     {
         return(false);
     }
     for (int i = 0; i < N.Variables.Count; i++)
     {
         if (!N.Variables.ElementAt(i).Equals(Variables.ElementAt(i)))
         {
             return(false);
         }
     }
     return(true);
 }
        List <PolynomialNode> AddFromTree(Node N)
        {
            switch (N.Type)
            {
            case NodeType.Number:
                return(new List <PolynomialNode>()
                {
                    new PolynomialNode(new Complex(N.Num, 0))
                });

            case NodeType.Variable:
                if (N.Var == 'i')
                {
                    return(new List <PolynomialNode>()
                    {
                        new PolynomialNode(new Complex(0, 1))
                    });
                }
                else
                {
                    int index = Variables.IndexOf(N.Var);
                    if (index == -1)
                    {
                        index = Variables.Count;
                        Variables.Add(N.Var);
                    }
                    return(new List <PolynomialNode>()
                    {
                        new PolynomialNode(new Complex(1, 0), index, 1)
                    });
                }

            case NodeType.Operation:
            {
                List <PolynomialNode> L1 = AddFromTree(N.N1);
                List <PolynomialNode> L2 = AddFromTree(N.N2);
                List <PolynomialNode> L3 = new List <PolynomialNode>();
                if (N.OpType == Operator.Multiply)
                {
                    for (int i = 0; i < L1.Count; i++)
                    {
                        for (int j = 0; j < L2.Count; j++)
                        {
                            var node = new PolynomialNode(L1[i].Scalar * L2[j].Scalar);
                            node.Variables = CopyDictionary(L1[i].Variables);
                            MergeDictionaries(node.Variables, L2[j].Variables, L3);
                            AddNodeToList(node, L3);
                        }
                    }
                }
                else if (N.OpType == Operator.Power)
                {
                    if (N.N2.Type == NodeType.Number && N.N2.Num >= 1)
                    {
                        int   num = (int)N.N2.Num;
                        int[] arr = new int[L1.Count];
                        //loop through all combinations of positive array contents that add up to num
                        while (Increment(arr, num))
                        {
                            //gets multinomial coefficients
                            int     IntCoefficient        = Factorial(num);
                            Complex ComplexCoefficient    = new Complex(1, 0);
                            SortedDictionary <int, int> D = new SortedDictionary <int, int>();
                            for (int i = 0; i < arr.Length; i++)
                            {
                                IntCoefficient /= Factorial(arr[i]);
                                for (int j = 0; j < arr[i]; j++)
                                {
                                    ComplexCoefficient *= L1[i].Scalar;
                                }
                                if (arr[i] > 0)
                                {
                                    MergeDictionaries(D, L1[i].Variables, L3, arr[i]);
                                }
                            }

                            AddNodeToList(new PolynomialNode(IntCoefficient * ComplexCoefficient, D), L3);
                        }
                    }
                    else
                    {
                        //shit
                    }
                }
                else
                {
                    double M = 1;
                    if (N.OpType == Operator.Subtract)
                    {
                        M = -1;
                    }
                    for (int i = 0; i < L1.Count; i++)
                    {
                        L3.Add(L1[i]);
                    }
                    for (int i = 0; i < L2.Count; i++)
                    {
                        AddNodeToList(new PolynomialNode(L2[i].Scalar * new Complex(M, 0), L2[i].Variables), L3);
                    }
                }
                return(L3);
            }

            default:
                return(new List <PolynomialNode>());
            }
        }
 public void Add(PolynomialNode N)
 {
     Scalar += N.Scalar;
 }