コード例 #1
0
ファイル: Omath.cpp プロジェクト: ndilday/virtualu
//------ Begin of function Math::double_poisson -------//
//!
//! Double Poisson(n, mu) 	= (exp[-mu]*mu^n)/n!  	/* Poison probability distribution */
//!
float Math::double_poisson(int n, float mu) {
    int nFactor=1;

    for (int i=2; i<=n; i++) {
	nFactor *= i;
    }

    return float( exp(-mu) * safe_pow(mu,(float)n) ) / nFactor;
}
コード例 #2
0
ファイル: CouenneExprEvenPow.hpp プロジェクト: imzye/coin
 /// compute power
 inline CouNumber exprEvenPow::operator () () {
   //  return (currValue_ = safe_pow (base, exponent));
   return (safe_pow ((**arglist_) (), (*(arglist_ [1])) ()));
 }
コード例 #3
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;
}
コード例 #4
0
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;
}