mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 13:30:52 -05:00 
			
		
		
		
	
		
			
	
	
		
			172 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			172 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								// inverse_chi_squared_distribution_example.cpp
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Copyright Paul A. Bristow 2010.
							 | 
						||
| 
								 | 
							
								// Copyright Thomas Mang 2010.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Use, modification and distribution are subject to the
							 | 
						||
| 
								 | 
							
								// Boost Software License, Version 1.0.
							 | 
						||
| 
								 | 
							
								// (See accompanying file LICENSE_1_0.txt
							 | 
						||
| 
								 | 
							
								// or copy at http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Example 1 of using inverse chi squared distribution
							 | 
						||
| 
								 | 
							
								#include <boost/math/distributions/inverse_chi_squared.hpp>
							 | 
						||
| 
								 | 
							
								using boost::math::inverse_chi_squared_distribution;  // inverse_chi_squared_distribution.
							 | 
						||
| 
								 | 
							
								using boost::math::inverse_chi_squared; //typedef for nverse_chi_squared_distribution double.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <iostream>
							 | 
						||
| 
								 | 
							
								using std::cout;    using std::endl;
							 | 
						||
| 
								 | 
							
								#include <iomanip> 
							 | 
						||
| 
								 | 
							
								using std::setprecision;
							 | 
						||
| 
								 | 
							
								using std::setw;
							 | 
						||
| 
								 | 
							
								#include <cmath>
							 | 
						||
| 
								 | 
							
								using std::sqrt;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class RealType>
							 | 
						||
| 
								 | 
							
								RealType naive_pdf1(RealType df, RealType x)
							 | 
						||
