こんにちは。
行列のLU分解のcによるプログラムを勉強している者です。
LU分解のcによるプログラムについてお尋ねしたいことがございます。
ニューメリカルレシピに、LU分解の方法として
以下のようなコードが記載せれておりました。
void ludcmp(double **a, int n, int *indx, double *d)
{
int i,imax,j,k;
double big,dum,sum,temp;
double *vv;// 各行の暗黙のスケーリングを記録する.
vv=vector(n);
*d=1.0;// まだ行交換していない.
for (i=0;i<n;i++) {// 行についてループし,暗黙のスケーリングの情報を得る.
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big) big=temp;
if (big == 0.0) printf("Singular matrix in routine ludcmp\n");// 最大要素が0なら特異行列である.
vv[i]=1.0/big;// スケーリングを記録する.
}
for (j=0;j<n;j++) {// Crout法,列についてのループ
for (i=0;i<j;i++) {// 方程式(2.3.12)のi=j以外
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
big=0.0;
for (i=j;i<n;i++) {
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (dum=vv[i]*fabs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
*d = -(*d);
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
}
free_vector(vv);
}
例えば、LU分解させたい行列3×3の({4,7,6}{2,5,9}{3,1,8})だとしたら、
メイン関数にどのように書いたらLU分解を実行できるでしょうか?
ニューメリカルレシピを買って読んでみたものの、よく理解できず、質問させていただきます。
稚拙な質問かもしれませんが、どうぞよろしくお願いいたします。
No.2ベストアンサー
- 回答日時:
あ、もしかして、
double a[3][3];
じゃなくて、
double a1[] = {4, 7, 6};
double a2[] = {2, 5, 9};
doulle a3[] = {3, 1, 8};
double *a[] = {a1, a2, a3};
なら、とりあえずはうまくいきますね。
でも、まだ、ludcmp(); をじっくり眺めるとおかしなところが残っています。
特異行列の時の処理とか。
あと、vector() はたぶん、どこかで独自に定義しているでしょうね。
この回答への補足
丁寧にお答えくださいましてありがとうございます。
さっそくお答えいただいた通りに、以下のようにして動かしてみたのですが、動きませんでした・・・。
どうしてでしょうか??(質問ばかりで申し訳ありません)
#include <stdio.h>
#include <math.h>
#include "nr.h"
#define TINY 1.0e-20;
int main()
{
double d;
int indx;
double a1[] = {4, 7, 6};
double a2[] = {2, 5, 9};
double a3[] = {3, 1, 8};
double *a[] = {a1, a2, a3};
ludcmp(a, 3, &indx, &d);
return(0);
}
void ludcmp(double **a, int n, int *indx, double *d)
{
int i,imax,j,k;
double big,dum,sum,temp;
double *vv;// 各行の暗黙のスケーリングを記録する.
vv=vector(n);
*d=1.0;// まだ行交換していない.
for (i=0;i<n;i++) {// 行についてループし,暗黙のスケーリングの情報を得る.
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big) big=temp;
if (big == 0.0) printf("Singular matrix in routine ludcmp\n");// 最大要素が0なら特異行列である.
vv[i]=1.0/big;// スケーリングを記録する.
}
for (j=0;j<n;j++) {// Crout法,列についてのループ
for (i=0;i<j;i++) {// 方程式(2.3.12)のi=j以外
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
big=0.0;
for (i=j;i<n;i++) {
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (dum=vv[i]*fabs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
*d = -(*d);
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
}
free_vector(vv);
}
ちなみに
>あと、vector() はたぶん、どこかで独自に定義しているでしょうね。
その通りです。ヘッダファイルで定義されております。
記載せず、申し訳ありませんでした。
/*nr.h*/
#define DIM3
void ludcmp(double **a, int n, int *indx, double *d);
double *vector(long size);
void free_vector(double *v);
double **matrix(long rows, long cols);
void free_matrix(double **m);
int *ivector(long nh);
void free_ivector(int *v);
お礼欄に書くのはおかしいですが、
でたエラーメッセージは
1>------ ビルド開始: プロジェクト: LU, 構成: Debug Win32 ------
1> LU.cpp
1>LU.obj : error LNK2019: 未解決の外部シンボル "void __cdecl free_vector(double *)" (?free_vector@@YAXPAN@Z) が関数 "void __cdecl ludcmp(double * *,int,int *,double *)" (?ludcmp@@YAXPAPANHPAHPAN@Z) で参照されました。
1>LU.obj : error LNK2019: 未解決の外部シンボル "double * __cdecl vector(long)" (?vector@@YAPANJ@Z) が関数 "void __cdecl ludcmp(double * *,int,int *,double *)" (?ludcmp@@YAXPAPANHPAHPAN@Z) で参照されました。
1>C:\Users\njdata\Documents\Visual Studio 2010\Projects\LU\Debug\LU.exe : fatal error LNK1120: 外部参照 2 が未解決です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
でした。お伝えし忘れていました、すみません。
No.3
- 回答日時:
単に、vector の実体がリンクの指定にないだけです。
void ludcmp(double **a, int n, int *indx, double *d)
と同じように、vector の中身が書いてあるファイルをリンクしてください。
ご丁寧にありがとうございます。
どうしてもうまくいかないのですが、
方向性は示して頂けたので、もう少しじっくり自分で勉強してみたいと思います。
何度もご丁寧にありがとうございました。大変参考になりました!
No.1
- 回答日時:
気持ちとしては、こんな感じなんだろうなと思います。
でも、これでは、うまくいきません。
肝心の ludcmp(); 自体にいくつかの間違いがあるからです。
勉強中なのだし、まずは、ludcmp(); の間違いを修正するというのはいいかもしれません。
int main()
{
double d;
int indx;
double a[3][3] =
{
{4, 7, 6},
{2, 5, 9},
{3, 1, 8}
};
ludcmp(a, 3, &indx, &d);
// その他の処理
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- C言語・C++・C# LU分解法のピボット選択機能実装について(C言語・gcc-9) 1 2022/07/22 15:20
- C言語・C++・C# プログラミング実行後の表示される値を答えよ #include<stdio.h> void main( 7 2022/05/20 00:07
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# プログラミング実行後に表示される値を答えよ #include <stdio.h> void main 4 2022/05/28 10:20
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
float型とdouble型の変数の違い...
-
doubleの変数にintとintの割り...
-
c言語で、繰り返し文の中で、0....
-
至急です! マクロ定義で #defi...
-
C言語で-23乗を取り扱うには
-
floating point not loadedとは?
-
C言語の型による処理速度の違い
-
数値を指数部と仮数部に分離したい
-
C 開放してるのにエラー(doubl...
-
int とdoubleの比較
-
関数におけるif文とreturn文に...
-
-1.#IND00 をデバッグしたい
-
C言語を実行すると-infが出てき...
-
doubleは常に%lfとするべきなのか
-
相互相関関数
-
C++で割り算の結果を昇順に出力...
-
C言語でポインタを用いた平均,...
-
配列を戻り値にして逆行列を求...
-
Cで3乗根を求める方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
doubleの変数にintとintの割り...
-
C 開放してるのにエラー(doubl...
-
Cで3乗根を求める方法
-
float型とdouble型の変数の違い...
-
至急です! マクロ定義で #defi...
-
C言語の型による処理速度の違い
-
int とdoubleの比較
-
関数におけるif文とreturn文に...
-
C言語初心者 構造体 課題について
-
c言語のコンパイルエラー canno...
-
C言語 関数プロトタイプ宣言の...
-
C言語を実行すると-infが出てき...
-
float?数字の後にLがつくもの
-
数値を指数部と仮数部に分離したい
-
difftime()について
-
浮動小数点数が表示されないん...
-
たくさんの数の平均を求める方...
-
DWORDの警告
-
-1.#IND00と出てしまうのですが...
おすすめ情報