[R] truly object oriented programming in R

Jason Liao jg_liao at yahoo.com
Thu Aug 12 17:28:18 CEST 2004


Good morning! I recently implemented a KD tree in JAVA for faster
kernel density estimation (part of the code follows). It went well. To
hook it with R, however, has proved more difficult. My question is: is
it possible to implement the algorithm in R? My impression seems to
indicate no as the code requires a complete class-object framework that
R does not support. But is there an R package or something that may
make it possible? Thanks in advance for your help.

Java implementation of KD tree:

public class Kdnode {
        	
        private double[] center; //center of the bounding box
        private double diameter; //maximum distance from center to
anywhere within the bounding box
        private int numOfPoints; //number of source data points in the
bounding box 
        
        private Kdnode left, right;

	
	public Kdnode(double[][] points, int split_dim, int [][]
sortedIndices, double[][] bBox) {
           //bBox: the bounding box, 1st row the lower bound, 2nd row
the upper bound 
                numOfPoints = points.length;
		int d = points[0].length;				
                
                center = new double[d];
                for(int j=0; j<d; j++) center[j] =
(bBox[0][j]+bBox[1][j])/2.;
                diameter = get_diameter(bBox);
                
		if(numOfPoints==1) {
                  diameter = 0.;
                  for(int j=0; j<d; j++) center[j] = points[0][j];
		  left = null;
		  right = null;	                  
		}
		else { 			  
                  int middlePoint =
sortedIndices[split_dim][numOfPoints/2];                      
		  double splitValue = points[middlePoint][split_dim];
                
                  middlePoint =
sortedIndices[split_dim][numOfPoints/2-1]; 
                  double splitValue_small =
points[middlePoint][split_dim]; 

		  int left_size = numOfPoints/2;
                  int right_size = numOfPoints - left_size;			

		  double[][] leftPoints = new double[left_size][d];
                  double[][] rightPoints = new double[right_size][d];		


		  int[][] leftSortedIndices = new int[d][left_size];				
		  int[][] rightSortedIndices = new int[d][right_size];
				
		  int left_counter = 0, right_counter = 0;				
		  int[] splitInfo = new int [numOfPoints];
				
		  for(int i = 0; i < numOfPoints; i++) {
		    if(points[i][split_dim] < splitValue) {
			for(int j=0; j<d; j++) leftPoints[left_counter][j] = points[i][j];
		       	splitInfo[i] = right_counter;
                        left_counter++;
                    }
		
		    else {
			for(int j=0; j<d; j++) rightPoints[right_counter][j] = points[i][j];
			splitInfo[i] = left_counter; 
                        right_counter++;
                    }
                  }
			// modify appropriately the indices to correspond to the new lists
			for(int i = 0; i < d; i++) {
				int left_index = 0, right_index = 0;
				for(int j = 0; j < numOfPoints; j++) {
					if(points[sortedIndices[i][j]][split_dim] < splitValue) 
						leftSortedIndices[i][left_index++] = sortedIndices[i][j] -
splitInfo[sortedIndices[i][j]];					
					else    rightSortedIndices[i][right_index++] = sortedIndices[i][j]
- splitInfo[sortedIndices[i][j]];
                                }				
			}
			
			// Recursively compute the kdnodes for the points in the two
splitted spaces			                        
			double[][] leftBBox = new double[2][];
			double[][] rightBBox = new double[2][];      
                        
                        for(int i=0; i<2; i++) {
                                leftBBox[i] =
(double[])bBox[i].clone();
                                rightBBox[i] =
(double[])bBox[i].clone();                              
                            }
                        
                        leftBBox[1][split_dim] = splitValue_small;
                        rightBBox[0][split_dim] = splitValue; 
			
                        int next_dim = (split_dim + 1) % (d);
			left = new Kdnode(leftPoints, next_dim, leftSortedIndices,
leftBBox);			
			right = new Kdnode(rightPoints, next_dim, rightSortedIndices,
rightBBox);
		}
	}
	
      
        public double evaluate(double[] target, double delta, double
bandwidth) throws Exception
        {         
            
             double dis_2_center = Common.distance(target,
center)/bandwidth;
             double dm = diameter/bandwidth;                       
             
             if(dis_2_center >= 1+dm) return 0.; 
             if(numOfPoints==1) return Common.K(dis_2_center);
             
             /*if(dis_2_center<1) 
             {
                 double temp2 = dm*Common.KDeriv(dis_2_center);  
                 if(temp2<delta) return
Common.K(dis_2_center)*numOfPoints;
             } */
                          
             return left.evaluate(target,delta, bandwidth) +
right.evaluate(target,delta, bandwidth); 
        }    
        
                 
         public double get_diameter(double[][] bBox)
        {
            double value = 0., diff;
            for (int i=0; i<bBox[0].length;i++)
            {
                diff = (bBox[1][i] - bBox[0][i])/2.;
                value += diff*diff;
            }
            return Math.sqrt(value);
        }       
}

=====
Jason Liao, http://www.geocities.com/jg_liao
Dept. of Biostatistics, http://www2.umdnj.edu/bmtrxweb
University of Medicine and Dentistry of New Jersey
phone 732-235-5429, School of Public Health office
phone 732-235-8611, Cancer Institute of New Jersey office
moble phone 908-720-4205




More information about the R-help mailing list