Пример #1
0
inline double KDERules<MetricType, KernelType, TreeType>::
Score(const size_t queryIndex, TreeType& referenceNode)
{
  double score, maxKernel, minKernel, bound;
  const arma::vec& queryPoint = querySet.unsafe_col(queryIndex);
  const double minDistance = referenceNode.MinDistance(queryPoint);
  bool newCalculations = true;

  if (tree::TreeTraits<TreeType>::FirstPointIsCentroid &&
      lastQueryIndex == queryIndex &&
      traversalInfo.LastReferenceNode() != NULL &&
      traversalInfo.LastReferenceNode()->Point(0) == referenceNode.Point(0))
  {
    // Don't duplicate calculations.
    newCalculations = false;
    lastQueryIndex = queryIndex;
    lastReferenceIndex = referenceNode.Point(0);
  }
  else
  {
    // Calculations are new.
    maxKernel = kernel.Evaluate(minDistance);
    minKernel = kernel.Evaluate(referenceNode.MaxDistance(queryPoint));
    bound = maxKernel - minKernel;
  }

  if (newCalculations &&
      bound <= (absError + relError * minKernel) / referenceSet.n_cols)
  {
    // Estimate values.
    double kernelValue;

    // Calculate kernel value based on reference node centroid.
    if (tree::TreeTraits<TreeType>::FirstPointIsCentroid)
    {
      kernelValue = EvaluateKernel(queryIndex, referenceNode.Point(0));
    }
    else
    {
      kde::KDEStat& referenceStat = referenceNode.Stat();
      kernelValue = EvaluateKernel(queryPoint, referenceStat.Centroid());
    }

    densities(queryIndex) += referenceNode.NumDescendants() * kernelValue;

    // Don't explore this tree branch.
    score = DBL_MAX;
  }
  else
  {
    score = minDistance;
  }

  ++scores;
  traversalInfo.LastReferenceNode() = &referenceNode;
  traversalInfo.LastScore() = score;
  return score;
}
Пример #2
0
inline force_inline double KDERules<MetricType, KernelType, TreeType>::
EvaluateKernel(const size_t queryIndex,
               const size_t referenceIndex) const
{
  return EvaluateKernel(querySet.unsafe_col(queryIndex),
                        referenceSet.unsafe_col(referenceIndex));
}
Пример #3
0
/*
 * Function: EvaluateKernelCell
 * -------------------------------------------------------------------
 * Evaluates the kernel for interactions between a pair of cells.
 * M2L operator initialization
 */
void H2_3D_Tree::EvaluateKernelCell(vector3 *field, vector3 *source, int Nf,
                        int Ns, doft *dof, double *kernel) {
	int i, j, k, l, count, count_kernel;
	int dof_f = dof->f;
	int dof_s = dof->s;
	int dofNf = dof->f * Nf;
	int dof2  = dof->f * dof->s;
	double * Kij;
	
	int LDA_kernel = dofNf;
	
	Kij = (double*) malloc(dof2 * sizeof(double));
	
	for (j=0;j<Ns;j++) {
		for (i=0;i<Nf;i++) {
            EvaluateKernel(field[i],source[j],Kij, dof);
			
			count_kernel = dof_f * i + LDA_kernel * dof_s * j;
			count = 0;
			for (k=0;k<dof_s;k++)
				for (l=0;l<dof_f;l++, count++)
                /* Column-major storage */
					kernel[count_kernel + k * LDA_kernel + l] = Kij[count];
		}
	}
    
	free(Kij);
}
Пример #4
0
inline double KDERules<MetricType, KernelType, TreeType>::
Score(TreeType& queryNode, TreeType& referenceNode)
{
  double score, maxKernel, minKernel, bound;
  const double minDistance = queryNode.MinDistance(referenceNode);
  // Calculations are not duplicated.
  bool newCalculations = true;

  if (tree::TreeTraits<TreeType>::FirstPointIsCentroid &&
      (traversalInfo.LastQueryNode() != NULL) &&
      (traversalInfo.LastReferenceNode() != NULL) &&
      (traversalInfo.LastQueryNode()->Point(0) == queryNode.Point(0)) &&
      (traversalInfo.LastReferenceNode()->Point(0) == referenceNode.Point(0)))
  {
    // Don't duplicate calculations.
    newCalculations = false;
    lastQueryIndex = queryNode.Point(0);
    lastReferenceIndex = referenceNode.Point(0);
  }
  else
  {
    // Calculations are new.
    maxKernel = kernel.Evaluate(minDistance);
    minKernel = kernel.Evaluate(queryNode.MaxDistance(referenceNode));
    bound = maxKernel - minKernel;
  }

  // If possible, avoid some calculations because of the error tolerance.
  if (newCalculations &&
      bound <= (absError + relError * minKernel) / referenceSet.n_cols)
  {
    // Auxiliary variables.
    double kernelValue;
    kde::KDEStat& referenceStat = referenceNode.Stat();
    kde::KDEStat& queryStat = queryNode.Stat();

    // If calculating a center is not required.
    if (tree::TreeTraits<TreeType>::FirstPointIsCentroid)
    {
      kernelValue = EvaluateKernel(queryNode.Point(0), referenceNode.Point(0));
    }
    // Sadly, we have no choice but to calculate the center.
    else
    {
      kernelValue = EvaluateKernel(queryStat.Centroid(),
                                   referenceStat.Centroid());
    }

    // Sum up estimations.
    for (size_t i = 0; i < queryNode.NumDescendants(); ++i)
    {
      densities(queryNode.Descendant(i)) +=
          referenceNode.NumDescendants() * kernelValue;
    }
    score = DBL_MAX;
  }
  else
  {
    score = minDistance;
  }

  ++scores;
  traversalInfo.LastQueryNode() = &queryNode;
  traversalInfo.LastReferenceNode() = &referenceNode;
  traversalInfo.LastScore() = score;
  return score;
}
Пример #5
0
/*
 * Function: ComputeKernelUniformGrid
 * ------------------------------------------------------------------
 * Computes the kernel for 316(2n-1)^3 interactions between Uniform
 * Grid nodes. Does not compute SVD.
 */
