// findStartPoint: search for point with value of sign specified by positive-parameter
IsoSurfaceTest IsoSurfacePolygonizer::findStartPoint(bool positive, const Point3D &p) {
  IsoSurfaceTest result(p);
#define STEPCOUNT 200000
  const double step  = root(1000,STEPCOUNT); // multiply range by this STEPCOUNT times
                                              // range will end up with value 10000*cellSize
  double       range = m_cellSize;
  for(int i = 0; i < STEPCOUNT; i++) {
    result.x = p.x + randDouble(-range, range);
    result.y = p.y + randDouble(-range, range);
    result.z = p.z + randDouble(-range, range);
    result.setValue(evaluate(result));
    if(result.m_positive == positive) {
      return result;
    }
    range *= step; // slowly expand search outwards
  }
  result.m_ok = false;
  return result;
}
Exemple #2
0
void threadFunction(int threadNo, int numOperationsPerThread, double insertOperationsPercent,
                    std::function<void(const Key& key)> find, std::function<void(const Key& key)> insert) {

    std::default_random_engine generator(threadNo);
    std::uniform_int_distribution<std::uint16_t> randNum(0, KEY_FIELD_MAX_VALUE);
    std::uniform_real_distribution<double> randDouble(0.0f, 100.0f);

    for (int i = 0; i < numOperationsPerThread; i++) {
        std::uint16_t a = randNum(generator);
        std::uint16_t b = randNum(generator);
        std::uint16_t c = randNum(generator);
        Key key(a, b, c);
        if (randDouble(generator) < insertOperationsPercent) {
            insert(key);
        } else {
            find(key);
        }
    }

}
Exemple #3
0
double TpsRNG::randNormal(double mean, double stdev)
{
	double first,v1,v2,rsq,fac;
	
	if (!_save) {
		int again = 1;
		while (again) {
			v1 = 2.0*randDouble()-1.0;
			v2 = 2.0*randDouble()-1.0;
			rsq = v1*v1 + v2*v2;
			if (rsq < 1.0 && rsq != 0.0) 
				again = 0;
			}
			fac = sqrt(-2.0*log(rsq)/rsq);
			_second = v1*fac;
			first = v2*fac;
			_save = true;
	}
	else {
		first = _second;
		_save = false;
	}
	return (mean + first*stdev);
}
Exemple #4
0
/*!
  In phase 0, advance the rock's image and move the rock
  according to its current poisition and velocity.

  In phase 1, if the rock has been marked dead, then it
  has collided with the ship. Destroy the rock. Sometimes
  create a powerup in its place.
  \internal
 */