| 
								 | 
							
								{ // Formula from Wikipedia http://en.wikipedia.org/wiki/Inverse-chi-square_distribution
							 | 
						||
| 
								 | 
							
								  // definition 1 using tgamma for simplicity as a check.
							 | 
						||
| 
								 | 
							
								   using namespace std; // For ADL of std functions.
							 | 
						||
| 
								 | 
							
								   using boost::math::tgamma;
							 | 
						||
| 
								 | 
							
								   RealType df2 = df / 2;
							 | 
						||
| 
								 | 
							
								   RealType result = (pow(2., -df2) * pow(x, (-df2 -1)) * exp(-1/(2 * x) ) )
							 | 
						||
| 
								 | 
							
								      / tgamma(df2);  // 
							 | 
						||
| 
								 | 
							
								   return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class RealType>
							 | 
						||
| 
								 | 
							
								RealType naive_pdf2(RealType df, RealType x)
							 | 
						||
| 
								 | 
							
								{ // Formula from Wikipedia http://en.wikipedia.org/wiki/Inverse-chi-square_distribution
							 | 
						||
| 
								 | 
							
								  // Definition 2, using tgamma for simplicity as a check.
							 | 
						||
| 
								 | 
							
								  // Not scaled, so assumes scale = 1 and only uses nu aka df.
							 | 
						||
| 
								 | 
							
								   using namespace std; // For ADL of std functions.
							 | 
						||
| 
								 | 
							
								   using boost::math::tgamma;
							 | 
						||
| 
								 | 
							
								   RealType df2 = df / 2;
							 | 
						||
| 
								 | 
							
								   RealType result = (pow(df2, df2) * pow(x, (-df2 -1)) * exp(-df/(2*x) ) )
							 | 
						||
| 
								 | 
							
								     / tgamma(df2);
							 | 
						||
| 
								 | 
							
								   return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class RealType>
							 | 
						||
| 
								 | 
							
								RealType naive_pdf3(RealType df, RealType scale, RealType x)
							 | 
						||
| 
								 | 
							
								{ // Formula from Wikipedia http://en.wikipedia.org/wiki/Scaled-inverse-chi-square_distribution
							 | 
						||
| 
								 | 
							
								  // *Scaled* version, definition 3, df aka nu, scale aka sigma^2
							 | 
						||
| 
								 | 
							
								  // using tgamma for simplicity as a check.
							 | 
						||
| 
								 | 
							
								   using namespace std; // For ADL of std functions.
							 | 
						||
| 
								 | 
							
								   using boost::math::tgamma;
							 | 
						||
| 
								 | 
							
								   RealType df2 = df / 2;
							 | 
						||
| 
								 | 
							
								   RealType result = (pow(scale * df2, df2) * exp(-df2 * scale/x) ) 
							 | 
						||
| 
								 | 
							
								     / (tgamma(df2) * pow(x, 1+df2));
							 | 
						||
| 
								 | 
							
								   return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template <class RealType>
							 | 
						||
| 
								 | 
							
								RealType naive_pdf4(RealType df, RealType scale, RealType x)
							 | 
						||
| 
								 | 
							
								{ // Formula from http://mathworld.wolfram.com/InverseChi-SquaredDistribution.html
							 | 
						||
| 
								 | 
							
								  // Weisstein, Eric W. "Inverse Chi-Squared Distribution." From MathWorld--A Wolfram Web Resource.
							 | 
						||
| 
								 | 
							
								  // *Scaled* version, definition 3, df aka nu, scale aka sigma^2
							 | 
						||
| 
								 | 
							
								  // using tgamma for simplicity as a check.
							 | 
						||
| 
								 | 
							
								   using namespace std; // For ADL of std functions.
							 | 
						||
| 
								 | 
							
								   using boost::math::tgamma;
							 | 
						||
| 
								 | 
							
								   RealType nu = df; // Wolfram uses greek symbols nu,
							 | 
						||
| 
								 | 
							
								   RealType xi = scale; // and xi.
							 | 
						||
| 
								 | 
							
								   RealType result = 
							 | 
						||
| 
								 | 
							
								     pow(2, -nu/2) *  exp(- (nu * xi)/(2 * x)) * pow(x, -1-nu/2) * pow((nu * xi), nu/2) 
							 | 
						||
| 
								 | 
							
								     / tgamma(nu/2);
							 | 
						||
| 
								 | 
							
								   return result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int main()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cout << "Example (basic) using Inverse chi squared distribution. " << endl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // TODO find a more practical/useful example.  Suggestions welcome?
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
							 | 
						||
| 
								 | 
							
								  int max_digits10 = 2 + (boost::math::policies::digits<double, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
							 | 
						||
| 
								 | 
							
								  cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined" << endl; 
							 | 
						||
| 
								 | 
							
								#else 
							 | 
						||
| 
								 | 
							
								  int max_digits10 = std::numeric_limits<double>::max_digits10;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								  cout << "Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = "
							 | 
						||
| 
								 | 
							
								    << max_digits10 << endl; 
							 | 
						||
| 
								 | 
							
								  cout.precision(max_digits10); // 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  inverse_chi_squared ichsqdef; // All defaults  - not very useful!
							 | 
						||
| 
								 | 
							
								  cout << "default df = " << ichsqdef.degrees_of_freedom()
							 | 
						||
| 
								 | 
							
								    << ", default scale = " <<  ichsqdef.scale() << endl; //  default df = 1, default scale = 0.5
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inverse_chi_squared ichsqdef4(4); // Unscaled version, default scale = 1 / degrees_of_freedom
							 | 
						||
| 
								 | 
							
								   cout << "default df = " << ichsqdef4.degrees_of_freedom()
							 | 
						||
| 
								 | 
							
								    << ", default scale = " <<  ichsqdef4.scale() << endl; //  default df = 4, default scale = 2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   inverse_chi_squared ichsqdef32(3, 2); // Scaled version, both degrees_of_freedom and scale specified.
							 | 
						||
| 
								 | 
							
								   cout << "default df = " << ichsqdef32.degrees_of_freedom()
							 | 
						||
| 
								 | 
							
								    << ", default scale = " <<  ichsqdef32.scale() << endl; // default df = 3, default scale = 2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    cout.precision(3);
							 | 
						||
| 
								 | 
							
								    double nu = 5.;
							 | 
						||
| 
								 | 
							
								    //double scale1 = 1./ nu; // 1st definition sigma^2 = 1/df;
							 | 
						||
| 
								 | 
							
								    //double scale2 = 1.; // 2nd definition sigma^2 = 1
							 | 
						||
| 
								 | 
							
								    inverse_chi_squared ichsq(nu, 1/nu); // Not scaled
							 | 
						||
| 
								 | 
							
								    inverse_chi_squared sichsq(nu, 1/nu); // scaled
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    cout << "nu = " << ichsq.degrees_of_freedom() << ", scale = " << ichsq.scale() << endl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int width = 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    cout << "     x        pdf      pdf1   pdf2  pdf(scaled)    pdf       pdf      cdf     cdf" << endl;
							 | 
						||
| 
								 | 
							
								    for (double x = 0.0; x < 1.; x += 0.1)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      cout 
							 | 
						||
| 
								 | 
							
								        << setw(width) << x 
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << pdf(ichsq, x) // unscaled
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << naive_pdf1(nu,  x) // Wiki def 1 unscaled matches graph 
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << naive_pdf2(nu,  x) // scale = 1 - 2nd definition.
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << naive_pdf3(nu, 1/nu, x) // scaled 
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << naive_pdf4(nu, 1/nu, x) // scaled 
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << pdf(sichsq, x)  // scaled
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << cdf(sichsq, x)  // scaled
							 | 
						||
| 
								 | 
							
								        << ' ' << setw(width) << cdf(ichsq, x)  // unscaled
							 | 
						||
| 
								 | 
							
								       << endl;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cout.precision(max_digits10);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  inverse_chi_squared ichisq(2., 0.5);
							 | 
						||
| 
								 | 
							
								  cout << "pdf(ichisq, 1.) = " << pdf(ichisq, 1.) << endl;
							 | 
						||
| 
								 | 
							
								  cout << "cdf(ichisq, 1.) = " << cdf(ichisq, 1.) << endl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return 0;
							 | 
						||
| 
								 | 
							
								}  // int main()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Output is:
							 | 
						||
| 
								 | 
							
								 Example (basic) using Inverse chi squared distribution. 
							 | 
						||
| 
								 | 
							
								  Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = 17
							 | 
						||
| 
								 | 
							
								  default df = 1, default scale = 1
							 | 
						||
| 
								 | 
							
								  default df = 4, default scale = 0.25
							 | 
						||
| 
								 | 
							
								  default df = 3, default scale = 2
							 | 
						||
| 
								 | 
							
								  nu = 5, scale = 0.2
							 | 
						||
| 
								 | 
							
								       x        pdf      pdf1   pdf2  pdf(scaled)    pdf       pdf      cdf     cdf
							 | 
						||
| 
								 | 
							
								         0        0    -1.#J    -1.#J    -1.#J    -1.#J        0        0        0
							 | 
						||
| 
								 | 
							
								       0.1     2.83     2.83 3.26e-007     2.83     2.83     2.83   0.0752   0.0752
							 | 
						||
| 
								 | 
							
								       0.2     3.05     3.05  0.00774     3.05     3.05     3.05    0.416    0.416
							 | 
						||
| 
								 | 
							
								       0.3      1.7      1.7    0.121      1.7      1.7      1.7    0.649    0.649
							 | 
						||
| 
								 | 
							
								       0.4    0.941    0.941    0.355    0.941    0.941    0.941    0.776    0.776
							 | 
						||
| 
								 | 
							
								       0.5    0.553    0.553    0.567    0.553    0.553    0.553    0.849    0.849
							 | 
						||
| 
								 | 
							
								       0.6    0.345    0.345    0.689    0.345    0.345    0.345    0.893    0.893
							 | 
						||
| 
								 | 
							
								       0.7    0.227    0.227    0.728    0.227    0.227    0.227    0.921    0.921
							 | 
						||
| 
								 | 
							
								       0.8    0.155    0.155    0.713    0.155    0.155    0.155     0.94     0.94
							 | 
						||
| 
								 | 
							
								       0.9     0.11     0.11    0.668     0.11     0.11     0.11    0.953    0.953
							 | 
						||
| 
								 | 
							
								         1   0.0807   0.0807     0.61   0.0807   0.0807   0.0807    0.963    0.963
							 | 
						||
| 
								 | 
							
								  pdf(ichisq, 1.) = 0.30326532985631671
							 | 
						||
| 
								 | 
							
								  cdf(ichisq, 1.) = 0.60653065971263365
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 |