SparseWeightMatrix hessian_weight_matrix(RandomAccessIterator begin, RandomAccessIterator end, const Neighbors& neighbors, PairwiseCallback callback, const IndexType target_dimension) { timed_context context("Hessian weight matrix computation"); const IndexType k = neighbors[0].size(); SparseTriplets sparse_triplets; sparse_triplets.reserve(k*k*(end-begin)); const IndexType dp = target_dimension*(target_dimension+1)/2; #pragma omp parallel shared(begin,end,neighbors,callback,sparse_triplets) default(none) { IndexType index_iter; DenseMatrix gram_matrix = DenseMatrix::Zero(k,k); DenseMatrix Yi(k,1+target_dimension+dp); SparseTriplets local_triplets; local_triplets.reserve(k*k+2*k+1); #pragma omp for nowait for (index_iter=0; index_iter<static_cast<IndexType>(end-begin); index_iter++) { const LocalNeighbors& current_neighbors = neighbors[index_iter]; for (IndexType i=0; i<k; ++i) { for (IndexType j=i; j<k; ++j) { ScalarType kij = callback.kernel(begin[current_neighbors[i]],begin[current_neighbors[j]]); gram_matrix(i,j) = kij; gram_matrix(j,i) = kij; } } centerMatrix(gram_matrix); DenseSelfAdjointEigenSolver sae_solver; sae_solver.compute(gram_matrix); Yi.col(0).setConstant(1.0); Yi.block(0,1,k,target_dimension).noalias() = sae_solver.eigenvectors().rightCols(target_dimension); IndexType ct = 0; for (IndexType j=0; j<target_dimension; ++j) { for (IndexType p=0; p<target_dimension-j; ++p) { Yi.col(ct+p+1+target_dimension).noalias() = Yi.col(j+1).cwiseProduct(Yi.col(j+p+1)); } ct += ct + target_dimension - j; } for (IndexType i=0; i<static_cast<IndexType>(Yi.cols()); i++) { for (IndexType j=0; j<i; j++) { ScalarType r = Yi.col(i).dot(Yi.col(j)); Yi.col(i) -= r*Yi.col(j); } ScalarType norm = Yi.col(i).norm(); Yi.col(i) *= (1.f / norm); } for (IndexType i=0; i<dp; i++) { ScalarType colsum = Yi.col(1+target_dimension+i).sum(); if (colsum > 1e-4) Yi.col(1+target_dimension+i).array() /= colsum; } // reuse gram matrix storage m'kay? gram_matrix.noalias() = Yi.rightCols(dp)*(Yi.rightCols(dp).transpose()); for (IndexType i=0; i<k; ++i) { for (IndexType j=0; j<k; ++j) { SparseTriplet hessian_triplet(current_neighbors[i],current_neighbors[j],gram_matrix(i,j)); local_triplets.push_back(hessian_triplet); } } #pragma omp critical { copy(local_triplets.begin(),local_triplets.end(),back_inserter(sparse_triplets)); } local_triplets.clear(); } } return sparse_matrix_from_triplets(sparse_triplets, end-begin, end-begin); }
Bool_t TZigZag::PointsNear(Double_t x, Double_t y, Double_t &yi, TArrayD &Tn, TArrayD &Yn) const { // Two-dimensional case. Finds in I,T,X,Y the 4 points of the grid around point (x,y). //Then finds the 2 closest points along the zigzag in In,Tn,Xn,Yn. // If point (x,y) not inside [fXmin,fXmax] and [fYmin,fYmax], make a projection //towards center and stops at point just after entry and gives the 4 points for it. const Double_t un = 1.0; const Double_t aeps = 1.0e-6; TArrayI Ii(4); TArrayD Ti(4); TArrayD Xi(4); TArrayD Yi(4); Bool_t ok; Int_t i; Int_t kx=0; Int_t ky=0; Double_t mx,my,eps; Double_t xc,xl,xr,dx,dxs2; Double_t yc,yl,yr,dy,dys2; Double_t xi,xp,yp; Double_t xle,xre,yle,yre; Tn.Set(2); Yn.Set(2); dx = (fXmax-fXmin)/fNx; dxs2 = dx/2; dy = (fYmax-fYmin)/fNy; dys2 = dy/2; xl = dxs2; xr = dxs2 + (fNx-1)*dx; yl = dys2; yr = dys2 + (fNy-1)*dy; if ((yr-yl) > (xr-xl)) eps = aeps*(yr-yl); else eps = aeps*(xr-xl); xle = xl + eps; xre = xr - eps; yle = yl + eps; yre = yr - eps; if ((x>=xle) && (x<=xre) && (y>=yle) && (y<=yre)) { xi = x; yi = y; kx = Int_t((xi-dxs2)/dx) + 1; ky = Int_t((yi-dys2)/dy) + 1; ok = kTRUE; }//end if ((x>xl) && (x<xr) && (y>yl) && (y<yr)) else { xc = (fXmax-fXmin)/2; yc = (fYmax-fYmin)/2; mx = (y-yc)/(x-xc); my = un/mx; xi = xle; yi = yc + mx*(xi-xc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); if (!ok) { xi = xre; yi = yc + mx*(xi-xc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); if (!ok) { yi = yle; xi = xc + my*(yi-yc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); if (!ok) { yi = yre; xi = xc + my*(yi-yc); ok = IsInside(xi,yi,x,y,xc,yc,xl,xr,yl,yr); }//end if (!ok) }//end if (!ok) }//end if (!ok) if (ok) { kx = Int_t((xi-dxs2)/dx) + 1; ky = Int_t((yi-dys2)/dy) + 1; } else { cout << "TZigZag::PointsNear : ERROR point inside not found" << endl; } }//end else if ((x>xl) && (x<xr) && (y>yl) && (y<yr)) if (ok) { //Point kx,ky xp = dxs2 + (kx-1)*dx; yp = dys2 + (ky-1)*dy; i = NToZZ(kx,ky); Ii[0] = i; Ti[0] = T(i); Xi[0] = xp; Yi[0] = yp; //Point kx+1,ky xp = dxs2 + kx*dx; yp = dys2 + (ky-1)*dy; i = NToZZ(kx+1,ky); Ii[1] = i; Ti[1] = T(i); Xi[1] = xp; Yi[1] = yp; //Point kx,ky+1 xp = dxs2 + (kx-1)*dx; yp = dys2 + ky*dy; i = NToZZ(kx,ky+1); Ii[2] = i; Ti[2] = T(i); Xi[2] = xp; Yi[2] = yp; //Point kx+1,ky+1 xp = dxs2 + kx*dx; yp = dys2 + ky*dy; i = NToZZ(kx+1,ky+1); Ii[3] = i; Ti[3] = T(i); Xi[3] = xp; Yi[3] = yp; //Finding the 2 points along the zigzag Order(4,Ii,Ti,Xi,Yi); Yn[0] = Yi[0]; Tn[0] = Ti[0] + ((Ti[1] - Ti[0])/(Xi[1] -Xi[0]))*(xi - Xi[0]); Yn[1] = Yi[2]; Tn[1] = Ti[2] + ((Ti[3] - Ti[2])/(Xi[3] -Xi[2]))*(xi - Xi[2]); } return ok; }