/* * Compute * C = C*diag(D) flags & RIGHT == true * C = diag(D)*C flags & LEFT == true * * Arguments * C M-by-N matrix if flags&RIGHT == true or N-by-M matrix if flags&LEFT == true * * D N element column or row vector or N-by-N matrix * * flags Indicator bits, LEFT or RIGHT */ func MultDiag(C, D *matrix.FloatMatrix, flags Flags) { var c, d0 matrix.FloatMatrix if D.Cols() == 1 { // diagonal is column vector switch flags & (LEFT | RIGHT) { case LEFT: // scale rows; for each column element-wise multiply with D-vector for k := 0; k < C.Cols(); k++ { C.SubMatrix(&c, 0, k, C.Rows(), 1) c.Mul(D) } case RIGHT: // scale columns for k := 0; k < C.Cols(); k++ { C.SubMatrix(&c, 0, k, C.Rows(), 1) // scale the column c.Scale(D.GetAt(k, 0)) } } } else { // diagonal is row vector var d *matrix.FloatMatrix if D.Rows() == 1 { d = D } else { D.SubMatrix(&d0, 0, 0, 1, D.Cols(), D.LeadingIndex()+1) d = &d0 } switch flags & (LEFT | RIGHT) { case LEFT: for k := 0; k < C.Rows(); k++ { C.SubMatrix(&c, k, 0, 1, C.Cols()) // scale the row c.Scale(d.GetAt(0, k)) } case RIGHT: // scale columns for k := 0; k < C.Cols(); k++ { C.SubMatrix(&c, 0, k, C.Rows(), 1) // scale the column c.Scale(d.GetAt(0, k)) } } } }