00001 /* 00002 File: Mixed.cc 00003 00004 Function: Implements Mixed.h 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1997-2000, Andrew Willmott 00009 */ 00010 00011 #include "vl/Mixed.h" 00012 00013 00014 // --- Vector dot products ---------------------------------------------------- 00015 00016 00017 TMReal dot(const TMVec &a, const TVec &b) 00018 { 00019 Assert(a.Elts() == b.Elts(), "(Vec::dot) Vec sizes don't match"); 00020 00021 TMReal sum = vl_zero; 00022 Int i; 00023 00024 for (i = 0; i < a.Elts(); i++) 00025 sum += a[i] * b[i]; 00026 00027 return(sum); 00028 } 00029 00030 00031 #ifdef __SparseVec__ 00032 00033 TMReal dot(const TMSparseVec &a, const TSparseVec &b) 00034 { 00035 Assert(a.Elts() == b.Elts(), "(SparseVec::dot) Vec sizes don't match"); 00036 00037 TMReal sum = vl_zero; 00038 TMSVIter j(a); 00039 Int i; 00040 00041 for (i = 0; i < b.NumItems() - 1; i++) 00042 { 00043 if (j.IncTo(b[i].index)) 00044 sum += j.Data() * b[i].elt; 00045 } 00046 00047 return(sum); 00048 } 00049 00050 TMReal dot(const TMSparseVec &a, const TVec &b) 00051 { 00052 Assert(a.Elts() == b.Elts(), "(SparseVec::dot) Vec sizes don't match"); 00053 00054 TMReal sum = vl_zero; 00055 Int i; 00056 00057 for (i = 0; i < a.NumItems() - 1; i++) 00058 sum += a[i].elt * b[a[i].index]; 00059 00060 return(sum); 00061 } 00062 00063 #endif 00064 00065 00066 // --- Matrix-vector multiply ------------------------------------------------- 00067 00068 00069 TVec4 operator * (const TMat4 &m, const TVec4 &v) // m * v 00070 { 00071 TVec4 result; 00072 00073 result[0] = v[0] * m[0][0] + v[1] * m[0][1] + v[2] * m[0][2] + v[3] * m[0][3]; 00074 result[1] = v[0] * m[1][0] + v[1] * m[1][1] + v[2] * m[1][2] + v[3] * m[1][3]; 00075 result[2] = v[0] * m[2][0] + v[1] * m[2][1] + v[2] * m[2][2] + v[3] * m[2][3]; 00076 result[3] = v[0] * m[3][0] + v[1] * m[3][1] + v[2] * m[3][2] + v[3] * m[3][3]; 00077 00078 return(result); 00079 } 00080 00081 TVec4 operator * (const TVec4 &v, const TMat4 &m) // v * m 00082 { 00083 TVec4 result; 00084 00085 result[0] = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0] + v[3] * m[3][0]; 00086 result[1] = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1] + v[3] * m[3][1]; 00087 result[2] = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2] + v[3] * m[3][2]; 00088 result[3] = v[0] * m[0][3] + v[1] * m[1][3] + v[2] * m[2][3] + v[3] * m[3][3]; 00089 00090 return(result); 00091 } 00092 00093 TVec4 &operator *= (TVec4 &v, const TMat4 &m) // v *= m 00094 { 00095 TVReal t0, t1, t2; 00096 00097 t0 = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0] + v[3] * m[3][0]; 00098 t1 = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1] + v[3] * m[3][1]; 00099 t2 = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2] + v[3] * m[3][2]; 00100 v[3] = v[0] * m[0][3] + v[1] * m[1][3] + v[2] * m[2][3] + v[3] * m[3][3]; 00101 v[0] = t0; 00102 v[1] = t1; 00103 v[2] = t2; 00104 00105 return(v); 00106 } 00107 00108 TVec operator * (const TMat &m, const TVec &v) 00109 { 00110 Assert(m.Cols() == v.Elts(), "(Mat::*v) matrix and vector sizes don't match"); 00111 00112 Int i; 00113 TVec result(m.Rows()); 00114 00115 for (i = 0; i < m.Rows(); i++) 00116 result[i] = dot(m[i], v); 00117 00118 return(result); 00119 } 00120 00121 TVec operator * (const TVec &v, const TMat &m) // v * m 00122 { 00123 Assert(v.Elts() == m.Rows(), "(Mat::v*m) vector/matrix sizes don't match"); 00124 00125 TMVec temp(m.Cols(), vl_zero); // accumulate in high precision 00126 TVec result(m.Cols()); // return low precision. 00127 Int i; 00128 00129 for (i = 0; i < m.Rows(); i++) 00130 temp += m[i] * v[i]; 00131 00132 for (i = 0; i < temp.Elts(); i++) 00133 result[i] = temp[i]; 00134 00135 return(result); 00136 } 00137 00138 TVec &operator *= (TVec &v, const TMat &m) // v *= m 00139 { 00140 v = v * m; // Can't optimise much here... 00141 00142 return(v); 00143 } 00144 00145 #ifdef __SparseVec__ 00146 00147 TSparseVec operator * (const TSparseMat &m, const TSparseVec &v) 00148 { 00149 Assert(m.Cols() == v.Elts(), "(SparseMat::m*v) matrix and vector sizes don't match"); 00150 00151 Int i; 00152 TSparseVec result(m.Rows()); 00153 00154 result.Begin(); 00155 00156 for (i = 0; i < m.Rows(); i++) 00157 result.AddElt(i, dot(m[i], v)); 00158 00159 result.End(); 00160 00161 return(result); 00162 } 00163 00164 TSparseVec operator * (const TSparseVec &v, const TSparseMat &m) // v * m 00165 { 00166 Assert(v.Elts() == m.Rows(), "(Mat::v*m) vector/matrix sizes don't match"); 00167 00168 TMSparseVec temp(m.Cols()); 00169 TSparseVec result(m.Cols()); 00170 Int i; 00171 TSVIter j(v); 00172 TMSVIter k; 00173 00174 temp = vl_zero; 00175 00176 // v * M = v[0] * m[0] + v[1] * m[1] + ... 00177 00178 for (i = 0; i < m.Rows(); i++) 00179 { 00180 j.Inc(i); 00181 if (j.Exists(i)) 00182 temp += m[i] * j.Data(); 00183 } 00184 00185 result.SetNumElts(temp.Elts()); 00186 result.Begin(); 00187 00188 for (k.Begin(temp.Elts()); !k.AtEnd(); k.Inc()) 00189 result.AddNZElt(k.Index(), k.Data()); 00190 00191 result.End(); 00192 00193 return(result); 00194 } 00195 00196 TSparseVec &operator *= (TSparseVec &v, const TSparseMat &m) // v *= m 00197 { 00198 TSparseVec t = v * m; 00199 v.Replace(t); 00200 return(v); 00201 } 00202 00203 TVec operator * (const TSparseMat &m, const TVec &v) 00204 { 00205 Assert(m.Cols() == v.Elts(), "(SparseMat::*v) matrix and vector sizes don't match"); 00206 00207 Int i; 00208 TVec result(m.Rows()); 00209 00210 for (i = 0; i < m.Rows(); i++) 00211 result[i] = dot(m[i], v); 00212 00213 return(result); 00214 } 00215 00216 TVec operator * (const TVec &v, const TSparseMat &m) // v * m 00217 { 00218 Assert(v.Elts() == m.Rows(), "(Mat::v*m) vector/matrix sizes don't match"); 00219 00220 TVec result(m.Cols()); 00221 Int i, j; 00222 00223 result = vl_zero; 00224 00225 // v * M = v[0] * m[0] + v[1] * m[1] + ... 00226 00227 for (i = 0; i < m.Rows(); i++) 00228 if (len(v[i]) > 0) 00229 for (j = 0; j < m[i].NumItems() - 1; j++) 00230 result[m[i][j].index] += v[i] * m[i][j].elt; 00231 00232 return(result); 00233 } 00234 00235 TVec &operator *= (TVec &v, const TSparseMat &m) // v *= m 00236 { 00237 v = v * m; 00238 return(v); 00239 } 00240 00241 #endif