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