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); }