//!!! standard basis added here public Matrix(Rational[] basis, int vectorLength = -1, int vectorCount = -1, bool makeDiagonal = false) { // if (basis == null) { throw new ArgumentException(); } if (vectorCount == -1) { vectorCount = basis.Length; // other vectors may be invalid } if (vectorLength == -1) { vectorLength = GetMaxLength(basis, vectorCount); } // basisSize = vectorCount; width = basisSize + vectorLength; // we add standard basis here height = vectorLength; // m = new int[width, height]; for (int j = 0; j < basisSize; ++j) { //!!! fail: C# can't copy memory from 1d to 2d - we might use 1d array for matrix! int[] pows = basis[j].GetPrimePowers(); //Array.Copy(basis[i], 0, m, i * height, vectorLength); for (int i = 0; i < vectorLength; ++i) { m[j, i] = Powers.SafeAt(pows, i); } } // add standard basis for (int j = 0; j < vectorLength; ++j) { m[basisSize + j, j] = 1; } Init(); if (makeDiagonal) { MakeEchelon(); ReduceRows(); } }
/* * public static int[] FindCoordinates(Rational[] basis, Rational vector, int vectorLength) * { * int basisSize = basis.Length; * * // get prime powers * int[][] b = new int[basisSize][]; * for (int i = 0; i < basisSize; ++i) { * b[i] = basis[i].GetPrimePowers(); * } * int[] v = vector.GetPrimePowers(); * * // * int[] coordinates = FindCoordinates(b, v, vectorLength); * #if DEBUG * // check result * if (coordinates != null) { * Rational r = Rational.One; * for (int i = 0; i < coordinates.Length; ++i) { * r *= basis[i].Pow(coordinates[i]); * } * if (!r.Equals(vector)) throw new Exception( * String.Format("FindCoordinates failed: {0} != {1}", r, vector) * ); * } #endif * * return coordinates; * } */ #region Tests #if DEBUG private static void CheckVector(Rational[] basis, Rational vector, int vectorLength, bool addStandard = false) { // add standard basis int basisSize = basis.Length; if (addStandard) { Array.Resize(ref basis, basisSize + vectorLength); for (int i = 0; i < vectorLength; ++i) { basis[basisSize + i] = Rational.Prime(i); } } // for (int i = 0; i < basis.Length; ++i) { Debug.WriteLine(String.Format("Basis {0}. {1,-15} {2}", i, basis[i].FormatFraction(), basis[i].FormatMonzo())); } Debug.WriteLine(String.Format("Vector {0,-15} {1}", vector.FormatFraction(), vector.FormatMonzo())); // int[] coords = FindCoordinates(basis, vector, vectorLength); if (coords == null) { Debug.WriteLine("Invalid Basis or Out of basis subspace"); } else { Debug.WriteLine("Coordinates: " + Powers.ToString(coords, "()")); // Debug.WriteLine(vector.FormatFraction() + " = "); for (int i = 0; i < basisSize; ++i) { int e = Powers.SafeAt(coords, i); Debug.Print(" * ({0})^{1}", basis[i].FormatFraction(), e); } if (addStandard) { Rational r = new Rational(coords.Skip(basisSize).ToArray()); Debug.Print(" * {0} {1} {2}", r.FormatFraction(), r.FormatMonzo(), r.FormatNarrowPowers()); } } }
public int[] leadCols; // column -> row // public Matrix(int[][] basis, int[] vector, int vectorLength) { basisSize = basis.Length; width = basisSize + 1; height = vectorLength; // m = new int[width, height]; for (int j = 0; j < basisSize; ++j) { //!!! fail: C# can't copy memory from 1d to 2d - we might use 1d array for matrix! //Array.Copy(basis[i], 0, m, i * height, vectorLength); for (int i = 0; i < vectorLength; ++i) { m[j, i] = Powers.SafeAt(basis[j], i); } } //Array.Copy(vector, 0, m, basisSize * height, vectorLength); for (int i = 0; i < vectorLength; ++i) { m[basisSize, i] = Powers.SafeAt(vector, i); } Init(); }