// l labels the position the vector index goes in. // After that, indices are cyclic. Tensor outerProduct(const DoubleVector &V, const DoubleMatrix & M, int l) { Tensor temp; int i, j, k; for (i=1; i<=3; i++) for (j=1; j<=3; j++) for (k=1; k<=3; k++) { switch(l) { case 1: temp(i, j, k) = V.display(i) * M.display(j, k); break; case 2: temp(i, j, k) = V.display(j) * M.display(k, i); break; case 3: temp(i, j, k) = V.display(k) * M.display(i, j); break; default: ostringstream ii; ii << "Trying to outer product " << l << "th element of tensor"; throw ii.str(); break; } } return temp; }
// T^kij=M^kl T^lij Tensor Tensor::raise(const DoubleMatrix & M) const { Tensor temp; int i,k,j,l; for(k=1; k<=3; k++) for(i=1; i<=3; i++) for(j=1; j<=3; j++) for(l=1; l<=3; l++) temp(k, i, j) += M.display(k, l) * this -> display(l, i, j); return temp; }
// T^kij = M_il T^klj Tensor operator*(const DoubleMatrix &M, const Tensor &T) { if (M.displayRows() !=3 || M.displayCols() != 3) { ostringstream ii; ii << "DoubleMatrix " << M << " * Tensor" << T << "of wrong size\n"; throw ii.str(); } Tensor temp; int i,j,k,l; for(k=1; k<=3; k++) for(i=1; i<=3; i++) for(j=1; j<=3; j++) for(l=1; l<=3; l++) temp(k, i, j) += M.display(i, l) * T.display(k, l, j); return temp; }
// Does T^ijk = T^ljk M_li Tensor Tensor::product(const DoubleMatrix & M) const { if (M.displayRows() != 3 || M.displayCols() !=3) { ostringstream ii; ii << "Tensor " << *this << " * matrix" << M << "of wrong size.\n"; throw ii.str(); } Tensor T; int i,j,k,l; for (i=1; i<=3; i++) for (j=1; j<=3; j++) for (k=1; k<=3; k++) for (l=1; l<=3; l++) T(i, j, k) = T(i, j, k) + display(l, j, k) * M.display(l, i); return T; }