void H2_3D_Tree::ComputeKernelUniformGrid(double *Kweights, int n, doft *dof, char *Kmat, double alphaAdjust, rfftw_plan p_r2c) {
    
    /* TODO: multi-dof, alphaAdjust */
    
    int i, k1, k2, k3, l1, l2, l3;
    vector3 scenter;
    
    int dof2 = dof->s * dof->f;
    //int dof2n6 = dof2 * (2*n-1)*(2*n-1)*(2*n-1); // Total size
    
    double nodes[n], kernel[dof2];
    vector3 fieldpos, sourcepos;
    
    
    // Compute Chebyshev nodes of T_n(x)
    //double scale = 1+alphaAdjust;
    CalculateNodeLocations(n,nodes,0);
    
    // creat FFT plan
    int vecSize = 2*n-1, reducedMatSize = pow(vecSize, 3);
    int M2LSize = dof2 *reducedMatSize;
    double *MatM2L  = (double*)malloc(M2LSize *sizeof(double));
    double *freqMat = (double*)malloc(316 *M2LSize *sizeof(double));
    
    // Compute the kernel values for interactions with all 316 cells
    int countM2L=0, count, count1;
    int shift1, shift2, shiftGlo, shiftLoc;
    int reducedMatSizeDofs = reducedMatSize *dof->s;
    int f, s;
    
    for (k1=-3;k1<4;k1++) {
        scenter.x = (double)k1;
        for (k2=-3;k2<4;k2++) {
            scenter.y = (double)k2;
            for (k3=-3;k3<4;k3++) {
                scenter.z = (double)k3;
                if (abs(k1) > 1 || abs(k2) > 1 || abs(k3) > 1) {
                    
                    for (count=0, l1=0; l1<vecSize; l1++) {
                        GetPosition(n, l1, &fieldpos.x, &sourcepos.x, nodes);
                        sourcepos.x += scenter.x;
                        for (l2=0; l2<vecSize; l2++) {
                            GetPosition(n, l2, &fieldpos.y, &sourcepos.y, nodes);
                            sourcepos.y += scenter.y;
                            for (l3=0; l3<vecSize; l3++, count++) {
                                GetPosition(n, l3, &fieldpos.z, &sourcepos.z, nodes);
                                sourcepos.z += scenter.z;
                                
                                EvaluateKernel(fieldpos,sourcepos,kernel,dof);
                                
                                // kernel[f x s] in column major
                                // MatM2L[(2n-1)^3 x s x f] in column
                                // major
                                count1 = 0;
                                shift1 = count;
                                for (s=0; s < dof->s; s++) {
                                    for(f=0, shift2=0; f < dof->f; f++) {
                                        MatM2L[shift1 + shift2] =  kernel[count1++];
                                        shift2 += reducedMatSizeDofs;
                                    }
                                    shift1 += reducedMatSize;
                                }
                            }
                        }
                    }
                    
                    // FFT
                    shiftGlo = countM2L *M2LSize;
                    
                    for (i=0, shiftLoc=0; i<dof2; i++) {
                        rfftw_one(p_r2c, MatM2L + shiftLoc, freqMat +
                                  shiftGlo + shiftLoc);
                        shiftLoc += reducedMatSize;
                    }
                    
                
                    
                    countM2L++;
                }
            }
        }
    }
    	
    FILE *ptr_file;
    ptr_file = fopen(Kmat, "wb");
    fwrite(freqMat, sizeof(double),316 *M2LSize, ptr_file);
    fclose(ptr_file);
    
    free(MatM2L);
    free(freqMat);
    
}