void Tensor::Divide(Tensor& result_tensor, Tensor& t1, double val) { result_tensor.Initialize(t1.Dims()); for (int i = 0; i < t1.NumElements(); ++i) { result_tensor.Set(i, t1.At(i) / val); } }
// add two tensors, store result in result_tensor which is assumed // to be uninitialized void Tensor::Add(Tensor& result_tensor, Tensor& t1, Tensor& t2) { assert(t1.NumElements() == t2.NumElements()); result_tensor.Initialize(t1.Dims()); for (int i = 0; i < result_tensor.NumElements(); ++i) { result_tensor.Set(i, t1.At(i) + t2.At(i)); } }
void Tensor::Rearrange(Tensor& result_tensor, Tensor& orig_tensor, vector<int>& old_to_new_modes) { vector<int> new_dims; VectorPlus::Rearrange(new_dims, orig_tensor.Dims(), old_to_new_modes); result_tensor.Initialize(new_dims); int i = 0; FastIndexer indexer(orig_tensor.Dims()); while (indexer.HasNext()) //for (int i = 0; i < orig_tensor.NumElements(); ++i) { vector<int>& orig_indices = indexer.GetNext(); // vector<int> orig_indices; // orig_tensor.ComputeIndexArray(orig_indices, i); vector<int> new_indices; VectorPlus::Rearrange(new_indices, orig_indices, old_to_new_modes); result_tensor.Set(new_indices, orig_tensor.At(i++)); } }
vector<int>& Dims() { return prob_tensor->Dims(); }
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)); } } }