Example #1
0
SparseWeightMatrix klle_weight_matrix(RandomAccessIterator begin, RandomAccessIterator end, 
                                      const Neighbors& neighbors, PairwiseCallback callback, DefaultScalarType shift)
{
	timed_context context("KLLE weight computation");
	const unsigned int k = neighbors[0].size();

	SparseTriplets sparse_triplets;
	sparse_triplets.reserve((k*k+2*k+1)*(end-begin));

	RandomAccessIterator iter;
	RandomAccessIterator iter_begin = begin, iter_end = end;
	DenseMatrix gram_matrix = DenseMatrix::Zero(k,k);
	DenseVector dots(k);
	DenseVector rhs = DenseVector::Ones(k);
	DenseVector weights;
	for (RandomAccessIterator iter=iter_begin; iter!=iter_end; ++iter)
	{
		DefaultScalarType kernel_value = callback(*iter,*iter);
		const LocalNeighbors& current_neighbors = neighbors[iter-begin];
		
		for (unsigned int i=0; i<k; ++i)
			dots[i] = callback(*iter, begin[current_neighbors[i]]);

		for (unsigned int i=0; i<k; ++i)
		{
			for (unsigned int j=i; j<k; ++j)
				gram_matrix(i,j) = kernel_value - dots(i) - dots(j) + callback(begin[current_neighbors[i]],begin[current_neighbors[j]]);
		}
		
		DefaultScalarType trace = gram_matrix.trace();
		gram_matrix.diagonal().array() += 1e-3*trace;
		weights = gram_matrix.selfadjointView<Eigen::Upper>().ldlt().solve(rhs);
		weights /= weights.sum();

		sparse_triplets.push_back(SparseTriplet(iter-begin,iter-begin,1.0+shift));
		for (unsigned int i=0; i<k; ++i)
		{
			sparse_triplets.push_back(SparseTriplet(current_neighbors[i],iter-begin,
			                                        -weights[i]));
			sparse_triplets.push_back(SparseTriplet(iter-begin,current_neighbors[i],
			                                        -weights[i]));
			for (unsigned int j=0; j<k; ++j)
				sparse_triplets.push_back(SparseTriplet(current_neighbors[i],current_neighbors[j],
				                                        +weights(i)*weights(j)));
		}
	}

	SparseWeightMatrix weight_matrix(end-begin,end-begin);
	weight_matrix.setFromTriplets(sparse_triplets.begin(),sparse_triplets.end());

	return weight_matrix;
}
SparseWeightMatrix linear_weight_matrix(const RandomAccessIterator& begin, const RandomAccessIterator& end,
                                        const Neighbors& neighbors, PairwiseCallback callback,
                                        const ScalarType shift, const ScalarType trace_shift)
{
	timed_context context("KLLE weight computation");
	const IndexType k = neighbors[0].size();

	SparseTriplets sparse_triplets;
	sparse_triplets.reserve((k*k+2*k+1)*(end-begin));

#pragma omp parallel shared(begin,end,neighbors,callback,sparse_triplets) default(none)
	{
		IndexType index_iter;
		DenseMatrix gram_matrix = DenseMatrix::Zero(k,k);
		DenseVector dots(k);
		DenseVector rhs = DenseVector::Ones(k);
		DenseVector weights;
		SparseTriplets local_triplets;
		local_triplets.reserve(k*k+2*k+1);

		//RESTRICT_ALLOC;
#pragma omp for nowait
		for (index_iter=0; index_iter<static_cast<IndexType>(end-begin); index_iter++)
		{
			ScalarType kernel_value = callback.kernel(begin[index_iter],begin[index_iter]);
			const LocalNeighbors& current_neighbors = neighbors[index_iter];

			for (IndexType i=0; i<k; ++i)
				dots[i] = callback.kernel(begin[index_iter], begin[current_neighbors[i]]);

			for (IndexType i=0; i<k; ++i)
			{
				for (IndexType j=i; j<k; ++j)
					gram_matrix(i,j) = kernel_value - dots(i) - dots(j) +
					                   callback.kernel(begin[current_neighbors[i]],begin[current_neighbors[j]]);
			}

			ScalarType trace = gram_matrix.trace();
			gram_matrix.diagonal().array() += trace_shift*trace;
			weights = gram_matrix.selfadjointView<Eigen::Upper>().ldlt().solve(rhs);
			weights /= weights.sum();

			SparseTriplet diagonal_triplet(index_iter,index_iter,1.0+shift);
			local_triplets.push_back(diagonal_triplet);
			for (IndexType i=0; i<k; ++i)
			{
				SparseTriplet row_side_triplet(current_neighbors[i],index_iter,-weights[i]);
				SparseTriplet col_side_triplet(index_iter,current_neighbors[i],-weights[i]);
				local_triplets.push_back(row_side_triplet);
				local_triplets.push_back(col_side_triplet);
				for (IndexType j=0; j<k; ++j)
				{
					SparseTriplet cross_triplet(current_neighbors[i],current_neighbors[j],weights(i)*weights(j));
					local_triplets.push_back(cross_triplet);
				}
			}

#pragma omp critical
			{
				copy(local_triplets.begin(),local_triplets.end(),back_inserter(sparse_triplets));
			}

			local_triplets.clear();
		}
		//UNRESTRICT_ALLOC;
	}

	return sparse_matrix_from_triplets(sparse_triplets, end-begin, end-begin);
}