void KSmallRock::advance(int phase)
{
    if (!isDead()) {
	if (!phase) {
	    KRock::advanceImage();
	    KSprite::advance(phase);
	}
    }
    if (phase && (isDead() || dying())) {
        view_->reportRockDestroyed(10);
	if (!dying()) {
	    KPowerup* new_pup = KPowerup::create();
	    if (new_pup) {
		double r = (0.5 - randDouble()) * 4.0;
		new_pup->setPos(x(),y());
		new_pup->setVelocity(velocityX()+r,velocityY()+r);
		new_pup->show();
	    }
	}
	delete this; // Don't do anything after deleting me.
    }
}
bool PairwiseBiasMatrixFactorization::allocateOrCleanBaseMatrix(double*** ppBase, unsigned int rows, int cols, double init)
{
	unsigned int i;
	if(!(*ppBase))
	{
		(*ppBase) = new double*[rows]; 
		for(i = 0; i < rows; i++)
		{
 			(*ppBase)[i] = new double[cols];
		}
		assert(*ppBase);
	}


	//Init all values:
	for(i=0;i<rows;i++)
	{
		for(int j=0;j<cols;j++)
		  (*ppBase)[i][j] = randDouble(-init,init);
	}

	return true;
}
Exemple #6
0
void test7()
{
  matrix *m;
  PCAMODEL *model;

  int nobj = 200;
  int nvars = 32000;
  NewMatrix(&m, nobj, nvars);

  srand(nobj);
  for(size_t i = 0; i < nobj; i++){
    for(size_t j = 0; j < nvars; j++){
      m->data[i][j] = randDouble(0,20);
    }
  }

  NewPCAModel(&model);

  PCA(m, 1, 5, model, NULL);

  DelPCAModel(&model);
  DelMatrix(&m);
}
Exemple #7
0
unsigned long distribute_w_sa (unsigned long * dislikes, unsigned long * rooms, unsigned long nstudents, double t0) {
	
	unsigned long * assigned;
	unsigned long   cost;
	unsigned long   i, j;
	unsigned long   laststudent = nstudents - 1;
	unsigned long   max = nstudents * nstudents;
	unsigned long   p1;
	unsigned long   p2;
	unsigned long   r1;
	unsigned long   r2;
	unsigned long   sa;
	unsigned long   sb;
	unsigned long   s1;
	unsigned long   s2;
	unsigned long   s3;
	unsigned long   s4;
	long   dcost;

	double t = t0;


	assigned = (unsigned long *) malloc(nstudents * sizeof(unsigned long));
	if (!assigned)
	{
		fprintf(stderr, "Failed to allocate memory for the assigned vector!\n");
		fprintf(stderr, "\tERROR %d : %s\n", errno, strerror(errno));
		exit(errno);
	}
	
	cost = distribute_random(dislikes, rooms, assigned, nstudents);
	
	i = max;
	j = nstudents;

	while (cost && i && j) {
	// Find two students which are not roommates
		do
		{
			s1 = randomul_limited(0, laststudent);
			s2 = randomul_limited(0, laststudent);
		}
		while (assigned[s1] == assigned[s2]);

	// Find their roommates
		// Room of the first student
		r1 = assigned[s1];
		sa = rooms[r1 * 2    ];
		sb = rooms[r1 * 2 + 1];
		p1 = (s1 == sa);
		s3 = p1 ? sb : sa;

		// Room of the second student
		r2 = assigned[s2];
		sa = rooms[r2 * 2    ];
		sb = rooms[r2 * 2 + 1];
		p2 = (s2 == sa);
		s4 = p2 ? sb : sa;

	// Get the cost in swapping them
		dcost = dislikes[s1 * nstudents + s4]
		      + dislikes[s2 * nstudents + s3]
			  - dislikes[s1 * nstudents + s3]
			  - dislikes[s2 * nstudents + s4];	

		double r = randDouble();
		double f = (double) (- dcost) / (double) t;
		double e = exp(f);
		if (dcost < 0 || (e >= r)) {	
	// Swap the roommates
			assigned[s3] = r2;
			assigned[s4] = r1;
			rooms[r1 * 2 + p1] = s4;
			rooms[r2 * 2 + p2] = s3;
	// Update the total cost
			if (dcost) {
				cost += dcost;
				j = nstudents;
			} else
				--j;

			// since sometimes dcost is negative and |dcost| > cost, if such happens, assume the value should be zero and wrap up			
				if (cost && dcost < 0 && ((unsigned long)(- dcost)) > cost)
					cost = 0;			
			//Reset iterations
			i = max;
		}
		else {
			--i;
		}

		//cool the system
			t *= 0.999;
	}
	
	free(assigned);

	return cost;
}
Exemple #8
0
// Returns a pseudo-random number in the given range
double randRange(double mn, double mx)
{
    return (randDouble() * (mx - mn)) + mn;
}
void SplitFunctionImgPatch<BaseType, BaseTypeIntegral, AppContext>::SetRandomValues()
{
	// some initializations
	int min_w, min_h, max_w, max_h;
	int min_x, min_y, max_x, max_y;

    // if set, draw a random split function from the list
    // and set the member of SplitFunctionImgPatch
    if (m_appcontext->use_random_split_function){
        int num_available_split_functions = m_appcontext->split_function_type_list.size();
        this->m_splitfunction_type = m_appcontext->split_function_type_list[randInteger(0, num_available_split_functions-1)];
    } else {
        // use the default implementation
        this->m_splitfunction_type = m_appcontext->split_function_type;
    }

	// get some patch sub-regions
    switch (this->m_splitfunction_type){
	case SPLITFUNCTION_TYPE::SINGLEPIXELTEST:
		this->px1.x = randInteger(0, m_appcontext->patch_size[1]-1);
		this->px1.y = randInteger(0, m_appcontext->patch_size[0]-1);
		break;
	case SPLITFUNCTION_TYPE::PIXELPAIRTEST:
		this->px1.x = randInteger(0, m_appcontext->patch_size[1]-1);
		this->px1.y = randInteger(0, m_appcontext->patch_size[0]-1);
		this->px2.x = randInteger(0, m_appcontext->patch_size[1]-1);
		this->px2.y = randInteger(0, m_appcontext->patch_size[0]-1);
		break;
	case SPLITFUNCTION_TYPE::PIXELPAIRTESTCONDITIONED:
		this->px1.x = randInteger(0, m_appcontext->patch_size[1]-1);
		this->px1.y = randInteger(0, m_appcontext->patch_size[0]-1);
		int min_x, max_x, min_y, max_y;
		max_w = 10;
		min_x = max(0, px1.x - max_w);
		max_x = min(m_appcontext->patch_size[1]-1, px1.x + max_w);
		min_y = max(0, px1.y - max_w);
		max_y = min(m_appcontext->patch_size[0]-1, px1.y + max_w);
		this->px2.x = randInteger(min_x, max_x);
		this->px2.y = randInteger(min_y, max_y);
		break;
	case SPLITFUNCTION_TYPE::HAAR_LIKE:
		min_w = 1;
		min_h = 1;
		//max_w = static_cast<int>((double)m_appcontext->patch_size[1]*0.5);
		//max_h = static_cast<int>((double)m_appcontext->patch_size[0]*0.5);
		max_w = static_cast<int>((double)m_appcontext->patch_size[1]*0.90);
		max_h = static_cast<int>((double)m_appcontext->patch_size[0]*0.90);
		this->re1.width = randInteger(min_w, max_w);
		this->re1.height = randInteger(min_w, max_w);
		this->re1.x = randInteger(0, m_appcontext->patch_size[1]-re1.width);
		this->re1.y = randInteger(0, m_appcontext->patch_size[0]-re1.height);
		this->re2.width = randInteger(min_w, max_w);
		this->re2.height = randInteger(min_w, max_w);
		this->re2.x = randInteger(0, m_appcontext->patch_size[1]-re2.width);
		this->re2.y = randInteger(0, m_appcontext->patch_size[0]-re2.height);
		break;
	case SPLITFUNCTION_TYPE::ORDINAL:
//		this->pxs.resize(m_appcontext->ordinal_split_k);
//		for (size_t k = 0; k < pxs.size(); k++)
//		{
//			pxs[k].x = randInteger(0, m_appcontext->patch_size[1]-1);
//			pxs[k].y = randInteger(0, m_appcontext->patch_size[0]-1);
//		}
        // ORDINAL IS IMPLEMENTED HERE, BUT NOT IN GETRESPONSE?????
        throw std::logic_error("SplitFunction (set random value): Ordinal split functions not implemented yet!");
		break;
	default:
		throw std::runtime_error("SplitFunction: unknown split-type not implemented");
	}

	// define the feature channels
	this->ch1 = randInteger(0, m_appcontext->num_feature_channels-1);
	if (m_appcontext->split_channel_selection == 0)
		// use the same channel
		this->ch2 = this->ch1;
	else if (m_appcontext->split_channel_selection == 1)
		// use 2 random channels
		this->ch2 = randInteger(0, m_appcontext->num_feature_channels-1);
	else if (m_appcontext->split_channel_selection == 2)
	{
		// 50/50 chance of using same channel or using 2 random channels.
		if (randDouble() > 0.5)
			this->ch2 = this->ch1;
		else
			this->ch2 = randInteger(0, m_appcontext->num_feature_channels-1);
	}
	else
		throw std::runtime_error("SplitFunction: unknown channel-selection type");
}
Exemple #10
0
/*!
  \internal

  This function is called when a large rock or a medium rock
  is shattered by a missile. It is not called for small rocks.

  Destroy this rock because it was either hit by a missile
  fired by the ship, or it was hit by the ship itself while
  the ship's shield was up.

  If this rock is a large rock, remove it from the board and
  break it into 4 medium rocks. If this rock is a medium
  rock, remove it from the board and break it into four
  small rocks.

  An appropriate rockDestroyed signal is emitted so the game
  score can be updated.

  Additionally, a powerup might be created as a consequence
  of destroying the rock.
 */
