<commit_before>#include <cmath>
#include <iostream>
#include <iomanip>
#include "RandomNumberGenerator.h"
#include "Utils.h"

template<class Distribution>
RJObject<Distribution>::RJObject(int num_dimensions, int max_num_components, bool fixed,
				const Distribution& dist)
:num_dimensions(num_dimensions)
,max_num_components(max_num_components)
,fixed(fixed)
,dist(dist)
,num_components((fixed)?(max_num_components):(0))
{

}

template<class Distribution>
void RJObject<Distribution>::fromPrior()
{
	// Generate the hyperparameters from their prior
	dist.fromPrior();

	// Generate from {0, 1, 2, ..., max_num_components}
	if(!fixed)
		num_components = DNest3::randInt(max_num_components + 1);

	// Resize the vectors of component properties
	components.resize  (num_components, std::vector<double>(num_dimensions));
	u_components.resize(num_components, std::vector<double>(num_dimensions));

	// Generate components
	for(int i=0; i<num_components; i++)
	{
		for(int j=0; j<num_dimensions; j++)
		{
			u_components[i][j] = DNest3::randomU();
			components  [i][j] = u_components[i][j];
		}
		dist.from_uniform(components[i]);
	}
}

template<class Distribution>
double RJObject<Distribution>::perturb_components(double chance, double scale)
{
	if(num_components == 0)
		return 0.;

	// A flag for whether each component gets changed or not
	std::vector<bool> change(num_components, false);
	int count = 0;
	for(int i=0; i<num_components; i++)
	{
		if(DNest3::randomU() <= chance)
		{
			change[i] = true;
			count++;
		}
	}
	// At least do one...
	if(count == 0)
		change[DNest3::randInt(num_components)] = true;

	for(int i=0; i<num_components; i++)
	{
		if(change[i])
		{
			// Perturb
			for(int j=0; j<num_dimensions; j++)
			{
				u_components[i][j] += scale*DNest3::randn();
				u_components[i][j] = DNest3::mod(
							u_components[i][j], 1.);
				components[i][j] = u_components[i][j];
			}
			dist.from_uniform(components[i]);
		}
	}

	return 0.;
}

template<class Distribution>
double RJObject<Distribution>::add_component()
{
	if(num_components >= max_num_components)
	{
		std::cerr<<"# WARNING: Trying to add component ";
		std::cerr<<"but already full!"<<std::endl;
		return 0.;
	}

	// Increment counter
	num_components++;

	// Generate component
	std::vector<double> component(num_dimensions);
	for(int j=0; j<num_dimensions; j++)
		component[j] = DNest3::randomU();
	u_components.push_back(component);
	dist.from_uniform(component);
	components.push_back(component);

	return 0.;
}

template<class Distribution>
double RJObject<Distribution>::perturb_num_components(double scale)
{
	double logH = 0.;

	// Work out how many components we will have after the change
	double delta = max_num_components*scale*DNest3::randn();
	int diff = (int)floor(delta);
	// In case diff is zero, make it + 1
	if(diff == 0)
	{
		if(DNest3::randomU() <= 0.5)
			diff = -1;
		else
			diff =  1;
	}
	int new_num_components = DNest3::mod(num_components + diff, max_num_components + 1);
	diff = new_num_components - num_components;

	// Now do the required changes
	if(diff > 0)
	{
		for(int i=0; i<diff; i++)
			logH += add_component();
	}
	else
	{
		for(int i=0; i<-diff; i++)
			logH += remove_component();
	}

	return logH;
}

