public static RadicalSum Add(RadicalSum left, RadicalSum right) { var z = new Radical[left.Radicals.Length + right.Radicals.Length]; left.Radicals.CopyTo(z, 0); right.Radicals.CopyTo(z, left.Radicals.Length); return(new RadicalSum(z)); }
public static RadicalSum Negate(RadicalSum value) { Radical[] radicals = new Radical[value.Radicals.Length]; for (int i = 0; i < value.Radicals.Length; i++) { radicals[i] = -value.Radicals[i]; } var result = new RadicalSum(radicals); return(result); }
public static RadicalSum Multiply(RadicalSum left, RadicalSum right) { var z = new Radical[left.Radicals.Length * right.Radicals.Length]; for (int i = 0; i < left.Radicals.Length; i++) { for (int j = 0; j < right.Radicals.Length; j++) { z[(i * right.Radicals.Length) + j] = left.Radicals[i] * right.Radicals[j]; } } return(new RadicalSum(z)); }
public static RadicalSum Divide(RadicalSum left, Radical right) { if (right == 0) { throw new DivideByZeroException("Cannot divide by zero"); } var z = new Radical[left.Radicals.Length]; for (int i = 0; i < left.Radicals.Length; i++) { z[i] = left.Radicals[i] / right; } return(new RadicalSum(z)); }
public static Radical[] SimplifyRadicals(Radical[] radicals) { if (radicals == null) { return(null); } if (radicals.Length == 0) { return(new Radical[0]); } if (radicals.Length == 1) { return(radicals); } var uniqueRadicals = new Dictionary <Tuple <BigInteger, int>, Radical>(); for (int i = 0; i < radicals.Length; i++) { Radical b = radicals[i]; var key = new Tuple <BigInteger, int>(b.Radicand, b.Index); if (uniqueRadicals.ContainsKey(key)) { uniqueRadicals[key] = Radical.AddCompatible(uniqueRadicals[key], b); } else if (!b.IsZero) { uniqueRadicals[key] = b; } } Radical[] result = uniqueRadicals.Values .Where(f => !f.IsZero) .OrderBy(f => f.Index) .ThenBy(f => f.Radicand) .ToArray(); if (result.Length == 0) { result = new Radical[1] { Radical.Zero } } ; return(result); }
public RadicalSumRatio(Radical radical) : this(new RadicalSum(radical), RadicalSum.One) { }
/// <summary> /// Returns multiplicative inverse, i.e., B such that this * B = 1 /// </summary> /// <returns></returns> public static RadicalSum GetRationalizer(RadicalSum value) { // Method derived from: // Rationalizing Denominators // Allan Berele and Stefan Catoiu // https://www.jstor.org/stable/10.4169/mathmaga.88.issue-2 // See Example 9 if (value == 0) { throw new Exception("Cannot get rationalization of zero"); } // Solve for the largest field extensions in turn // S = r_1 + r_2 + ... + r_n // r_n = S - r_1 - r_2 - ... - r_(n-1) // r_n^2 = [S - r_1 - r_2 - ... - r_(n-1)]^2 // Create polynomial in S // S - r_1 - r_2 - ... - r_n = 0 var term1 = new Polynomials.PolynomialTerm(1, 1); var term0 = new Polynomials.PolynomialTerm(-value, 0); var p = new Polynomials.Polynomial(new Polynomials.PolynomialTerm[2] { term0, term1 }); // Get the set of unique indexes and radicands for each index var uniquePrimeNthRoots = p.GetUniquePrimeNthRoots(); // Main loop for (int i = uniquePrimeNthRoots.Length - 1; i >= 0; i--) { var currentPrimeNthRoot = uniquePrimeNthRoots[i]; if (currentPrimeNthRoot.Item1 < 2) // Index { continue; } if (currentPrimeNthRoot.Item2 < 2) // Radicand { continue; } // Solve for largest radicand // p = p_reduced + p_extract = 0 // p_extract = root[currentIndex](currentRadicand) * p' for some p' Polynomials.Polynomial p_reduced; Polynomials.Polynomial p_extract; p.ExtractTermsContainingNthRoot( radicand: currentPrimeNthRoot.Item2, index: currentPrimeNthRoot.Item1, p_reduced: out p_reduced, p_extract: out p_extract); // Remove root[currentIndex](currentRadicand) to keep p' === p_extract_coefficient var r = new Radical(1, currentPrimeNthRoot.Item2, currentPrimeNthRoot.Item1); var p_extract_coefficient = p_extract /= r; // p_reduced = -p_extract // p_reduced^currentIndex = (-p_extract)^currentIndex // p_reduced^currentIndex = (-p_extract_coefficient)^currentIndex * currentRadicand // p => p_reduced^currentIndex - currentRadicand * (-p_extract_coefficient)^currentIndex = 0 var left = Polynomials.Polynomial.Pow(p_reduced, currentPrimeNthRoot.Item1); var right = Polynomials.Polynomial.Pow(-p_extract, currentPrimeNthRoot.Item1) * currentPrimeNthRoot.Item2; p = left - right; } // We now have a polynomial in S with all radicals removed: // a_0 + a_1 * S + a_2 * S^2 + ... + a_n * S^n = 0 // Radicalizer then becomes: // -a_0 / S = a_1 + a_2 * S + ... + a_n * S^(n-1) // // 1 a_1 + a_2 * S + ... + a_n * S^(n-1) // - = ----------------------------------- // S -a_0 var constantTerm = p.GetConstantTerm(); var constantP = new Polynomials.Polynomial(constantTerm); p -= constantP; if (!p.IsDivisibleByX) { throw new Exception("All terms should have at least degree 1"); } if (!constantTerm.IsRational) { throw new Exception("No radicals should remain in any terms"); } p = Polynomials.Polynomial.DivideByX(p); p /= (Rational)(-constantTerm); var rationalizer = p.EvaluateAt(value); return(rationalizer); }
public RadicalSum(Radical radical) { _radicals = new Radical[1] { radical }; }