public equation CombineAndReduce(equation othereq)
        {
            long topmultiplier = 0, bottommultiplier = 0;

            // This function considers "this" the top, and othereq the bottom.
            // It multiplies both equations by the first coefficient of the opposite equation,
            // and then subtracts the bottom from the top, eliminating the first coefficient from
            // the left side, and adding coefficients to the right.

            equation neweq = new equation();

            othereq.KillFactors();

            for (int i = 0; i < leftside.Count; i++)
            {
                coefficient topco    = leftside[i];
                coefficient bottomco = othereq.leftside[i];

                if (i == 0)
                {
                    topmultiplier    = bottomco.multiplier;
                    bottommultiplier = topco.multiplier;
                    // avoid saving a coefficient because the multiplier and subtraction guarantee they cancel
                }
                else
                {
                    neweq.leftside.Add(new coefficient(topco.multiplier * topmultiplier - bottomco.multiplier * bottommultiplier, topco.vindex));
                }
            }

            for (int i = 0; i < 8; i++)
            {
                long multiplier = 0;
                foreach (coefficient r in rightside)
                {
                    if (r.vindex == i)
                    {
                        multiplier += (r.multiplier * topmultiplier);
                    }
                }

                foreach (coefficient r in othereq.rightside)
                {
                    if (r.vindex == i)
                    {
                        multiplier -= (r.multiplier * bottommultiplier);
                    }
                }

                if (multiplier != 0)
                {
                    neweq.rightside.Add(new coefficient(multiplier, i));
                }
            }

            neweq.KillFactors();
            return(neweq);
        }
 public void SolveLeft(BigInteger[] v)
 {
     for (int i = 0; i < 8; i++)
     {
         if (v[i] != null && v[i].Equals(BigInteger.Zero) == false)
         {
             // find anything on the left that uses this value and eliminate it.
             for (int j = 0; j < leftside.Count; j++)
             {
                 coefficient c = leftside[j];
                 if (c.vindex == i)
                 {
                     // found something - eliminate it
                     BigInteger accum = v[i];
                     accum = accum.Multiply(new BigInteger(c.multiplier.ToString()));
                     // now subtract the whole thing from both sides
                     subtractor = subtractor.Add(accum);
                     leftside.RemoveAt(j);
                     j--;
                 }
             }
         }
     }
 }