private double [] calculateRegionProbs(int j, int i) throws Exception {
    double [] sumOfProbsForRegion = 
      new double [m_trainingData.classAttribute().numValues()];

    for (int u = 0; u < m_numOfSamplesPerRegion; u++) {
      
      double [] sumOfProbsForLocation = 
	new double [m_trainingData.classAttribute().numValues()];
      
      m_weightingAttsValues[m_xAttribute] = getRandomX(j);
      m_weightingAttsValues[m_yAttribute] = getRandomY(m_panelHeight-i-1);
      
      m_dataGenerator.setWeightingValues(m_weightingAttsValues);
      
      double [] weights = m_dataGenerator.getWeights();
      double sumOfWeights = Utils.sum(weights);
      int [] indices = Utils.sort(weights);
      
      // Prune 1% of weight mass
      int [] newIndices = new int[indices.length];
      double sumSoFar = 0; 
      double criticalMass = 0.99 * sumOfWeights;
      int index = weights.length - 1; int counter = 0;
      for (int z = weights.length - 1; z >= 0; z--) {
	newIndices[index--] = indices[z];
	sumSoFar += weights[indices[z]];
	counter++;
	if (sumSoFar > criticalMass) {
	  break;
	}
      }
      indices = new int[counter];
      System.arraycopy(newIndices, index + 1, indices, 0, counter);
      
      for (int z = 0; z < m_numOfSamplesPerGenerator; z++) {
        
	m_dataGenerator.setWeightingValues(m_weightingAttsValues);
	double [][] values = m_dataGenerator.generateInstances(indices);
        
	for (int q = 0; q < values.length; q++) {
	  if (values[q] != null) {
	    System.arraycopy(values[q], 0, m_vals, 0, m_vals.length);
	    m_vals[m_xAttribute] = m_weightingAttsValues[m_xAttribute];
	    m_vals[m_yAttribute] = m_weightingAttsValues[m_yAttribute];
            
	    // classify the instance
	    m_dist = m_classifier.distributionForInstance(m_predInst);

	    for (int k = 0; k < sumOfProbsForLocation.length; k++) {
	      sumOfProbsForLocation[k] += (m_dist[k] * weights[q]); 
	    }
	  }
	}
      }
      
      for (int k = 0; k < sumOfProbsForRegion.length; k++) {
	sumOfProbsForRegion[k] += (sumOfProbsForLocation[k] * sumOfWeights); 
      }
    }
    
    // average
    Utils.normalize(sumOfProbsForRegion);

    // cache
    double [] tempDist = new double[sumOfProbsForRegion.length];
    System.arraycopy(sumOfProbsForRegion, 0, tempDist, 
		     0, sumOfProbsForRegion.length);
		
    return tempDist;
  }