static HessMatrix GetMulImpl(HessMatrix left, HessMatrix right, ILinAlg ila, bool warning) { if (HDebug.Selftest()) { Matrix h1 = new double[, ] { { 0, 1, 2, 3, 4, 5 } , { 1, 2, 3, 4, 5, 6 } , { 2, 3, 4, 5, 6, 7 } , { 3, 4, 5, 6, 7, 8 } , { 4, 5, 6, 7, 8, 9 } , { 5, 6, 7, 8, 9, 0 } }; HessMatrix h2 = HessMatrixSparse.FromMatrix(h1); Matrix h11 = Matrix.GetMul(h1, h1); HessMatrix h22 = HessMatrix.GetMulImpl(h2, h2, null, false); Matrix hdiff = h11 - h22; HDebug.AssertToleranceMatrix(0, hdiff); } if ((left is HessMatrixDense) && (right is HessMatrixDense)) { if (ila != null) { return(new HessMatrixDense { hess = ila.Mul(left, right) }); } if (warning) { HDebug.ToDo("Check (HessMatrixDense * HessMatrixDense) !!!"); } } Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > left_ic_rows = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >(); foreach (var ic_row in left.EnumRowBlocksAll()) { left_ic_rows.Add(ic_row.Item1, ic_row.Item2.HToDictionaryWithKeyItem2()); } Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > > right_ir_cols = new Dictionary <int, Dictionary <int, Tuple <int, int, MatrixByArr> > >(); foreach (var ir_col in right.EnumColBlocksAll()) { right_ir_cols.Add(ir_col.Item1, ir_col.Item2.HToDictionaryWithKeyItem1()); } HessMatrix mul = null; if ((left is HessMatrixDense) && (right is HessMatrixDense)) { mul = HessMatrixDense.ZerosDense(left.ColSize, right.RowSize); } else { mul = HessMatrixSparse.ZerosSparse(left.ColSize, right.RowSize); } for (int ic = 0; ic < left.ColBlockSize; ic++) { var left_row = left_ic_rows[ic]; if (left_row.Count == 0) { continue; } for (int ir = 0; ir < right.RowBlockSize; ir++) { var right_col = right_ir_cols[ir]; if (right_col.Count == 0) { continue; } foreach (var left_ck in left_row) { int ik = left_ck.Key; HDebug.Assert(ic == left_ck.Value.Item1); HDebug.Assert(ik == left_ck.Value.Item2); if (right_col.ContainsKey(ik)) { var right_kr = right_col[ik]; HDebug.Assert(ik == right_kr.Item1); HDebug.Assert(ir == right_kr.Item2); MatrixByArr mul_ckr = mul.GetBlock(ic, ir) + left_ck.Value.Item3 * right_kr.Item3; mul.SetBlock(ic, ir, mul_ckr); } } } } return(mul); }