public Normalizer(int[] height) { var m = height.Max(); FactoredDifference = new FactoredRational[m + 1, m + 1]; for (int i = 0; i <= m; i++) { for (int j = 0; j <= m; j++) { FactoredDifference[i, j] = new FactoredRational(i - j); } } InsideProduct = new FactoredRational[height.Length, m + 1]; for (int i = 0; i < height.Length; i++) { for (int j = 0; j <= height[i]; j++) { InsideProduct[i, j] = new FactoredRational() { K = new List <int>(), Sign = 1 }; for (int k = 0; k <= height[i]; k++) { if (k == j) { continue; } InsideProduct[i, j] *= FactoredDifference[j, k]; } } } }
public FactoredRational Get(int[] a) { var normalizer = new FactoredRational() { K = new List <int>(), Sign = 1 }; for (int i = 0; i < a.Length; i++) { normalizer *= InsideProduct[i, a[i]]; } return(normalizer); }
public int GetCoefficient(int[] power) { _normalizer = new Normalizer(power); var a = new int[power.Length]; long top = 0L; long bottom = 1L; var partialProduct = new FactoredRational() { K = new List <int>(), Sign = 1 }; SumTerms(0, a, power, ref partialProduct, ref top, ref bottom); return((int)(top / bottom)); }
void SumTerms(int w, int[] a, int[] power, ref FactoredRational partialProduct, ref long top, ref long bottom) { if (w == power.Length) { var r = partialProduct / _normalizer.Get(a); int top2; int bottom2; r.ToRational(out top2, out bottom2); top = top * bottom2 + bottom * top2; bottom = bottom * bottom2; var gcd = GCD(top, bottom); top /= gcd; bottom /= gcd; } else { for (int j = 0; j <= power[w]; j++) { a[w] = j; var current = new FactoredRational() { K = new List <int>(), Sign = 1 }; foreach (var v in _priorNeighbors[w]) { current *= _normalizer.FactoredDifference[a[v], a[w]]; } if (current.Sign == 0) { continue; } partialProduct *= current; SumTerms(w + 1, a, power, ref partialProduct, ref top, ref bottom); partialProduct /= current; } } }