00001
00007 #ifndef TENSOR_H
00008 #define TENSOR_H
00009
00010 #include <math.h>
00011 #include <stdio.h>
00012 #include "common.h"
00013 #include "Vector.h"
00014
00015 class Tensor {
00016 public:
00017 BigReal xx, xy, xz;
00018 BigReal yx, yy, yz;
00019 BigReal zx, zy, zz;
00020
00021 inline Tensor(void) {
00022 xx=xy=xz=yx=yy=yz=zx=zy=zz=0.0;
00023 }
00024
00025 inline Tensor(const Tensor &t2) {
00026 xx = t2.xx; xy = t2.xy; xz = t2.xz;
00027 yx = t2.yx; yy = t2.yy; yz = t2.yz;
00028 zx = t2.zx; zy = t2.zy; zz = t2.zz;
00029 }
00030
00031 static inline Tensor identity(BigReal v1 = 1.0) {
00032 Tensor tmp;
00033 tmp.xx = tmp.yy = tmp.zz = v1;
00034 return tmp;
00035 }
00036
00037 static inline Tensor diagonal(const Vector &v1) {
00038 Tensor tmp;
00039 tmp.xx = v1.x; tmp.xy = 0; tmp.xz = 0;
00040 tmp.yx = 0; tmp.yy = v1.y; tmp.yz = 0;
00041 tmp.zx = 0; tmp.zy = 0; tmp.zz = v1.z;
00042 return tmp;
00043 }
00044
00045 static inline Tensor symmetric(const Vector &v1, const Vector &v2) {
00046 Tensor tmp;
00047 tmp.xx = v1.x; tmp.xy = v2.x; tmp.xz = v2.y;
00048 tmp.yx = v2.x; tmp.yy = v1.y; tmp.yz = v2.z;
00049 tmp.zx = v2.y; tmp.zy = v2.z; tmp.zz = v1.z;
00050 return tmp;
00051 }
00052
00053 static inline Tensor triangular(const Vector &v1, const Vector &v2) {
00054 Tensor tmp;
00055 tmp.xx = v1.x; tmp.xy = v2.x; tmp.xz = v2.y;
00056 tmp.yx = 0; tmp.yy = v1.y; tmp.yz = v2.z;
00057 tmp.zx = 0; tmp.zy = 0; tmp.zz = v1.z;
00058 return tmp;
00059 }
00060
00061 ~Tensor(void) { }
00062
00063 inline Tensor& operator=(const Tensor &t2) {
00064 xx = t2.xx; xy = t2.xy; xz = t2.xz;
00065 yx = t2.yx; yy = t2.yy; yz = t2.yz;
00066 zx = t2.zx; zy = t2.zy; zz = t2.zz;
00067 return *this;
00068 }
00069
00070 inline Tensor& operator=(const BigReal &r2) {
00071 xx=xy=xz=yx=yy=yz=zx=zy=zz=r2;
00072 return *this;
00073 }
00074
00075 inline Tensor& operator+=(const Tensor &t2) {
00076 xx += t2.xx; xy += t2.xy; xz += t2.xz;
00077 yx += t2.yx; yy += t2.yy; yz += t2.yz;
00078 zx += t2.zx; zy += t2.zy; zz += t2.zz;
00079 return *this;
00080 }
00081
00082 inline Tensor& operator-=(const Tensor &t2) {
00083 xx -= t2.xx; xy -= t2.xy; xz -= t2.xz;
00084 yx -= t2.yx; yy -= t2.yy; yz -= t2.yz;
00085 zx -= t2.zx; zy -= t2.zy; zz -= t2.zz;
00086 return *this;
00087 }
00088
00089 inline Tensor& operator*=(const BigReal &r2) {
00090 xx *= r2; xy *= r2; xz *= r2;
00091 yx *= r2; yy *= r2; yz *= r2;
00092 zx *= r2; zy *= r2; zz *= r2;
00093 return *this;
00094 }
00095
00096 inline Tensor& operator/=(const BigReal &r2) {
00097 xx /= r2; xy /= r2; xz /= r2;
00098 yx /= r2; yy /= r2; yz /= r2;
00099 zx /= r2; zy /= r2; zz /= r2;
00100 return *this;
00101 }
00102
00103 inline void outerAdd (BigReal scale, const Vector &v1, const Vector &v2);
00104
00105 inline friend int operator==(const Tensor &t1, const Tensor &t2) {
00106 return (
00107 t1.xx == t2.xx && t1.xy == t2.xy && t1.xz == t2.xz &&
00108 t1.yx == t2.yx && t1.yy == t2.yy && t1.yz == t2.yz &&
00109 t1.zx == t2.zx && t1.zy == t2.zy && t1.zz == t2.zz );
00110 }
00111
00112 inline friend int operator!=(const Tensor &t1, const Tensor &t2) {
00113 return ( ! ( t1 == t2 ) );
00114 }
00115
00116 inline friend Tensor operator+(const Tensor& t1, const Tensor& t2) {
00117 Tensor tmp(t1);
00118 tmp += t2;
00119 return tmp;
00120 }
00121
00122 inline friend Tensor operator-(const Tensor& t1, const Tensor& t2) {
00123 Tensor tmp(t1);
00124 tmp -= t2;
00125 return tmp;
00126 }
00127
00128 inline friend Tensor operator-(const Tensor &t1) {
00129 Tensor tmp(t1);
00130 tmp *= -1.0;
00131 return tmp;
00132 }
00133
00134 inline friend Tensor operator*(const BigReal &r1, const Tensor &t2) {
00135 Tensor tmp(t2);
00136 tmp *= r1;
00137 return tmp;
00138 }
00139
00140 inline friend Tensor operator*(const Tensor &t1, const BigReal &r2) {
00141 Tensor tmp(t1);
00142 tmp *= r2;
00143 return tmp;
00144 }
00145
00146 inline friend Tensor operator/(const Tensor &t1, const BigReal &r2) {
00147 Tensor tmp(t1);
00148 tmp /= r2;
00149 return tmp;
00150 }
00151
00152 inline friend Vector operator*(const Tensor &t1, const Vector &v2) {
00153 Vector tmp;
00154 tmp.x = t1.xx * v2.x + t1.xy * v2.y + t1.xz * v2.z;
00155 tmp.y = t1.yx * v2.x + t1.yy * v2.y + t1.yz * v2.z;
00156 tmp.z = t1.zx * v2.x + t1.zy * v2.y + t1.zz * v2.z;
00157 return tmp;
00158 }
00159
00160 inline friend Vector operator*(const Vector &v1, const Tensor &t2) {
00161 Vector tmp;
00162 tmp.x = t2.xx * v1.x + t2.yx * v1.y + t2.zx * v1.z;
00163 tmp.y = t2.xy * v1.x + t2.yy * v1.y + t2.zy * v1.z;
00164 tmp.z = t2.xz * v1.x + t2.yz * v1.y + t2.zz * v1.z;
00165 return tmp;
00166 }
00167
00168 inline friend Tensor outer(const Vector &v1, const Vector &v2);
00169
00170 inline friend Tensor transpose(const Tensor &t1) {
00171 Tensor tmp;
00172 tmp.xx = t1.xx; tmp.yx = t1.xy; tmp.zx = t1.xz;
00173 tmp.xy = t1.yx; tmp.yy = t1.yy; tmp.zy = t1.yz;
00174 tmp.xz = t1.zx; tmp.yz = t1.zy; tmp.zz = t1.zz;
00175 return tmp;
00176 }
00177
00178 inline friend Tensor symmetric(const Tensor &t1) {
00179 Tensor tmp;
00180 tmp.xx = t1.xx; tmp.xy = 0.5*(t1.xy+t1.yx); tmp.xz = 0.5*(t1.xz+t1.zx);
00181 tmp.yx = tmp.xy; tmp.yy = t1.yy; tmp.yz = 0.5*(t1.yz+t1.zy);
00182 tmp.zx = tmp.xz; tmp.zy = tmp.yz; tmp.zz = t1.zz;
00183 return tmp;
00184 }
00185
00186 inline friend Tensor triangular(const Tensor &t1) {
00187 Tensor tmp;
00188 tmp.xx = t1.xx; tmp.xy = 0.5*(t1.xy+t1.yx); tmp.xz = 0.5*(t1.xz+t1.zx);
00189 tmp.yx = 0; tmp.yy = t1.yy; tmp.yz = 0.5*(t1.yz+t1.zy);
00190 tmp.zx = 0; tmp.zy = 0; tmp.zz = t1.zz;
00191 return tmp;
00192 }
00193
00194 inline friend Vector diagonal(const Tensor &t1) {
00195 return Vector(t1.xx,t1.yy,t1.zz);
00196 }
00197
00198 inline friend Vector off_diagonal(const Tensor &t1) {
00199 return Vector(t1.xy,t1.xz,t1.yz);
00200 }
00201
00202 inline friend BigReal trace(const Tensor &t1) {
00203 return (t1.xx + t1.yy + t1.zz);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 };
00240
00241 inline Tensor outer(const Vector &v1, const Vector &v2) {
00242 Tensor tmp;
00243 tmp.xx = v1.x * v2.x;
00244 tmp.xy = v1.x * v2.y;
00245 tmp.xz = v1.x * v2.z;
00246 tmp.yx = v1.y * v2.x;
00247 tmp.yy = v1.y * v2.y;
00248 tmp.yz = v1.y * v2.z;
00249 tmp.zx = v1.z * v2.x;
00250 tmp.zy = v1.z * v2.y;
00251 tmp.zz = v1.z * v2.z;
00252 return tmp;
00253 }
00254
00255 inline void Tensor::outerAdd (BigReal scale, const Vector &v1, const Vector &v2) {
00256 xx += v1.x * v2.x * scale;
00257 xy += v1.x * v2.y * scale;
00258 xz += v1.x * v2.z * scale;
00259 yx += v1.y * v2.x * scale;
00260 yy += v1.y * v2.y * scale;
00261 yz += v1.y * v2.z * scale;
00262 zx += v1.z * v2.x * scale;
00263 zy += v1.z * v2.y * scale;
00264 zz += v1.z * v2.z * scale;
00265 }
00266
00267 #endif
00268