예제 #1
0
bool insert_node(Node **u, int dep, int pos, Char x) {
	if (*u == NULL) {
		*u = new_node(), (*u)->x = x, update_node(*u);
		return dep <= 0;
	}
	int t = 0, lsz = (*u)->lson ? (*u)->lson->wsz : 0, wsz = (*u)->x.cnt;
	if (pos <= lsz+1) {
		t = insert_node(&((*u)->lson), dep-1, pos, x);
	} else if (pos > lsz + wsz) {
		t = insert_node(&((*u)->rson), dep-1, pos-lsz-wsz, x);
	} else {
		int remain = pos-lsz-1;
		insert_node(&((*u)->rson), dep-1, 0, clone_char((*u)->x.c, (*u)->x.cnt-remain));
		insert_node(&((*u)->rson), dep-1, 0, x);
		(*u)->x.cnt = remain;
	}
	update_node(*u);
	if (t && !isbad(*u))
		return 1;
	if (t) {
		flatsz = 0;
		flatten(*u);
		*u = build(0, flatsz-1);
	}
	return 0;
}
int m_insert(struct KD_TREE *tree, struct Node **u, int k, struct Point *x, int dep) {
	if (*u == NULL) {
		(*u) = newNode(tree), (*u)->pid = *x;
		tree->data[tree->size++] = *x;
		return dep <= 0;
	}
	(*u)->size++;
	int t = 0;
	if (x->d[k] < (*u)->pid.d[k])
		t = m_insert(tree, &(*u)->lson, (k+1)%tree->kD, x, dep-1);
	else
		t = m_insert(tree, &(*u)->rson, (k+1)%tree->kD, x, dep-1);
	if (t && !isbad(*u))
		return 1;
	if (t) {
		flatten_size = 0;
		flatten(tree, *u);
		*u = build(tree, k, 0, (*u)->size-1);
	}
	return 0;
}
inline T differentiate( const f * func, const T & in_param,
		const int_type order = 1, const flt_type & power = 1,
		const T & factor=SMALL_FACTOR )
{

	T d_in_param( 0 );
	T low_in_param( 0 );
	T high_in_param( 0 );
	T low_out_param( 0 );
	T high_out_param( 0 );
	T small_factor_with_units(factor);

	bool power_flag = false;
	bool zero_in_flag = false;

	int_type order_to_use = max( order, 1 );

	if ( ( order_to_use > 1 ) )
	{
		throw std::logic_error("IceBRG::differentiate with order > 1 is not currently supported.\n");
	}

	if ( power != 1 )
		power_flag = true;
	else
		power_flag = false;

	// Check if any in_params are zero. If so, estimate small factor from other in_params
	if ( in_param == 0 )
	{
		zero_in_flag = true;
	}
	else     // if(in_params==0)
	{
		small_factor_with_units = in_param * factor;
		d_in_param = small_factor_with_units;
	} // else

	if ( zero_in_flag )
	{
		if ( small_factor_with_units == 0 )
		{
			d_in_param = factor;
		}
		else
		{
			if ( in_param == 0 )
			{
				d_in_param = small_factor_with_units;
			} // if(in_params[i]==0)
		}
	}

	bool bad_function_result = false;
	int_type counter = 0;

	T Jacobian=0;

	do {
		counter++;
		bad_function_result = false;

		low_in_param = in_param - d_in_param;
		high_in_param = in_param + d_in_param;

		// Run the function to get value at test point
		try
		{
			low_out_param = ( *func )( low_in_param );
			high_out_param = ( *func )( high_in_param );
		}
		catch(const std::runtime_error &e)
		{
			bad_function_result = true;
			d_in_param /= 10; // Try again with smaller step
			continue;
		}

		// Record this derivative
		Jacobian = ( high_out_param - low_out_param ) / (2*d_in_param);
		if ( power_flag )
			Jacobian *= power * safe_pow( ( high_out_param + low_out_param )/2, power - 1 );
		if(isbad(Jacobian))
		{
			bad_function_result = true;
			d_in_param /= 10; // Try again with smaller step
			continue;
		}
	} while ((bad_function_result) && (counter<3));

	if(counter>=3)
		throw std::runtime_error("Cannot differentiate function due to lack of valid nearby points found.");

	return Jacobian;
}
inline std::vector< std::vector< T > > differentiate( const f * func, const std::vector< T > & in_params,
		const int_type order = 1, const flt_type & power = 1 )
{
	auto num_in_params = ssize(in_params);
	std::vector< std::vector< T > > Jacobian;

	std::vector< T > d_in_params( 0 );
	std::vector< T > base_out_params( 0 );
	std::vector< T > test_in_params( 0 );
	std::vector< T > test_out_params( 0 );
	T small_factor_with_units = SMALL_FACTOR;

	bool power_flag = false;
	bool zero_in_flag = false;

	int_type order_to_use = (int_type)max( order, 1 );

	if ( ( order_to_use > 1 ) )
	{
		throw std::logic_error("IceBRG::differentiate with order > 1 is not currently supported.\n");
	}

	if ( power != 1 )
		power_flag = true;
	else
		power_flag = false;

	// Delete std::vectors we'll be overwriting in case they previously existed
	Jacobian.clear();

	// Set up differentials
	make_vector_zeroes( d_in_params, num_in_params );
	test_in_params = in_params;

	// Check if any in_params are zero. If so, estimate small factor from other in_params
	for ( size_t i = 0; i < num_in_params; i++ )
	{
		if ( in_params[i] == 0 )
		{
			zero_in_flag = true;
		}
		else     // if(in_params[i]==0)
		{
			small_factor_with_units = in_params[i] * SMALL_FACTOR;
			d_in_params[i] = small_factor_with_units;
		} // else
	} // for( size_t i = 0; i < num_in_params; i++ )

	if ( zero_in_flag )
	{
		if ( small_factor_with_units == 0 )
		{
			// At least try to get the units right
			for ( size_t i = 0; i < num_in_params; i++ )
			{
#ifdef _BRG_USE_UNITS_
				d_in_params[i].set(SMALL_FACTOR,in_params[i].get_unit_powers());
#else
				d_in_params[i] = SMALL_FACTOR;
#endif
			} // for( size_t i = 0; i < num_in_params; i++ )
		}
		else
		{
			for ( size_t i = 0; i < num_in_params; i++ )
			{
				if ( in_params[i] == 0 )
				{
#ifdef _BRG_USE_UNITS_
					d_in_params[i].set(small_factor_with_units.get_value(),in_params[i].get_unit_powers());
#else
					d_in_params[i] = small_factor_with_units;
#endif
				} // if(in_params[i]==0)
			} // for( size_t i = 0; i < num_in_params; i++ )
		}
	}

	// Get value of function at input parameters
	base_out_params = ( *func )( in_params );
	auto num_out_params=ssize(base_out_params);

	// Set up Jacobian
	make_vector_default( Jacobian, num_out_params, num_in_params );

	// Loop over input and output dimensions to get Jacobian

	bool bad_function_result = false;
	int_type counter = 0;
	do {
		counter++;
		bad_function_result = false;
		for ( size_t j = 0; j < num_in_params; j++ )
		{
			// Set up test input parameters
			for ( size_t j2 = 0; j2 < num_in_params; j2++ )
			{
				if ( j2 == j )
				{
					test_in_params[j2] = in_params[j2] + d_in_params[j2];
				} // if( j2==j )
				else
				{
					test_in_params[j2] = in_params[j2];
				} // else
			}

			// Run the function to get value at test point
			try
			{
				test_out_params = ( *func )( test_in_params );
			}
			catch(const std::exception &e)
			{
				bad_function_result = true;
				for(ssize_t j=0; j< ssize(in_params); j++)
					d_in_params[j] /= 10; // Try again with smaller step size
				continue;
			}

			// Record this derivative
			for ( size_t i = 0; i < num_out_params; i++ )
			{
				Jacobian[i][j] = ( test_out_params[i] - base_out_params[i] )
						/ d_in_params[j];
				if ( power_flag )
					Jacobian[i][j] *= power
							* safe_pow( base_out_params[i], power - 1 );
				if(isbad(Jacobian[i][j]))
				{
					bad_function_result = true;
					for(size_t j=0; j< ssize(in_params); j++)
						d_in_params[j] /= 10; // Try again with smaller step size
					continue;
				}
			} // for( int_type i = 0; i < num_out_params; i++)
		} // for( size_t j = 0; j < num_in_params; j++)
	} while (bad_function_result && (counter<3));

	if(counter>=3)
		throw std::runtime_error("Cannot differentiate function due to lack of valid nearby points found.");

	return Jacobian;
}
// Print data for all bins
void pair_bins_summary::print_bin_data(std::ostream &out,
		const unitconv_map & u_map)
{

	// Set up the data and header to be printed
	table_t<flt_type> data;
	header_t header;

	header.push_back("R_min");
	header.push_back("R_max");
	header.push_back("m_min");
	header.push_back("m_max");
	header.push_back("z_min");
	header.push_back("z_max");
	header.push_back("mag_min");
	header.push_back("mag_max");

	header.push_back("shear_R_mean");
	header.push_back("shear_lens_m_mean");
	header.push_back("shear_lens_z_mean");
	header.push_back("shear_lens_mag_mean");

	header.push_back("shear_source_z_mean");

	header.push_back("shear_N_pair");
	header.push_back("shear_N_pair_eff");

	header.push_back("shear_Sigma_crit");

	header.push_back("dS_t_mean");
	header.push_back("dS_t_stddev");
	header.push_back("dS_t_stderr");
	header.push_back("dS_x_mean");
	header.push_back("dS_x_stddev");
	header.push_back("dS_x_stderr");

	header.push_back("gamma_t_mean");
	header.push_back("gamma_t_stderr");
	header.push_back("gamma_x_mean");
	header.push_back("gamma_x_stderr");

	header.push_back("model_dS_t");
	header.push_back("model_gamma_t");

	header.push_back("model_1h_dS_t");
	header.push_back("model_1h_gamma_t");

	header.push_back("model_group_dS_t");
	header.push_back("model_group_gamma_t");

	header.push_back("magf_R_mean");
	header.push_back("magf_lens_m_mean");
	header.push_back("magf_lens_z_mean");
	header.push_back("magf_lens_mag_mean");

	header.push_back("magf_source_z_mean");

	header.push_back("magf_N_lens");
	header.push_back("magf_area");

	header.push_back("magf_Sigma_crit");

	header.push_back("mu");
	header.push_back("mu_stderr");
	header.push_back("kappa");
	header.push_back("kappa_stderr");
	header.push_back("Sigma");
	header.push_back("Sigma_stderr");

	header.push_back("model_mu");
	header.push_back("model_kappa");
	header.push_back("model_Sigma");

	header.push_back("model_1h_mu");
	header.push_back("model_1h_kappa");
	header.push_back("model_1h_Sigma");

	header.push_back("model_group_mu");
	header.push_back("model_group_kappa");
	header.push_back("model_group_Sigma");

	ssize_t num_columns = ssize(header);

	data.resize(num_columns);
	for(const auto & R_bins : pair_bin_summaries())
	{
		for(const auto & Rm_bins : R_bins)
		{
			for(const auto & Rmz_bins : Rm_bins)
			{
				for(const auto & bin : Rmz_bins)
				{

					// Check if this bin is good
					if(bin.shear_effective_pair_count()>=std::numeric_limits<flt_type>::max()) continue;
					if(isbad(bin.shear_effective_pair_count())) continue;
					// It's possible we'll get bins with no shear information like this, but this
					// prunes out at least those without any info

					ssize_t col_i = -1;

					data[++col_i].push_back(value_of(bin.R_min()));
					data[++col_i].push_back(value_of(bin.R_max()));
					data[++col_i].push_back(value_of(bin.m_min()));
					data[++col_i].push_back(value_of(bin.m_max()));
					data[++col_i].push_back(bin.z_min());
					data[++col_i].push_back(bin.z_max());
					data[++col_i].push_back(bin.mag_min());
					data[++col_i].push_back(bin.mag_max());

					data[++col_i].push_back(value_of(bin.shear_R_mean()));
					data[++col_i].push_back(value_of(bin.shear_lens_m_mean()));
					data[++col_i].push_back(bin.shear_lens_z_mean());
					data[++col_i].push_back(bin.shear_lens_mag_mean());

					data[++col_i].push_back(bin.shear_source_z_mean());

					data[++col_i].push_back(bin.shear_pair_count());
					data[++col_i].push_back(bin.shear_effective_pair_count());

					data[++col_i].push_back(value_of(bin.shear_sigma_crit()));

					data[++col_i].push_back(value_of(bin.delta_Sigma_t_mean()));
					data[++col_i].push_back(value_of(bin.delta_Sigma_t_std()));
					data[++col_i].push_back(value_of(bin.delta_Sigma_t_stderr()));
					data[++col_i].push_back(value_of(bin.delta_Sigma_x_mean()));
					data[++col_i].push_back(value_of(bin.delta_Sigma_x_std()));
					data[++col_i].push_back(value_of(bin.delta_Sigma_x_stderr()));

					data[++col_i].push_back(bin.gamma_t_mean());
					data[++col_i].push_back(bin.gamma_t_stderr());
					data[++col_i].push_back(bin.gamma_x_mean());
					data[++col_i].push_back(bin.gamma_x_stderr());

					data[++col_i].push_back(value_of(bin.model_delta_Sigma_t()));
					data[++col_i].push_back(bin.model_gamma_t());

					data[++col_i].push_back(value_of(bin.model_1h_delta_Sigma_t()));
					data[++col_i].push_back(bin.model_1h_gamma_t());

					data[++col_i].push_back(value_of(bin.model_offset_delta_Sigma_t()));
					data[++col_i].push_back(bin.model_offset_gamma_t());

					data[++col_i].push_back(value_of(bin.magf_R_mean()));
					data[++col_i].push_back(value_of(bin.magf_lens_m_mean()));
					data[++col_i].push_back(bin.magf_lens_z_mean());
					data[++col_i].push_back(bin.magf_lens_mag_mean());

					data[++col_i].push_back(bin.magf_source_z_mean());

					data[++col_i].push_back(bin.magf_num_lenses());
					data[++col_i].push_back(value_of(bin.area()));

					data[++col_i].push_back(value_of(bin.magf_sigma_crit()));

					data[++col_i].push_back(bin.mu_hat());
					data[++col_i].push_back(bin.mu_stderr());
					data[++col_i].push_back(bin.kappa());
					data[++col_i].push_back(bin.kappa_stderr());
					data[++col_i].push_back(value_of(bin.Sigma()));
					data[++col_i].push_back(value_of(bin.Sigma_stderr()));

					data[++col_i].push_back(bin.model_mu());
					data[++col_i].push_back(bin.model_kappa());
					data[++col_i].push_back(value_of(bin.model_Sigma()));

					data[++col_i].push_back(bin.model_1h_mu());
					data[++col_i].push_back(bin.model_1h_kappa());
					data[++col_i].push_back(value_of(bin.model_1h_Sigma()));

					data[++col_i].push_back(bin.model_offset_mu());
					data[++col_i].push_back(bin.model_offset_kappa());
					data[++col_i].push_back(value_of(bin.model_offset_Sigma()));
				}
			}
		}
	}

	assert(ssize(data.back())==ssize(data.front())); // Check we didn't miss a column to add to the table

	table_map_t<flt_type> table_map = get_table_after_unitconv(make_table_map(data,header),u_map);

	// And now print it out
	print_table_map<flt_type>(out,table_map);

}