Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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;
}