ピボット選択
をテンプレートにして作成
[
トップ
|
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
ガウスの消去法における前進消去の式をもう一度みてみる.
#ref(ls_pivoting.eq1.gif,nolink,70%)
右辺の第2項に&ref(ls_pivoting.eq2.gif,nolink,70%);で割る...
元々対角要素に0を含んでいる,もしくは,前進消去の過程で対...
また,0でなくても絶対値が非常に小さい数だと桁落ちが起こり...
この問題に対処するために,ピボット(pivot:枢軸)選択(pivota...
と呼ばれる方法を説明する.
まず,連立方程式において式の順番は交換可能であることに注...
つまり,&ref(ls_pivoting.eq3.gif,nolink,70%);行目の処理を...
の値を調べ,その絶対値が最大の行と&ref(ls_pivoting.eq3.gi...
これがピボット選択である.
ちなみに,このように行の入れ替えだけ行うことを部分的ピボ...
さらに列方向についても調べて入れ替えを適用することを完全...
ただし,部分的ピボッティングでは未知数の順番は変わらない...
完全ピボッティングの場合は未知数の順番も変化するので注意.
以下にピボット選択を含めたガウス消去法のコード例を示す.
#code(C){{
/*!
* ピボット選択(Pivoting)
* - 行入れ替えだけの部分的ピボッティング
* @param[inout] A n×nの係数項とn×1の定数項(b)を併せたn×(...
* @param[in] n n元連立一次方程式
* @param[in] k 対象行
* @return 1:成功
*/
inline void Pivoting(vector< vector<double> > &A, int n, ...
{
// k行目以降でk列目の絶対値が最も大きい要素を持つ行を...
int p = k; // 絶対値が最大の行
double am = fabs(A[k][k]);// 最大値
for(int i = k+1; i < n; ++i){
if(fabs(A[i][k]) > am){
p = i;
am = fabs(A[i][k]);
}
}
// k != pならば行を交換(ピボット選択)
if(k != p) swap(A[k], A[p]);
}
/*!
* ガウスの消去法(行に関するピボット選択(部分ピボッティン...
* @param[inout] A n×nの係数項とn×1の定数項(b)を併せたn×(...
* @param[in] n n元連立一次方程式
* @return 1:成功
*/
int GaussEliminationWithPivoting(vector< vector<double> >...
{
// 前進消去(forward elimination)
// - 対角要素をのぞいた左下要素をすべて0にする(上三...
for(int k = 0; k < n-1; ++k){
// ピボット選択
Pivoting(A, n, k);
double akk = A[k][k];
for(int i = k+1; i < n; ++i){
double aik = A[i][k];
for(int j = k; j < n+1; ++j){
A[i][j] = A[i][j]-aik*(A[k][j]/akk);
}
}
}
// 後退代入(back substitution)
// - x_nの解はb_n/a_nn,x_nをさらにn-1行の式に代入す...
// - この作業を1行目まで続けることですべての解を得る.
A[n-1][n] = A[n-1][n]/A[n-1][n-1];
for(int i = n-2; i >= 0; --i){
double ax = 0.0;
for(int j = i+1; j < n; ++j){
ax += A[i][j]*A[j][n];
}
A[i][n] = (A[i][n]-ax)/A[i][i];
}
return 1;
}
}}
終了行:
ガウスの消去法における前進消去の式をもう一度みてみる.
#ref(ls_pivoting.eq1.gif,nolink,70%)
右辺の第2項に&ref(ls_pivoting.eq2.gif,nolink,70%);で割る...
元々対角要素に0を含んでいる,もしくは,前進消去の過程で対...
また,0でなくても絶対値が非常に小さい数だと桁落ちが起こり...
この問題に対処するために,ピボット(pivot:枢軸)選択(pivota...
と呼ばれる方法を説明する.
まず,連立方程式において式の順番は交換可能であることに注...
つまり,&ref(ls_pivoting.eq3.gif,nolink,70%);行目の処理を...
の値を調べ,その絶対値が最大の行と&ref(ls_pivoting.eq3.gi...
これがピボット選択である.
ちなみに,このように行の入れ替えだけ行うことを部分的ピボ...
さらに列方向についても調べて入れ替えを適用することを完全...
ただし,部分的ピボッティングでは未知数の順番は変わらない...
完全ピボッティングの場合は未知数の順番も変化するので注意.
以下にピボット選択を含めたガウス消去法のコード例を示す.
#code(C){{
/*!
* ピボット選択(Pivoting)
* - 行入れ替えだけの部分的ピボッティング
* @param[inout] A n×nの係数項とn×1の定数項(b)を併せたn×(...
* @param[in] n n元連立一次方程式
* @param[in] k 対象行
* @return 1:成功
*/
inline void Pivoting(vector< vector<double> > &A, int n, ...
{
// k行目以降でk列目の絶対値が最も大きい要素を持つ行を...
int p = k; // 絶対値が最大の行
double am = fabs(A[k][k]);// 最大値
for(int i = k+1; i < n; ++i){
if(fabs(A[i][k]) > am){
p = i;
am = fabs(A[i][k]);
}
}
// k != pならば行を交換(ピボット選択)
if(k != p) swap(A[k], A[p]);
}
/*!
* ガウスの消去法(行に関するピボット選択(部分ピボッティン...
* @param[inout] A n×nの係数項とn×1の定数項(b)を併せたn×(...
* @param[in] n n元連立一次方程式
* @return 1:成功
*/
int GaussEliminationWithPivoting(vector< vector<double> >...
{
// 前進消去(forward elimination)
// - 対角要素をのぞいた左下要素をすべて0にする(上三...
for(int k = 0; k < n-1; ++k){
// ピボット選択
Pivoting(A, n, k);
double akk = A[k][k];
for(int i = k+1; i < n; ++i){
double aik = A[i][k];
for(int j = k; j < n+1; ++j){
A[i][j] = A[i][j]-aik*(A[k][j]/akk);
}
}
}
// 後退代入(back substitution)
// - x_nの解はb_n/a_nn,x_nをさらにn-1行の式に代入す...
// - この作業を1行目まで続けることですべての解を得る.
A[n-1][n] = A[n-1][n]/A[n-1][n-1];
for(int i = n-2; i >= 0; --i){
double ax = 0.0;
for(int j = i+1; j < n; ++j){
ax += A[i][j]*A[j][n];
}
A[i][n] = (A[i][n]-ax)/A[i][i];
}
return 1;
}
}}
ページ名: