/// <summary> /// Computes the Frobenius norm of the symmetric and non-symmetric parts of A, /// number of matching elements in symmetry and relative symmetry match. /// </summary> private void SymmetryInfo() { int n = S.ColumnCount; var ax = S.Values; var ap = S.RowPointers; var ai = S.ColumnIndices; var B = A.Transpose().Storage as SparseCompressedRowMatrixStorage <T>; var bx = B.Values; var bp = B.RowPointers; var bi = B.ColumnIndices; int i, j1, k1, k2, j2; int nnz, k1max, k2max; double st, fnorm; double fas = 0.0; double fan = 0.0; int imatch = 0; nnz = ap[n] - ap[0]; st = 0.0; for (i = 0; i < n; ++i) { k1 = ap[i]; k2 = bp[i]; k1max = ap[i + 1]; k2max = bp[i + 1]; while (k1 < k1max && k2 < k2max) { j1 = ai[k1]; j2 = bi[k2]; if (j1 == j2) { fas += math.Sum2(ax[k1], bx[k2]); fan += math.Difference2(ax[k1], bx[k2]); st += math.Square(ax[k1]); imatch++; } k1++; k2++; if (j1 < j2) { k2--; } if (j1 > j2) { k1--; } } } fas *= 0.25; fan *= 0.25; if (imatch == nnz) { st = 0.0; } else { fnorm = FrobeniusNorm(B); st = (fnorm * fnorm - st) * 0.5; if (st < 0.0) { st = 0.0; } } var info = this.StorageInfo; info.ElementsInSymmetry = imatch; info.FrobeniusNormSymPart = Math.Sqrt(fas + st); info.FrobeniusNormNonSymPart = fan < 0.0 ? 0.0 : Math.Sqrt(fan + st); }