TSparseMat oprods(const TVec &a, const TVec &b) // returns outerproduct of a and b: a * trans(b) { TSparseMat result; Int i; result.SetSize(a.Elts(), b.Elts()); for (i = 0; i < a.Elts(); i++) if (TSparseVec::IsNonZero(a[i])) { result[i] = b; result[i] *= a[i]; } else result[i] = vl_0; return(result); }
TVReal dot(const TSparseVec &a, const TVec &b) { Assert(a.Elts() == b.Elts(), "(SparseVec::dot) Vec sizes don't match"); TMReal sum = vl_zero; Int i; for (i = 0; i < a.NumItems() - 1; i++) sum += a[i].elt * b[a[i].index]; return(sum); }
TVec operator * (const TSparseMat &m, const TVec &v) { Assert(m.Cols() == v.Elts(), "(SparseMat::*v) matrix and vector sizes don't match"); Int i; TVec result(m.Rows()); for (i = 0; i < m.Rows(); i++) result[i] = dot(m[i], v); return(result); }
TMReal dot(const TMVec &a, const TVec &b) { Assert(a.Elts() == b.Elts(), "(Vec::dot) Vec sizes don't match"); TMReal sum = vl_zero; Int i; for (i = 0; i < a.Elts(); i++) sum += a[i] * b[i]; return(sum); }
TVec operator * (const TVec &v, const TMat &m) // v * m { Assert(v.Elts() == m.Rows(), "(Mat::v*m) vector/matrix sizes don't match"); TMVec temp(m.Cols(), vl_zero); // accumulate in high precision TVec result(m.Cols()); // return low precision. Int i; for (i = 0; i < m.Rows(); i++) temp += m[i] * v[i]; for (i = 0; i < temp.Elts(); i++) result[i] = temp[i]; return(result); }
TVec operator * (const TVec &v, const TSparseMat &m) // v * m { Assert(v.Elts() == m.Rows(), "(Mat::v*m) vector/matrix sizes don't match"); TVec result(m.Cols()); Int i, j; result = vl_zero; // v * M = v[0] * m[0] + v[1] * m[1] + ... for (i = 0; i < m.Rows(); i++) if (len(v[i]) > 0) for (j = 0; j < m[i].NumItems() - 1; j++) result[m[i][j].index] += v[i] * m[i][j].elt; return(result); }