void KRock::destroy()
{
    if (isSmallRock())
        return;
    /*
      Break large rocks into medium rocks and medium rocks
      into small rocks.
     */
    if (isLargeRock())
        view_->reportRockDestroyed(1);
    else if (isMediumRock())
        view_->reportRockDestroyed(5);

    static double x_multiplier[4] = { 1.0, 1.0, -1.0, -1.0 };
    static double y_multiplier[4] = { -1.0, 1.0, -1.0, 1.0 };

    double dx = velocityX() + velocityX() * 0.1;
    double dy = velocityY() + velocityY() * 0.1;

    double maxRockSpeed = ROCK_SPEED_MULTIPLIER * rockSpeed_;
    if (dx > maxRockSpeed)
	dx = maxRockSpeed;
    else if (dx < -maxRockSpeed)
	dx = -maxRockSpeed;
    if (dy > maxRockSpeed)
	dy = maxRockSpeed;
    else if (dy < -maxRockSpeed)
	dy = -maxRockSpeed;

    /*
      When the old rock explodes, we create four new, smaller
      rocks in its place. If the old rock is a large one, create
      four medium size rocks. If the old rock is a medium one,
      create four small ones. If the old rock is already small,
      we don't create anything. We don't even get into this loop
      if the old rock is small.
    */
    for (int i = 0; i < 4; i++) {
	double r = (rockSpeed_/2 - (randDouble() * rockSpeed_)) * 3.0;
	KRock* newRock = 0;
	if (isLargeRock())
	    newRock = new KMediumRock();
	else
	    newRock = new KSmallRock();

	/*
	  Each new rock is given an initial position which
	  is offset from the old rock's last position by the
	  width of one quadrant of the old rock's bounding box.
	  Each of the new rocks is positioned in a different
	  quadrant of the old rock's bounding box.
	*/
	qreal quadrant = newRock->boundingRect().width()/4;
	newRock->setPos(x() + (x_multiplier[i] * quadrant),
			y() + (y_multiplier[i] * quadrant));
	newRock->setVelocity(dx + (x_multiplier[i] * rockSpeed_) + r,
			     dy + (y_multiplier[i] * rockSpeed_) + r);
	newRock->setImage(randInt(ROCK_IMAGE_COUNT));
	newRock->show();
    }
    /*
      Note: This rock is actually deleted as the last
      statement of the caller. See KLargeRock::advance()
      and KMediumRock::advance().
    */
}
Exemple #11
0
double Motors::generate_unbound_time()
{
    double mean = 20.0;
    return -log(1 - randDouble(0, 1)) / mean;
}
bool SplitEvaluatorMLClass<Sample, TAppContext>::CalculateEntropyAndThreshold(DataSet<Sample, LabelMLClass>& dataset, std::vector<std::pair<double, int> > responses, std::pair<double, double>& score_and_threshold, int use_gini)
{
	// In: samples, sorted responses, out: optimality-measure + threshold

    // Initialize the counters
    double DGini, LGini, RGini, LTotal = 0.0, RTotal = 0.0, bestThreshold = 0.0, bestDGini = 1e16;
    vector<double> LCount(m_appcontext->num_classes, 0.0), RCount(m_appcontext->num_classes, 0.0);
    bool found = false;

    // Calculate random thresholds and sort them
    double min_response = responses[0].first;
    double max_response = responses[responses.size()-1].first;
    double d = (max_response - min_response);
    vector<double> random_thresholds(m_appcontext->num_node_thresholds, 0.0);
    for (int i = 0; i < random_thresholds.size(); i++)
    {
        random_thresholds[i] = (randDouble() * d) + min_response;
    }
    sort(random_thresholds.begin(), random_thresholds.end());

    // First, put everything in the right node
    for (int r = 0; r < responses.size(); r++)
    {
    	int labelIdx = dataset[responses[r].second]->m_label.class_label;
    	double sample_w = dataset[responses[r].second]->m_label.class_weight;

    	RCount[labelIdx] += sample_w;
        RTotal += sample_w;
    }

    // Now, iterate all responses and calculate Gini indices at the cutoff points (thresholds)
    int th_idx = 0;
    bool stop_search = false;
    for (int r = 0; r < responses.size(); r++)
    {
        // if the current sample is smaller than the current threshold put it to the left side
        if (responses[r].first <= random_thresholds[th_idx])
        {
            double cur_sample_weight = dataset[responses[r].second]->m_label.class_weight;

            RTotal -= cur_sample_weight;
            if (RTotal < 0.0)
            	RTotal = 0.0;
            LTotal += cur_sample_weight;
            int labelIdx = dataset[responses[r].second]->m_label.class_label;
            RCount[labelIdx] -= cur_sample_weight;
            if (RCount[labelIdx] < 0.0)
            	RCount[labelIdx] = 0.0;
            LCount[labelIdx] += cur_sample_weight;
        }
        else
        {
            // ok, now we found the first sample having higher response than the current threshold

            // now, we have to check the Gini index, this would be a valid split
            LGini = 0.0, RGini = 0.0;
            if (use_gini)
            {
                for (int c = 0; c < LCount.size(); c++)
                {
                    double pL = LCount[c]/LTotal, pR = RCount[c]/RTotal;
                    if (LCount[c] >= 1e-10) // F**K YOU rounding errors
                        LGini += pL * (1.0 - pL);
                    if (RCount[c] >= 1e-10)
                        RGini += pR * (1.0 - pR);
                }
            }
            else
            {
                for (int c = 0; c < LCount.size(); c++)
                {
                    double pL = LCount[c]/LTotal, pR = RCount[c]/RTotal;
                    if (LCount[c] >= 1e-10) // F**K YOU rounding errors
                        LGini -= pL * log(pL);
                    if (RCount[c] >= 1e-10)
                        RGini -= pR * log(pR);
                }
            }
            DGini = (LTotal*LGini + RTotal*RGini)/(LTotal + RTotal);

            if (DGini < bestDGini && LTotal > 0.0 && RTotal > 0.0)
            {
                bestDGini = DGini;
                bestThreshold = random_thresholds[th_idx];
                found = true;
            }

            // next, we have to find the next random threshold that is larger than the current response
            // -> there might be several threshold within the gap between the last response and this one.
            while (responses[r].first > random_thresholds[th_idx])
            {
                if (th_idx < (random_thresholds.size()-1))
                {
                    th_idx++;
                    // CAUTION::: THIS HAS TO BE INCLUDED !!!!!!!!!!!??????
                    r--; // THIS IS IMPORTANT, WE HAVE TO CHECK THE CURRENT SAMPLE AGAIN!!!
                }
                else
                {
                    stop_search = true;
                    break; // all thresholds tested
                }
            }
            // now, we can go on with the next response ...
        }

        if (stop_search)
            break;
    }

    score_and_threshold.first = bestDGini;
    score_and_threshold.second = bestThreshold;
    return found;
}
bool SplitEvaluatorMLClass<Sample, TAppContext>::CalculateSpecificLossAndThreshold(DataSet<Sample, LabelMLClass>& dataset, std::vector<std::pair<double, int> > responses, std::pair<double, double>& score_and_threshold)
{
	// In: samples, sorted responses, out:loss-value+threshold

    // 1) Calculate random thresholds and sort them
    double min_response = responses[0].first;
    double max_response = responses[responses.size()-1].first;
    double d = (max_response - min_response);
    vector<double> random_thresholds(m_appcontext->num_node_thresholds, 0.0);
    for (int i = 0; i < random_thresholds.size(); i++)
        random_thresholds[i] = (randDouble() * d) + min_response;
    sort(random_thresholds.begin(), random_thresholds.end());


    // Declare and init some variables
    vector<double> RClassWeights(m_appcontext->num_classes, 0.0);
    vector<double> LClassWeights(m_appcontext->num_classes, 0.0);
    vector<int> RSamples;
    vector<int> LSamples;
    double RTotalWeight = 0.0;
    double LTotalWeight = 0.0;
    double margin = 0.0;
    double RLoss = 0.0, LLoss = 0.0;
    double BestLoss = 1e16, CombinedLoss = 0.0, TotalWeight = 0.0, BestThreshold = 0.0;
    bool found = false;


    // First, put everything in the right node
    RSamples.resize(responses.size());
    for (int r = 0; r < responses.size(); r++)
    {
        int labelIdx = dataset[responses[r].second]->m_label.class_label;
        double sample_w = dataset[responses[r].second]->m_label.class_weight;

        RClassWeights[labelIdx] += sample_w;
        RTotalWeight += sample_w;
        RSamples[r] = responses[r].second;
    }

    // Now, iterate all responses and calculate Gini indices at the cutoff points (thresholds)
    int th_idx = 0;
    bool stop_search = false;
    for (int r = 0; r < responses.size(); r++)
    {
        // if the current sample is smaller than the current threshold put it to the left side
        if (responses[r].first <= random_thresholds[th_idx])
        {
            int labelIdx = dataset[responses[r].second]->m_label.class_label;
            double cur_sample_weight = dataset[responses[r].second]->m_label.class_weight;

            RClassWeights[labelIdx] -= cur_sample_weight;
            if (RClassWeights[labelIdx] < 0.0)
                RClassWeights[labelIdx] = 0.0;
            LClassWeights[labelIdx] += cur_sample_weight;

            RTotalWeight -= cur_sample_weight;
            if (RTotalWeight < 0.0)
                RTotalWeight = 0.0;
            LTotalWeight += cur_sample_weight;

            LSamples.push_back(RSamples[0]);
            RSamples.erase(RSamples.begin());
        }
        else
        {
            // ok, now we found the first sample having higher response than the current threshold

            // Reset the losses
            RLoss = 0.0, LLoss = 0.0;

            // calculate loss for left and right child nodes
            // RIGHT
			vector<double> pR(RClassWeights.size());
			for (int ci = 0; ci < RClassWeights.size(); ci++)
				pR[ci] = RClassWeights[ci] / RTotalWeight;
			for (int ci = 0; ci < RClassWeights.size(); ci++)
				RLoss += RClassWeights[ci] * ComputeLoss(pR, ci, m_appcontext->global_loss_classification);

            // LEFT
            vector<double> pL(LClassWeights.size());
			for (int ci = 0; ci < LClassWeights.size(); ci++)
				pL[ci] = LClassWeights[ci] / LTotalWeight;
			for (int ci = 0; ci < LClassWeights.size(); ci++)
				LLoss += LClassWeights[ci] * ComputeLoss(pL, ci, m_appcontext->global_loss_classification);

            // Total loss
            CombinedLoss = LLoss + RLoss;

            // best-search ...
            if (CombinedLoss < BestLoss && LTotalWeight > 0.0 && RTotalWeight > 0.0)
            {
                BestLoss = CombinedLoss;
                BestThreshold = random_thresholds[th_idx];
                found = true;
            }

            // next, we have to find the next random threshold that is larger than the current response
            // -> there might be several threshold within the gap between the last response and this one.
            while (responses[r].first > random_thresholds[th_idx])
            {
                if (th_idx < (random_thresholds.size()-1))
                {
                    th_idx++;
                    r--;
                }
                else
                {
                    stop_search = true;
                    break; // all thresholds tested
                }
            }
            // now, we can go on with the next response ...
        }
        if (stop_search)
            break;
    }

    score_and_threshold.first = BestLoss;
    score_and_threshold.second = BestThreshold;
    return found;
}
Exemple #14
0
double TpsRNG::randUniform(double min, double max)
{
	double range = max-min;
	return min + range*randDouble();
}
Exemple #15
0
/*!
  Create an exhaust sprite at position \a x, \a y with
  velocity \a dx, \a dy.
 */
