Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext
查找位置(均值)( Find Location )實例

首先我們需要包含一些頭文件來訪問正態分佈和查找算法(以及標準輸出)。

#include <boost/math/distributions/normal.hpp> // normal_distribution
  using boost::math::normal; // typedef 提供的缺省類型為 double.
#include <boost/math/distributions/cauchy.hpp> // cauchy_distribution
  using boost::math::cauchy; // typedef 提供的缺省類型為 double.
#include <boost/math/distributions/find_location.hpp>
  using boost::math::find_location;
  using boost::math::complement; // 如果你想要使用補集版本( complement version ).
  using boost::math::policies::policy;

#include <iostream>
  using std::cout; using std::endl;
#include <iomanip>
  using std::setw; using std::setprecision;
#include <limits>
  using std::numeric_limits;

對於這個例子,我們將使用標準正態分佈,均值為0,標準差為1,這也是這個庫的缺省實現:

normal N01;  // 缺省的標準正態分佈的均值為0
double sd = 1.; // 標準差為 1.

假設我們要查找一個均值改變的不同的正態分佈的標準差,使得僅有數量為p (在這裡為 0.001 或 0.1%) 的隨機變量位於一個特定的界限之下 (這裡為 -2. 標準差).

double z = -2.; // z to give prob p
double p = 0.001; // only 0.1% below z

cout << "Normal distribution with mean = " << N01.location()
  << ", standard deviation " << N01.scale()
  << ", has " << "fraction <= " << z 
  << ", p = "  << cdf(N01, z) << endl;
cout << "Normal distribution with mean = " << N01.location()
  << ", standard deviation " << N01.scale()
  << ", has " << "fraction > " << z
  << ", p = "  << cdf(complement(N01, z)) << endl; // Note: uses complement.

Normal distribution with mean = 0, standard deviation 1, has fraction <= -2, p = 0.0227501
Normal distribution with mean = 0, standard deviation 1, has fraction > -2, p = 0.97725

現在我們可以使用函數 ''find_location'' 來給定一個均值偏移(offset mean)。

double l = find_location<normal>(z, p, sd);
cout << "offset location (mean) = " << l << endl;

輸出為:

offset location (mean) = 1.09023

顯示我們需要將均值從它先前的0值增加一個標準差的值。

然後我們通過使用新的均值偏移(offset mean)來構造一個新的分佈來檢查我們已經達到目標(但標準差相同):

normal np001pc(l, sd); // 同相的 standard_deviation (scale) 但均值改變.

並重新計算低於我們選定界限的百分比。

cout << "Normal distribution with mean = " << l 
    << " has " << "fraction <= " << z 
    << ", p = "  << cdf(np001pc, z) << endl;
  cout << "Normal distribution with mean = " << l 
    << " has " << "fraction > " << z 
    << ", p = "  << cdf(complement(np001pc, z)) << endl;

Normal distribution with mean = 1.09023 has fraction <= -2, p = 0.001
Normal distribution with mean = 1.09023 has fraction > -2, p = 0.999

控制函數find_location對錯誤的處理

我們也可以控制處理各種錯誤的策略。例如,我們可以定義一個新的策略(可能不是很明智) 來忽略定義域錯誤 ('壞的' 參數)。

除非我們使用了 boost::math 名字空間,我們將需要::

using boost::math::policies::policy;
using boost::math::policies::domain_error;
using boost::math::policies::ignore_error;
雖然沒有被要求,但使用 typedef 是很方便的,尤其是如果重複使用, 就像下面的多個例子顯示的那樣:

typedef policy<domain_error<ignore_error> > ignore_domain_policy;
// find_location 使用新的策略,使用 typedef.
l = find_location<normal>(z, p, sd, ignore_domain_policy());
// 缺省策略 policy<>, 需要"using boost::math::policies::policy;"
l = find_location<normal>(z, p, sd, policy<>());
// 缺省策略,完全地指定.
l = find_location<normal>(z, p, sd, boost::math::policies::policy<>());
// 一個新的策略,忽略定義域錯誤,不使用 typedef.
l = find_location<normal>(z, p, sd, policy<domain_error<ignore_error> >());

如果我們想要使用的概率是概率的補集,我們幾乎不需要思考就可以寫出find_location<normal>(z, 1 - p, sd),但為了避免精度損失,使用補集版本( complement version)。

z = 2.;
double q = 0.95; // = 1 - p; // 補集.
l = find_location<normal>(complement(z, q, sd));

normal np95pc(l, sd); // 同樣的 standard_deviation 但均值改變了
cout << "Normal distribution with mean = " << l << " has " 
  << "fraction <= " << z << " = "  << cdf(np95pc, z) << endl;
cout << "Normal distribution with mean = " << l << " has " 
  << "fraction > " << z << " = "  << cdf(complement(np95pc, z)) << endl;

參考find_location_example.cpp 查看完整代碼:程序的輸出類似於下面:

Example: Find location (mean).
Normal distribution with mean = 0, standard deviation 1, has fraction <= -2, p = 0.0227501
Normal distribution with mean = 0, standard deviation 1, has fraction > -2, p = 0.97725
offset location (mean) = 1.09023
Normal distribution with mean = 1.09023 has fraction <= -2, p = 0.001
Normal distribution with mean = 1.09023 has fraction > -2, p = 0.999
Normal distribution with mean = 0.355146 has fraction <= 2 = 0.95
Normal distribution with mean = 0.355146 has fraction > 2 = 0.05


PrevUpHomeNext