TSparseVec operator - (const TSparseVec &a, const TSparseVec &b) { Assert(a.Elts() == b.Elts(), "(SparseVec::-) Vec sizes don't match"); TSparseVec result(a.Elts()); Int i, j; for (i = 0, j = 0; ; ) if (a[i].index == b[j].index) { if (a[i].index == VL_SV_MAX_INDEX) break; result.AddElt(a[i].index, a[i].elt - b[j].elt); // - i++; j++; } else if (a[i].index < b[j].index) { result.AddNZElt(a[i]); i++; } else { result.AddNZElt(b[j].index, -b[j].elt); j++; } result.End(); return(result); }
TSparseVec operator + (const TSparseVec &a, const TSparseVec &b) { Assert(a.Elts() == b.Elts(), "(SparseVec::+) Vec sizes don't match"); TSparseVec result(a.Elts()); Int i, j; // Step through a and b in parallel for (i = 0, j = 0; ; ) if (a[i].index == b[j].index) { // We have two elements at the same index. // Are we at the end of both arrays? if (a[i].index == VL_SV_MAX_INDEX) break; // If not, add the result result.AddElt(a[i].index, a[i].elt + b[j].elt); // + i++; j++; } else if (a[i].index < b[j].index) // result[x] = a[i] + 0 { result.AddNZElt(a[i]); i++; } else // result[x] = b[j] + 0 { result.AddNZElt(b[j]); j++; } result.End(); return(result); }
TSparseVec operator * (const TSparseVec &v, TVReal s) { TSparseVec result(v.Elts()); Int i; for (i = 0; i < v.NumItems() - 1; i++) result.AddElt(v[i].index, s * v[i].elt); result.End(); return(result); }
TSparseVec operator - (const TSparseVec &v) { TSparseVec result(v.Elts()); Int i; for (i = 0; i < v.NumItems() - 1; i++) result.AddNZElt(v[i].index, -v[i].elt); result.End(); 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); }
TVReal dot(const TSparseVec &a, const TSparseVec &b) { Assert(a.Elts() == b.Elts(), "(SparseVec::dot) Vec sizes don't match"); TMReal sum = vl_zero; TSVIter j(a); Int i; for (i = 0; i < b.NumItems() - 1; i++) if (j.IncTo(b[i].index)) sum += j.Data() * b[i].elt; return(sum); }
TSparseVec operator / (const TSparseVec &a, const TSparseVec &b) { Assert(a.Elts() == b.Elts(), "(SparseVec::/) Vec sizes don't match"); TSparseVec result(a.Elts()); TSVIter j(a); Int i; for (i = 0; i < b.NumItems() - 1; i++) if (j.IncTo(b[i].index)) result.AddElt(b[i].index, j.Data() / b[i].elt); result.End(); return(result); }
TSparseVec operator * (const TSparseVec &v, const TSparseMat &m) // v * m { Assert(v.Elts() == m.Rows(), "(Mat::v*m) vector/matrix sizes don't match"); TMSparseVec temp(m.Cols()); TSparseVec result(m.Cols()); Int i; TSVIter j(v); TMSVIter k; temp = vl_zero; // v * M = v[0] * m[0] + v[1] * m[1] + ... for (i = 0; i < m.Rows(); i++) { j.Inc(i); if (j.Exists(i)) temp += m[i] * j.Data(); } result.SetNumElts(temp.Elts()); result.Begin(); for (k.Begin(temp.Elts()); !k.AtEnd(); k.Inc()) result.AddNZElt(k.Index(), k.Data()); result.End(); return(result); }
TSparseMat oprod(const TSparseVec &a, const TSparseVec &b) // returns outerproduct of a and b: a * trans(b) { TSparseMat result; TSVIter i; result.SetSize(a.Elts(), b.Elts()); result = vl_0; for (i.Begin(a); !i.AtEnd(); i.Inc()) { result[i.Index()] = b; result[i.Index()] *= i.Data(); } return(result); }
Bool operator == (const TSparseVec &a, const TSparseVec &b) { Assert(a.Elts() == b.Elts(), "(SparseVec::==) Vec sizes don't match"); if (a.NumItems() != b.NumItems()) return(false); else { Int i; for (i = 0; i < a.NumItems(); i++) if (a[i] != b[i]) return(false); return(true); } }
TVReal sqrlen(const TSparseVec &v) { TVReal sum = vl_zero; Int i; for (i = 0; i < v.NumItems() - 1; i++) sum += sqrlen(v[i].elt); return(sum); }
TSparseVec operator * (const TSparseMat &m, const TSparseVec &v) { Assert(m.Cols() == v.Elts(), "(SparseMat::m*v) matrix and vector sizes don't match"); Int i; TSparseVec result(m.Rows()); for (i = 0; i < m.Rows(); i++) result.AddElt(i, dot(m[i], v)); result.End(); return(result); }
TMSparseVec operator * (const TSparseVec &v, const TSparseMat &m) // v * m { Assert(v.Elts() == m.Rows(), "(Mat::v*m) vector/matrix sizes don't match"); TMSparseVec result(m.Cols()); Int i; TSVIter j(v); result = vl_zero; // v * M = v[0] * m[0] + v[1] * m[1] + ... for (i = 0; i < m.Rows(); i++) { j.Inc(i); if (j.Exists(i)) result += m[i] * j.Data(); } return(result); }