KExhaust::KExhaust(double x, double y, double dx, double dy)
    : KAgingSprite(1)
{
    setPos(x + 2 - randDouble()*4, y + 2 - randDouble()*4);
    setVelocity(dx,dy);
}
bool SplitEvaluatorMLRegr<Sample>::CalculateMVNPluginAndThreshold(DataSet<Sample, LabelMLRegr>& dataset, std::vector<std::pair<double, int> > responses, std::pair<double,double>& score_and_threshold)
{
	// In: samples, sorted responses, out: optimality-measure + threshold

	// Initialize the variables and counters
	double InfoGain, LEntropy, REntropy, bestThreshold = 0.0, BestInfoGain = 1e16;
	double LTotal = 0.0, RTotal = 0.0, LSqNormTotal = 0.0, RSqNormTotal = 0.0;
	VectorXd RMean = VectorXd::Zero(m_appcontext->num_target_variables);
	VectorXd LMean = VectorXd::Zero(m_appcontext->num_target_variables);
	VectorXd RSum = VectorXd::Zero(m_appcontext->num_target_variables);
	VectorXd LSum = VectorXd::Zero(m_appcontext->num_target_variables);
	MatrixXd LCov = MatrixXd::Zero(m_appcontext->num_target_variables, m_appcontext->num_target_variables);
	MatrixXd RCov = MatrixXd::Zero(m_appcontext->num_target_variables, m_appcontext->num_target_variables);
	vector<int> RSamples, LSamples;
	bool found = false;

	// Calculate random thresholds and sort them
	double min_response = responses[0].first;
	double max_response = responses[responses.size()-1].first;
	double d = (max_response - min_response);
	vector<double> random_thresholds(m_appcontext->num_node_thresholds, 0.0);
	for (int i = 0; i < random_thresholds.size(); i++)
		random_thresholds[i] = (randDouble() * d) + min_response;
	sort(random_thresholds.begin(), random_thresholds.end());

	// First, put everything in the right node
	RSamples.resize(responses.size());
	for (int r = 0; r < responses.size(); r++)
	{
		double csw = dataset[responses[r].second]->m_weight;
		Eigen::VectorXd cst = dataset[responses[r].second]->m_label.regr_target;
		RSum += csw * cst;
		RTotal += csw;
		RSamples[r] = responses[r].second;
	}
	RMean = RSum / RTotal;

	// Now, iterate all responses and calculate Gini indices at the cutoff points (thresholds)
	int th_idx = 0;
	bool stop_search = false;
	for (int r = 0; r < responses.size(); r++)
	{
		// if the current sample is smaller than the current threshold put it to the left side
		if (responses[r].first <= random_thresholds[th_idx])
		{
			// move the current response from the right node to the left node
			double csw = dataset[responses[r].second]->m_weight;
			Eigen::VectorXd cst = dataset[responses[r].second]->m_label.regr_target;
			RSum -= csw * cst;
			RTotal -= csw;
			if (RTotal < 0.0)
				RTotal = 0.0;
			LSum += csw * cst;
			LTotal += csw;
			LSamples.push_back(RSamples[0]);
			RSamples.erase(RSamples.begin());
		}
		else
		{
			if (LTotal > 0.0 && RTotal > 0.0)
			{
				// RIGHT: Weighted mean
				RMean = RSum / RTotal;
				RCov = MatrixXd::Zero(m_appcontext->num_target_variables, m_appcontext->num_target_variables);
				RSqNormTotal = 0.0;
				for (int s = 0; s < RSamples.size(); s++)
				{
					Eigen::VectorXd cst = dataset[RSamples[s]]->m_label.regr_target;
					RCov += dataset[RSamples[s]]->m_weight * ((cst - RMean) * (cst - RMean).transpose());
					RSqNormTotal += pow(dataset[RSamples[s]]->m_weight/RTotal, 2.0);
				}
				RCov /= RTotal;
				if (RSqNormTotal < 1.0)
					RCov /= (1.0 - RSqNormTotal);
				double RCovDet = RCov.determinant();
				if (RCovDet <= 0.0)
					RCovDet = 1e-10;
				REntropy = log(RCovDet);
				if (REntropy <= 0.0)
					REntropy = 0.0;

				// LEFT: Weighted mean
				LMean = LSum / LTotal;

				// weighted co-variance
				LCov = MatrixXd::Zero(m_appcontext->num_target_variables, m_appcontext->num_target_variables);
				LSqNormTotal = 0.0;
				for (int s = 0; s < LSamples.size(); s++)
				{
					Eigen::VectorXd cst = dataset[LSamples[s]]->m_label.regr_target;
					LCov += dataset[LSamples[s]]->m_weight * ((cst - LMean) * (cst - LMean).transpose());
					LSqNormTotal += pow(dataset[LSamples[s]]->m_weight/LTotal, 2.0);
				}
				if (LSamples.size() == 0)
				{
					cout << LCov << endl;
					cout << LSqNormTotal << endl;
				}
				LCov /= LTotal;
				if (LSqNormTotal < 1.0)
					LCov /= (1.0 - LSqNormTotal);
				double LCovDet = LCov.determinant();
				if (LCovDet <= 0.0)
					LCovDet = 1e-10;
				LEntropy = log(LCovDet);
				if (LEntropy <= 0.0)
					LEntropy = 0.0;

				// combine left and right entropy measures (weighted!!!)
				InfoGain = (LTotal*LEntropy + RTotal*REntropy) / (LTotal + RTotal);

				if (this->m_appcontext->debug_on)
					cout << "Eval: " << InfoGain << ", LTotal=" << LTotal << ", RTotal=" << RTotal << "(" << LEntropy << ", " << REntropy << ")" << endl;

				if (InfoGain < BestInfoGain)
				{
					BestInfoGain = InfoGain;
					bestThreshold = random_thresholds[th_idx];
					found = true;
				}
			}

			// next, we have to find the next random threshold that is larger than the current response
			// -> there might be several threshold within the gap between the last response and this one.
			while (responses[r].first > random_thresholds[th_idx])
			{
				if (th_idx < (random_thresholds.size()-1))
				{
					th_idx++;
					r--;
				}
				else
				{
					stop_search = true;
					break;
				}
			}
			// now, we can go on with the next response ...
		}
		if (stop_search)
			break;
	}

	score_and_threshold.first = BestInfoGain;
	score_and_threshold.second = bestThreshold;
	return found;
}
Exemple #17
0
double randomizeAround(double value, double distance)
{
    return (value + randDouble(-(value * distance), (value * distance)));
}