Example #1
0
void Tensor::Slice(Tensor& result_tensor, int fixed_mode, int fixed_index)
{
	vector<int> result_dims;
	vector<int> free_modes;


	vector<int> fixed_mode_vec  = VectorPlus::CreateSingleton(fixed_mode);
	vector<int> fixed_index_vec = VectorPlus::CreateSingleton(fixed_index);

	VectorPlus::SetDiff(free_modes, *all_modes,  fixed_mode_vec);
	VectorPlus::Subset(result_dims, *dims, free_modes);
	
	result_tensor.Initialize(result_dims);

	if (result_tensor.NumElements() == 1)
	{
		assert(fixed_mode == 1);
		result_tensor.Set(0, this->At(fixed_index));
		return;
	}
	FastIndexer indexer(result_dims);

	int i = 0;
	while (indexer.HasNext())
//	for (int i = 0; i < result_tensor.NumElements(); ++i)
	{
		vector<int>& indices = indexer.GetNext();
	//	vector<int> indices;
		vector<int> total_indices;
	//	result_tensor.ComputeIndexArray(indices, i); 
		MergeIndices(total_indices, free_modes, fixed_mode_vec, indices, fixed_index_vec); 

		result_tensor.Set(i++, this->At(total_indices));
	}
}
Example #2
0
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);
	}
}
Example #3
0
// 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));
	}
}
Example #4
0
void Tensor::Slice(Tensor& result_tensor, vector<int>& fixed_modes, vector<int>& fixed_indices)
{
	vector<int> free_modes;
	vector<int> free_dims;
	VectorPlus::SetDiff(free_modes, *all_modes, fixed_modes);
	VectorPlus::Subset(free_dims, *dims, free_modes);
	result_tensor.Initialize(free_dims);
	int i = 0;
	FastIndexer indexer(free_dims);
	while (indexer.HasNext())
//	for (int i = 0; i < result_tensor.NumElements(); ++i)
	{
	//	vector<int> result_indices;
	//	result_tensor.ComputeIndexArray(result_indices, i);
		vector<int>& result_indices = indexer.GetNext();
		vector<int> orig_indices;
		MergeIndices(orig_indices, free_modes, fixed_modes, result_indices, fixed_indices);
		result_tensor.Set(i++, this->At(orig_indices));
	}
}
Example #5
0
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++));
	}
}
Example #6
0
void Tensor::Select(Tensor& result_tensor, vector<int>& fixed_modes, vector<int>& fixed_indices)
{
	result_tensor.Initialize(*dims);

	int i = 0;
	FastIndexer indexer(*dims);
	while (indexer.HasNext())
//	for (int i = 0; i < result_tensor.NumElements(); ++i)
	{
		vector<int>& i_indices = indexer.GetNext();
	//	vector<int> i_indices;
	//	result_tensor.ComputeIndexArray(i_indices, i);
		vector<int> fixed_i_indices;
		VectorPlus::Subset(fixed_i_indices, i_indices, fixed_modes);
		if (VectorPlus::Equals(fixed_i_indices, fixed_indices))
			result_tensor.Set(i, this->At(i));
		else
			result_tensor.Set(i, 0);
		i++;
	}

}
Example #7
0
bool Tensor::Inverse(Tensor& Umat, Tensor& result_tensor, vector<int>& mult_modes, int nonzerovals)
{	
	int num_sing_vals = (int)pow((double)nonzerovals, (double)mult_modes.size());

	vector<int> free_modes;
	vector<int> mult_dims;
	vector<int> free_dims;
	vector<int> mult_offsets;
	vector<int> free_offsets;

	VectorPlus::SetDiff(free_modes, *all_modes, mult_modes);  
	VectorPlus::Subset(mult_dims, *dims, mult_modes);
	VectorPlus::CSubset(free_dims, *dims, mult_modes);
	ComputeOffsets(mult_offsets, mult_dims);
	ComputeOffsets(free_offsets, free_dims);

	vector<int> usmalldims(free_modes.size(), nonzerovals);
	vector<int> udims;
	vector<int> usmall_offsets;
	ComputeOffsets(usmall_offsets, usmalldims);

	VectorPlus::Concat(udims, free_dims, usmalldims);
	Umat.Initialize(udims);

	vector<int> result_dims;
		VectorPlus::Concat(result_dims, free_dims, usmalldims);
		result_tensor.Initialize(result_dims);

/*	int numMultElements = VectorPlus::Product(mult_dims);
	int numFreeElements = VectorPlus::Product(free_dims);

	assert(numMultElements == numFreeElements);

    Eigen::MatrixXd matricized_tensor(numFreeElements,numMultElements);

	cout << "copy start 1\n";
	for (int i = 0; i < numFreeElements; ++i)
	{
		vector<int> free_indices;
		ComputeIndexArray(free_indices, free_offsets, i);
		for (int j = 0; j < numMultElements; ++j)
		{
			vector<int> mult_indices;
			ComputeIndexArray(mult_indices, mult_offsets, j);
			vector<int> total_indices;
			VectorPlus::Concat(total_indices, free_indices, mult_indices);
			matricized_tensor(i,j) = this->At(total_indices);
		}
	}
	cout << "copy end 1\n";	
//	MatrixXd matricized_inverse = matricized_tensor.inverse();
//	cout << matricized_inverse;
//	cout << "\n";
	//compute pseudoinverse
	cout << "svd start 1\n";	
		Eigen::JacobiSVD<Eigen::MatrixXd> svd(matricized_tensor, Eigen::ComputeFullU);
		Eigen::MatrixXd U = svd.matrixU();
		cout << "svd end 1\n";	
		Eigen::MatrixXd thinU = U.leftCols(num_sing_vals);
		
	/*	MatrixXd reduced_matrix = thinU.transpose() * matricized_tensor;

		JacobiSVD<MatrixXd> svd2(reduced_matrix, ComputeFullU | ComputeFullV);
		U = svd2.matrixU();


		MatrixXd Uleft = U.leftCols(num_sing_vals);
		MatrixXd V = svd2.matrixV();
		MatrixXd Vleft = V.leftCols(num_sing_vals);
		VectorXd s_vals = svd2.singularValues();

		MatrixXd Sigma(num_sing_vals, num_sing_vals);
		for (int i = 0; i < num_sing_vals; ++i)
		{
			for (int j = 0; j < num_sing_vals; ++j)
			{
				Sigma(i,j) = 0;
			}
		}

		for (int s = 0; s < num_sing_vals;  ++s)
		{
			cout << s_vals(s);
			cout << "\n";
			if (abs(s_vals(s)) < .00000000001)
				assert(0);
			Sigma(s,s) = 1.0 / s_vals(s);
			
		}

		MatrixXd pinverse_temp = Vleft * Sigma;
	 MatrixXd matricized_inverse = pinverse_temp * Uleft.transpose();
	 */
	

		// rearrange into tensor
/*	 	vector<int> result_dims;
		VectorPlus::Concat(result_dims, free_dims, usmalldims);
		result_tensor.Initialize(result_dims);


	/*	for (int i = 0; i < matricized_inverse.rows(); ++i)
		{
			vector<int> left_indices;
			ComputeIndexArray(left_indices, free_offsets, i);

			for (int j = 0; j < matricized_inverse.cols(); ++j)
			{
				vector<int> right_indices;
				ComputeIndexArray(right_indices, usmall_offsets, j);
				vector<int> total_indices;

				VectorPlus::Concat(total_indices, left_indices, right_indices);
				result_tensor.Set(total_indices, matricized_inverse(i, j));
			}
		} */

	
	/*	VectorPlus::Concat(udims, free_dims, usmalldims);
		Umat.Initialize(udims);

		

		vector<int> semi_dims;
		semi_dims.push_back(thinU.rows());
		semi_dims.push_back(thinU.cols());

		cout << "copy start 2 \n";	
		for (int i = 0; i < thinU.rows(); ++i)
		{
			vector<int> left_indices;
			ComputeIndexArray(left_indices, free_offsets, i);

			for (int j = 0; j < thinU.cols(); ++j)
			{
				vector<int> right_indices;
				ComputeIndexArray(right_indices, usmall_offsets, j);
				vector<int> indices;
				VectorPlus::Concat(indices, left_indices, right_indices);
			//	Umat.Set(indices, rand_matrix.At(i,j));
				Umat.Set(indices, thinU(i,j));

				if (thinU.rows() == thinU.cols())
				{
					if (VectorPlus::Equals(left_indices, right_indices))
					{	
						Umat.Set(indices, 1);
					}
					else
					{
						Umat.Set(indices, 0);
					}
				}
			}
		}
		cout << "copy end 2 \n"; */
	return true;
}
Example #8
0
// 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);
	}
}
Example #9
0
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);
	}
}
Example #10
0
bool Tensor::ComputeJointSVD(Tensor& Umat, vector<Tensor*>& extra_tensor_list, vector<int>& mult_modes, int nonzerovals)
{
	int num_sing_vals = (int)pow((double)nonzerovals, (double)mult_modes.size());

	vector<int> free_modes;
	vector<int> mult_dims;
	vector<int> free_dims;
	vector<int> mult_offsets;
	vector<int> free_offsets;

	Tensor& temp_tensor = *(extra_tensor_list.at(0));
	VectorPlus::SetDiff(free_modes, temp_tensor.Modes(), mult_modes);  
	VectorPlus::Subset(mult_dims, temp_tensor.Dims(), mult_modes);
	VectorPlus::CSubset(free_dims, temp_tensor.Dims(), mult_modes);
	ComputeOffsets(mult_offsets, mult_dims);
	ComputeOffsets(free_offsets, free_dims);

	vector<int> usmalldims(free_modes.size(), nonzerovals);
	vector<int> udims;
	vector<int> usmall_offsets;
	ComputeOffsets(usmall_offsets, usmalldims);

	int numMultElements = VectorPlus::Product(mult_dims);
	int numFreeElements = VectorPlus::Product(free_dims);

	assert(numMultElements == numFreeElements);

    Eigen::MatrixXd matricized_tensor(numFreeElements,extra_tensor_list.size() * numMultElements);

	//cout << "copy start 1\n";
	for (int z = 0; z < extra_tensor_list.size(); ++z)
	{
		int z_offset = z * numMultElements;
		FastIndexer i_indexer(free_dims);
		for (int i = 0; i < numFreeElements; ++i)
		{
			vector<int>& free_indices = i_indexer.GetNext();
		//	ComputeIndexArray(free_indices, free_offsets, i);
			FastIndexer j_indexer(mult_dims);
			for (int j = 0; j < numMultElements; ++j)
			{
				vector<int>& mult_indices = j_indexer.GetNext();
		//		ComputeIndexArray(mult_indices, mult_offsets, j);
				vector<int> total_indices;
				VectorPlus::Concat(total_indices, free_indices, mult_indices);
				matricized_tensor(i,z_offset + j) = extra_tensor_list.at(z)->At(total_indices);
			}
		}
	}
//	cout << "copy end 1\n";	
//	MatrixXd matricized_inverse = matricized_tensor.inverse();
//	cout << matricized_inverse;
//	cout << "\n";
	//compute pseudoinverse
	//cout << "svd start 1\n";	
		Eigen::JacobiSVD<Eigen::MatrixXd> svd(matricized_tensor, Eigen::ComputeFullU);
		Eigen::MatrixXd U = svd.matrixU();
	//	cout << "svd end 1\n";	
		Eigen::MatrixXd thinU = U.leftCols(num_sing_vals);
		
	
		VectorPlus::Concat(udims, free_dims, usmalldims);
		Umat.Initialize(udims);

		

		vector<int> semi_dims;
		semi_dims.push_back(thinU.rows());
		semi_dims.push_back(thinU.cols());

	//	cout << "copy start 2 \n";	
		FastIndexer i_indexer(free_dims);
		for (int i = 0; i < thinU.rows(); ++i)
		{
			vector<int>& left_indices = i_indexer.GetNext();
		//	ComputeIndexArray(left_indices, free_offsets, i);

			FastIndexer j_indexer(usmalldims);
			for (int j = 0; j < thinU.cols(); ++j)
			{
				vector<int>& right_indices = j_indexer.GetNext();
			//	ComputeIndexArray(right_indices, usmall_offsets, j);
				vector<int> indices;
				VectorPlus::Concat(indices, left_indices, right_indices);
			//	Umat.Set(indices, rand_matrix.At(i,j));
				Umat.Set(indices, thinU(i,j));

				if (thinU.rows() == thinU.cols())
				{
					if (VectorPlus::Equals(left_indices, right_indices))
					{	
						Umat.Set(indices, 1);
					}
					else
					{
						Umat.Set(indices, 0);
					}
				}
			}
		}
	//	cout << "copy end 2 \n";	
	return true;
}