static IEnumerable <Tuple <int, int, T> > ExpandSparse <T>(MatrixMarketSymmetry symmetry, IEnumerable <Tuple <int, int, T> > indexedValues) { var map = CreateSymmetryMap <T>(symmetry); foreach (var x in indexedValues) { yield return(x); if (x.Item1 != x.Item2) { yield return(new Tuple <int, int, T>(x.Item2, x.Item1, map(x.Item3))); } } }
static Func <T, T> CreateSymmetryMap <T>(MatrixMarketSymmetry symmetry) { if (symmetry != MatrixMarketSymmetry.Hermitian) { return(x => x); } if (typeof(T) == typeof(double)) { return(x => x); } if (typeof(T) == typeof(Complex)) { return(x => (T)(object)Complex.Conjugate((Complex)(object)x)); } throw new NotSupportedException(); }
static void ExpandStorage <T>(MatrixMarketSymmetry symmetry, CoordinateStorage <T> storage) where T : struct, IEquatable <T>, IFormattable { var map = CreateSymmetryMap <T>(symmetry); var ai = storage.RowIndices; var aj = storage.ColumnIndices; var ax = storage.Values; int i, j, n = storage.NonZerosCount; for (int k = 0; k < n; k++) { i = ai[k]; j = aj[k]; if (i > j) { storage.At(j, i, map(ax[k])); } } }
static void ExpectHeader(TextReader reader, bool matrix, out bool complex, out bool sparse, out MatrixMarketSymmetry symmetry) { string line; while ((line = reader.ReadLine()) != null) { line = line.Trim(); if (line.StartsWith("%%MatrixMarket")) { var tokens = line.ToLowerInvariant().Substring(15).Split(Separators, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length < 2) { throw new FormatException(@"Expected MatrixMarket Header with 2-4 attributes: object format [field] [symmetry]; see http://math.nist.gov/MatrixMarket/ for details."); } if (tokens[0] != (matrix ? "matrix" : "vector")) { throw new FormatException("Expected matrix content."); } switch (tokens[1]) { case "array": sparse = false; break; case "coordinate": sparse = true; break; default: throw new NotSupportedException("Format type not supported."); } if (tokens.Length < 3) { complex = false; } else { switch (tokens[2]) { case "real": case "double": case "integer": complex = false; break; case "complex": complex = true; break; default: throw new NotSupportedException("Field type not supported."); } } if (tokens.Length < 4) { symmetry = MatrixMarketSymmetry.General; } else { switch (tokens[3]) { case "general": symmetry = MatrixMarketSymmetry.General; break; case "symmetric": symmetry = MatrixMarketSymmetry.Symmetric; break; case "skew-symmetric": symmetry = MatrixMarketSymmetry.SkewSymmetric; break; case "hermitian": symmetry = MatrixMarketSymmetry.Hermitian; break; default: throw new NotSupportedException("Symmetry type not supported"); } } return; } } throw new FormatException(@"Expected MatrixMarket Header, see http://math.nist.gov/MatrixMarket/ for details."); }