template<class Distribution>
double RJObject<Distribution>::perturb()
{
	double logH = 0.;

	int which = (fixed)?(1 + DNest3::randInt(2)):(DNest3::randInt(3));

	if(which == 0)
	{
		// Do some birth or death
		logH += perturb_num_components(
				pow(10., 1.5 - 6.*DNest3::randomU()));
	}
	else if(which == 1)
	{
		// Change the hyperparameters
		if(DNest3::randomU() <= 0.5)
			logH += dist.perturb1(components, u_components);
		else
			logH += dist.perturb2(components, u_components);
	}
	else if(which == 2)<commit_msg>Renamed diff --> difference<commit_after>#include <cmath>
#include <iostream>
#include <iomanip>
#include "RandomNumberGenerator.h"
#include "Utils.h"

template<class Distribution>
RJObject<Distribution>::RJObject(int num_dimensions, int max_num_components, bool fixed,
				const Distribution& dist)
:num_dimensions(num_dimensions)
,max_num_components(max_num_components)
,fixed(fixed)
,dist(dist)
,num_components((fixed)?(max_num_components):(0))
{

}

template<class Distribution>
void RJObject<Distribution>::fromPrior()
{
	// Generate the hyperparameters from their prior
	dist.fromPrior();

	// Generate from {0, 1, 2, ..., max_num_components}
	if(!fixed)
		num_components = DNest3::randInt(max_num_components + 1);

	// Resize the vectors of component properties
	components.resize  (num_components, std::vector<double>(num_dimensions));
	u_components.resize(num_components, std::vector<double>(num_dimensions));

	// Generate components
	for(int i=0; i<num_components; i++)
	{
		for(int j=0; j<num_dimensions; j++)
		{
			u_components[i][j] = DNest3::randomU();
			components  [i][j] = u_components[i][j];
		}
		dist.from_uniform(components[i]);
	}
}

template<class Distribution>
double RJObject<Distribution>::perturb_components(double chance, double scale)
{
	if(num_components == 0)
		return 0.;

	// A flag for whether each component gets changed or not
	std::vector<bool> change(num_components, false);
	int count = 0;
	for(int i=0; i<num_components; i++)
	{
		if(DNest3::randomU() <= chance)
		{
			change[i] = true;
			count++;
		}
	}
	// At least do one...
	if(count == 0)
		change[DNest3::randInt(num_components)] = true;

	for(int i=0; i<num_components; i++)
	{
		if(change[i])
		{
			// Perturb
			for(int j=0; j<num_dimensions; j++)
			{
				u_components[i][j] += scale*DNest3::randn();
				u_components[i][j] = DNest3::mod(
							u_components[i][j], 1.);
				components[i][j] = u_components[i][j];
			}
			dist.from_uniform(components[i]);
		}
	}

	return 0.;
}

template<class Distribution>
double RJObject<Distribution>::add_component()
{
	if(num_components >= max_num_components)
	{
		std::cerr<<"# WARNING: Trying to add component ";
		std::cerr<<"but already full!"<<std::endl;
		return 0.;
	}

	// Increment counter
	num_components++;

	// Generate component
	std::vector<double> component(num_dimensions);
	for(int j=0; j<num_dimensions; j++)
		component[j] = DNest3::randomU();
	u_components.push_back(component);
	dist.from_uniform(component);
	components.push_back(component);

	return 0.;
}

template<class Distribution>
double RJObject<Distribution>::perturb_num_components(double scale)
{
	double logH = 0.;

	// Work out how many components we will have after the change
	double delta = max_num_components*scale*DNest3::randn();
	int difference = (int)floor(delta);
	// In case difference is zero, make it + 1
	if(difference == 0)
	{
		if(DNest3::randomU() <= 0.5)
			difference = -1;
		else
			difference =  1;
	}
	int new_num_components = DNest3::mod(num_components + difference, max_num_components + 1);
	difference = new_num_components - num_components;

	// Now do the required changes
	if(difference > 0)
	{
		for(int i=0; i<difference; i++)
			logH += add_component();
	}
	else
	{
		for(int i=0; i<-difference; i++)
			logH += remove_component();
	}

	return logH;
}

template<class Distribution>
double RJObject<Distribution>::perturb()
{
	double logH = 0.;

	int which = (fixed)?(1 + DNest3::randInt(2)):(DNest3::randInt(3));

	if(which == 0)
	{
		// Do some birth or death
		logH += perturb_num_components(
				pow(10., 1.5 - 6.*DNest3::randomU()));
	}
	else if(which == 1)
	{
		// Change the hyperparameters
		if(DNest3::randomU() <= 0.5)
			logH += dist.perturb1(components, u_components);
		else
			logH += dist.perturb2(components, u_components);
	}
	else if(which == 2)
{'fraction_non_alphanumeric': 0.15609304784562517, 'fraction_numerical': 0.01586042823156225, 'mean_word_length': 4.75, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6459754', 'n_tokens_mistral': 2997, 'n_tokens_neox': 2709, 'n_words': 577}