bool CheckInverse(Tensor<DataMesh>& A, Tensor<DataMesh>& B){ //Make sure the tensor and inverse of the inverse are equal for(int i=0;i<A.Dim();i++){ for(int j=0;j<B.Dim();j++){ for(int k=0;k<A(0).Size();k++){ double diff = A(i,j)[k] - B(i,j)[k]; REQUIRE(diff<1e-14 && diff>-1e-14, "Tensor and the inverse of its inverse are not equal"); } } } return true; }
bool checkInverse(Tensor<DataMesh>& A, Tensor<DataMesh>& B){ /** Checks that a tensor and its inverse are equal to within roundoff */ for(int i=0;i<A.Dim();i++){ for(int j=0;j<B.Dim();j++){ for(int k=0;k<A(0).Size();k++){ double d = A(i,j)[k]-B(i,j)[k]; REQUIRE(d<1e-14 && d>-1e-14, "Tensor and it's inverse are not the same"); } } } return true; }
void ComputeItemRho::RecomputeData(const DataBoxAccess& box) const { REQUIRE(l >= 0, "ERROR: l must be >= 0"); REQUIRE(abs(m) <= l, "ERROR: m must be between the values of -l and l"); const Tensor<DataMesh> rho_i=box.Get<Tensor<DataMesh> >(mInput); REQUIRE(rho_i.Dim() == 3, "ERROR: The Dimension of the Tensor<DataMesh> input must be 3"); REQUIRE(rho_i.Rank() == 0, "ERROR: The Rank of the Tensor<DataMesh> input must be 0"); const MyVector<DataMesh>& coords= box.Get<MyVector<DataMesh> >("GlobalCoords"); const Mesh mesh = box.Get<Mesh>("Mesh"); DataMesh theta(mesh); DataMesh phi(mesh); theta = acos(coords[2] / sqrt(coords[0]*coords[0] + coords[1]*coords[1] + coords[2]*coords[2])); phi = atan(coords[1] / coords[0]); Tensor<DataMesh> SHY(SphericalHarmonicYTDM(l, m, theta, phi, mesh)); mResult.assign(0, "", rho_i()*SHY()); }
void TensorDeterminant(const Tensor<DataMesh>& t, DataMesh& det) { ASSERT(t.Rank() == 2, "Not a matrix"); ASSERT(t.Dim() == 3, "Not 3D"); det = t(0,0) * (t(1,1)*t(2,2) - t(1,2)*t(2,1)) + t(0,1) * (t(1,2)*t(2,0) - t(1,0)*t(2,2)) + t(0,2) * (t(1,0)*t(2,1) - t(1,1)*t(2,0)); }
void TensorInverse(const Tensor<DataMesh>& t, Tensor<DataMesh>& inv) { ASSERT(t.Rank() == 2, "Not a matrix"); ASSERT(t.Dim() == 3, "Not 3D"); ASSERT(t.Structure() == inv.Structure(), "Tensors have different structures"); DataMesh det = t(0,0); TensorDeterminant(t, det); for(int i=0;i<det.Size();i++) { ASSERT(det[i] != 0, "Singular matrix"); } for(TensorIter it(t);it;++it) { IPoint ind = t.Structure().Indices(it.Index()); inv[it] = (t((ind[1]+1)%3,(ind[0]+1)%3) * t((ind[1]+2)%3,(ind[0]+2)%3) - t((ind[1]+1)%3,(ind[0]+2)%3) * t((ind[1]+2)%3,(ind[0]+1)%3)) / det; } }
int ModeDim(int mode) { return prob_tensor->Dim(mode); }
int VarDim(int var) { return prob_tensor->Dim((*vars_to_modes)[var]); }
// multiply two tensors, store result in result_tensor which is assumed to be uninitialized void Tensor::Multiply(Tensor& result_tensor, Tensor& t1, Tensor& t2, vector<int>& mult_modes1, vector<int>& mult_modes2) { assert(mult_modes1.size() == mult_modes2.size()); if (t1.Order() == mult_modes1.size() && t2.Order() == mult_modes2.size()) { double val = InnerProduct(t1, t2); vector<int> fake_dims; result_tensor.Initialize(fake_dims); result_tensor.Set(0, val); return; } int numMultElements = 1; vector<int> mult_dims(mult_modes1.size(), 0); for (int i = 0; i < mult_modes1.size(); ++i) { assert(t1.Dim(mult_modes1[i]) == t2.Dim(mult_modes2[i])); mult_dims[i] = t1.Dim(mult_modes1[i]); numMultElements = numMultElements * mult_dims[i]; } vector<int> mult_offsets; ComputeOffsets(mult_offsets, mult_dims); int result_order = t1.Order() + t2.Order() - mult_modes1.size() - mult_modes2.size(); if (result_order == 0) assert(0); vector<int> result_dims; vector<int> free_modes1; vector<int> free_modes2; // find free indices from t1 for (int i = 0; i < t1.Order(); ++i) { if (!VectorPlus::Contains(mult_modes1, i)) { result_dims.push_back(t1.Dim(i)); free_modes1.push_back(i); } } // find free indices from t2 for (int i = 0; i < t2.Order(); ++i) { if (!VectorPlus::Contains(mult_modes2, i)) { result_dims.push_back(t2.Dim(i)); free_modes2.push_back(i); } } // initialize result_tensor result_tensor.Initialize(result_dims); // fill in elements from result tensor FastIndexer result_indexer(result_dims); for (int n = 0; n < result_tensor.NumElements(); ++n) { vector<int>& indices = result_indexer.GetNext(); vector<int> free_indices1; vector<int> free_indices2; // result_tensor.ComputeIndexArray(indices, n); for (int i = 0; i < result_tensor.Order(); ++i) { if (i < free_modes1.size()) free_indices1.push_back(indices[i]); else free_indices2.push_back(indices[i]); } // sum over elementwise products of mult-mode elements double temp_sum = 0; FastIndexer mult_indexer(mult_dims); for (int k = 0; k < numMultElements; ++k) { vector<int>& mult_indices = mult_indexer.GetNext(); // ComputeIndexArray(mult_indices, mult_offsets, k); vector<int> indices1; vector<int> indices2; MergeIndices(indices1, mult_modes1, free_modes1, mult_indices, free_indices1); MergeIndices(indices2, mult_modes2, free_modes2, mult_indices, free_indices2); temp_sum += t1.At(indices1) * t2.At(indices2); } result_tensor.Set(n, temp_sum); } }
void Tensor::ElementwiseMultiply(Tensor& result_tensor, Tensor& t1, Tensor& t2, vector<int>& mult_modes1, vector<int>& mult_modes2) { assert(mult_modes1.size() == mult_modes2.size()); int numMultElements = 1; vector<int> mult_dims(mult_modes1.size(), 0); for (int i = 0; i < mult_modes1.size(); ++i) { assert(t1.Dim(mult_modes1[i]) == t2.Dim(mult_modes2[i])); mult_dims[i] = t1.Dim(mult_modes1[i]); numMultElements = numMultElements * mult_dims[i]; } vector<int> mult_offsets; ComputeOffsets(mult_offsets, mult_dims); int result_order = t1.Order() + t2.Order() - mult_modes2.size(); if (result_order == 0) assert(0); vector<int> result_dims; vector<int> free_modes1; vector<int> free_modes2; // find free indices from t1 for (int i = 0; i < t1.Order(); ++i) { if (!VectorPlus::Contains(mult_modes1, i)) { free_modes1.push_back(i); } } // find free indices from t2 for (int i = 0; i < t2.Order(); ++i) { if (!VectorPlus::Contains(mult_modes2, i)) { free_modes2.push_back(i); } } int curr_index = 0; for (int i = 0; i < result_order; ++i) { if (i < t1.Order()) { result_dims.push_back(t1.Dim(i)); } else { result_dims.push_back(t2.Dim(free_modes2[curr_index++])); } } // initialize result_tensor result_tensor.Initialize(result_dims); // fill in elements from result tensor FastIndexer indexer(result_dims); int n = 0; while (indexer.HasNext()) { vector<int>& indices = indexer.GetNext(); vector<int> indices1(t1.Order(), 0); vector<int> free_indices2; // result_tensor.ComputeIndexArray(indices, n); for (int i = 0; i < result_tensor.Order(); ++i) { if (i < t1.Order()) indices1[i] = indices[i]; else free_indices2.push_back(indices[i]); } vector<int> mult_indices; VectorPlus::Subset(mult_indices, indices1, mult_modes1); vector<int> indices2; MergeIndices(indices2, mult_modes2, free_modes2, mult_indices, free_indices2); double val = 0; double val1 = t1.At(indices1); if (val1 != 0) { val = val1 * t2.At(indices2); } result_tensor.Set(n++, val); } }
void Tensor::CreateLinearSystem(vector<double>& B_vec, Matrix& A_matrix, Tensor& X, Tensor& A, Tensor& B, vector<int>& mult_modesX, vector<int>& mult_modesA) { // fake multiply x and A together to create B, creating the linear system in the process assert(mult_modesX.size() == mult_modesA.size()); if (X.Order() == mult_modesX.size() && A.Order() == mult_modesA.size()) { assert(0); } int numMultElements = 1; vector<int> mult_dims(mult_modesX.size(), 0); for (int i = 0; i < mult_modesX.size(); ++i) { assert(X.Dim(mult_modesX[i]) == A.Dim(mult_modesA[i])); mult_dims[i] = X.Dim(mult_modesX[i]); numMultElements = numMultElements * mult_dims[i]; } vector<int> mult_offsets; ComputeOffsets(mult_offsets, mult_dims); int result_order = X.Order() + A.Order() - mult_modesX.size() - mult_modesA.size(); if (result_order == 0) assert(0); vector<int> result_dims; vector<int> free_modesX; vector<int> free_modesA; // find free indices from X for (int i = 0; i < X.Order(); ++i) { if (!VectorPlus::Contains(mult_modesX, i)) { free_modesX.push_back(i); } } // find free indices from A for (int i = 0; i < A.Order(); ++i) { if (!VectorPlus::Contains(mult_modesA, i)) { free_modesA.push_back(i); } } vector<int> a_mat_dims = VectorPlus::CreatePair(B.NumElements(), X.NumElements()); A_matrix.Initialize(a_mat_dims); B_vec.reserve(B.NumElements()); // fill in elements from result tensor FastIndexer B_indexer(B.Dims()); for (int n = 0; n < B.NumElements(); ++n) { B_vec.push_back(B.At(n)); vector<int>& indices = B_indexer.GetNext(); vector<int> free_indicesX; vector<int> free_indicesA; // B.ComputeIndexArray(indices, n); for (int i = 0; i < B.Order(); ++i) { if (!VectorPlus::Contains(mult_modesX, i)) free_indicesX.push_back(indices[i]); else free_indicesA.push_back(indices[i]); } // sum over elementwise products of mult-mode elements double temp_sum = 0; FastIndexer mult_indexer(mult_dims); for (int k = 0; k < numMultElements; ++k) { vector<int>& mult_indices = mult_indexer.GetNext(); // ComputeIndexArray(mult_indices, mult_offsets, k); vector<int> indicesX; vector<int> indicesA; MergeIndices(indicesX, mult_modesX, free_modesX, mult_indices, free_indicesX); MergeIndices(indicesA, mult_modesA, free_modesA, mult_indices, free_indicesA); A_matrix.Set(n, X.ComputeIndex(indicesX), A.At(indicesA)); } } }