/*下記のプログラムで”1回目”という部分以降の繰り返し計算がうまくいきません.エラーは出ませんが,何が間違っているか,お気づきの点を教えてください,よろしくお願いします(..)
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>



int main(){

FILE *fp;
//*fp fopen("kadai2.dat","w");
//数値結果エラー表示
if((fp=fopen("kadai2.dat","w"))==NULL){
printf("error\n");
exit(1);
}


int i,j,k;
double r=2,ta=1000,tb=0;//r,ta,tb
const int N=10;//N
const int T=1;//N

const int m=N-1;//mは(N-1)とりあへず一定にしないと定まらないみたい
const int n=N-1;//n=N-1 とりあへず一定にしないと定まらないみたい
const int t=T;//n=N-1 とりあへず一定にしないと定まらないみたい

//行列定義aa,xx
double a[m+2][n+2],**aa,a1,x1;
double x[n+2][t],**xx;
aa=( double **) malloc((unsigned) m*sizeof(float*));
for(i=0;i<=m-1;i++){
aa[i]=a[i];
}
xx=( double **) malloc((unsigned) n*sizeof(float*));
for(i=0;i<=n-1;i++){
xx[i]=x[i];
}
//xx[n][t]初期化 x[0][],x[10][]以外
for(i=1;i<=n+1;i++){
x[i][0]=0;
}
//huyou
double b[n+2][t],**bb;
bb=( double **) malloc((unsigned) m*sizeof(float*));
for(i=0;i<=m-1;i++){
bb[i]=b[i];
}

//************************************ 入れなおしでx完成
//kの繰り返し開始
for(k=0;k<=T;k++){

//aaに初期値 初期化
for(j=0;j<=N;j++){
for(i=0;i<=N;i++){
a[j][i]=0;
}
}
//aaに値代入
for(i=0;i<=N-1;i++){
a[i][i]=1+2*r;
a[i+1][i]=-r;
a[i][i+1]=-r;
}

//xx[n][t]初期化 x[0][],x[10][]
x[0][k]=ta;
x[10][k]=tb;

//xx[n][t]値代入 j
x[1][k]=x[1][k]+r*x[0][k];
x[N-1][k]=x[N-1][k]+r*x[10][k];

//************************************計算部
//printf("*********************** %d\n",k);

//1回目
for(j=1;j<=N-2;j++){
for(i=1;i<=N-1;i++){
a[j+1][i]=a[j+1][i]-a[j][i]*a[j+1][j]/a[j][j];
}
x[j+1][k]=x[j+1][k]-x[j][k]*a[j+1][j]/a[j][j];
}

for(j=1;j<=N-1;j++){
for(i=1;i<=N-1;i++){
printf("%4.2fl",a[j][i]);
}
printf("\n");
}



//2回目
for(j=1;j<=N-2;j++){
for(i=1;i<=N-1;i++){
a[N-1-j][i]=a[N-1-j][i]-a[N-j][i]*a[N-1-j][N-j]/a[N-j][N-j];
}
x[N-1-j][k]=x[N-j-1][k]-x[N-1-j][k]*a[N-1-j][N-j]/a[N-j][N-j];
}

//3回目
for(i=1;i<=N-1;i++){
x[i][k]=x[i][k]/a[i][i];
}
//答え出てきたら

//ファイルに結果放り込む※時間変化表示 n x t
for(i=0;i<=N;i++){
fprintf(fp,"%d %10.5fl %d\n",i,x[i][k],k);
//printf("%d %10.7g %d\n",i,x[i][k],k);
}
//出てきたxを次の時間用に入れなおし
for(i=0;i<=8;i++){
x[i][k+1]=x[i][k];
}



}//kの繰り返し終了

fclose(fp);
return 0;

}

このQ&Aに関連する最新のQ&A

A 回答 (2件)

> //aaに値代入


> for(i=0;i<=N-1;i++){
> a[i][i]=1+2*r;
> a[i+1][i]=-r;
> a[i][i+1]=-r;
> }

コメントでは"aa"に代入するよう書いてありますが
実際にはaaでなくaに代入しています。
これは、問題ないですか?

おそらく、わざわざaaなんて作っているので
aは保存し、aaを作業用に使うつもりではなかろうかと考えます。
(そうでないなら、aaは不要だと思うのですが...)

おそらくaとaaを混同されていると思います。
保存しておく方をorg
作業用をwなどど変数名を役割がはっきり分かるよう命名しなおし、
ソースを整理すると良いと思います。
    • good
    • 0

これが何をするプログラムで, それぞれの場所でどのような処理をするのか, そしてどのような入力に対して期待する出力と実際どのような動作をしているのかは書けないんでしょうか?


とりあえず aa, xx, bb の意味がわからんし malloc でなぜ sizeof(float *) なのか理解不能.
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q行列式の解き方

こんにちは。プログラミングでわからないことがあったので質問します。文章がわかりにくかったらすみません・・・

3行3列の行列式をガウスの消去法を使ってまず上三角行列を作り、その上三角行列を上三角行列の解法で解くというプログラムを作りたいのですが、2つの解法を使うときはプログラムはどうやって作ればよいでしょうか?

例えば、上三角行列が与えられてそれを上三角行列の解法を使って解いて結果を表示するといったプログラムだけ作るということならできるのですが、2つの解法を同時に同じプログラムで作るということが出来ません。教えていただきたいです。お願いします。

Aベストアンサー

二つの解法というのは、ガウスの消去法と上三角行列法のことですね。
質問のなかで言われているように、ガウスの消去法は上三角行列を作成して、(単純に言えば)後置代入で一番下の行から順番に解を得るものでしたよね。

ガウス消去法のなかで上三角法を使いたいならば、上三角解法の関数(メソッド)を先に作成し、ガウス消去法関数のなかで上三角法関数を呼ぶ。
上三角解法(引数){...}
ガウス消去解法(引数)
{
上三角解法(引数);
}
int main
{
ガウス消去解法(引数);
}

うーん、質問を理解してないのかも。

QC言語プログラミング 逆行列を求めるプログラムを教えてください。

C言語プログラミングで掃きだし法を使って与えられた行列の逆行列を求めるプログラムを作っています。行列に0が出てきた時に対応ができないので困ってます。例えば、次の行列の逆行列を求めるプログラムを教えてください。
0 2 3
1 0 1
3 3 0
よろしくお願いします!

Aベストアンサー

ピボットで検索しましょう。
掃き出しで行や列を交換してもよいのですよ。
簡単でしょ?

出来れば、計算誤差を減らすピボットの
選択方法も学ぶと良いです。

Q線形代数の正方行列の三角化について

 現在、大学で線形代数学を学んでいるのですが、対角化の仕方は分かるのですが、三角化の仕方がさっぱり分かりません。
 例えば、

行列A =
8 -9
4 -4

について、固有値を求めると、2になりますよね。
この場合は、2に対する固有ベクトルをp_1とすると、

p_1=
3
2

のみなので、対角化はできずに三角化をするしかありませんよね。

→ここからが分からない部分です。

 このとき、(A-2E)p_2=p_1を満たすp_2を求めると、

p_2=
-1
-1

となり、Ap_1=2p_1,Ap_2=p_1+2p_2であるから、
P=(p_1,p_2)とすると、

Pの逆行列×AP=
2 1
0 2

となるそうなのですが、どうしてその仕組みで三角化が
できるか分かりません。
 分かる方がいましたら、解説していただけないでしょうか?宜しくお願い致します。

Aベストアンサー

2x2行列をAとし,非零2次元列ベクトルをp,qとしαを複素数としJ=
[α 1]
[0 α]
としたとき
A・p=α・pかつA・q-α・q=p⇔
A・p=α・pかつA・q=α・q+p⇔
(A・p,A・q)=(α・p,p+α・q)⇔
(A・p,A・q)=(p,q)・J⇔
A・(p,q)=(p,q)・J⇔
J=(p,q)^(-1)・A・(p,q)

(A-α・E)・q=pかつ(A-α・E)・p=0かつp≠0だからpとqは独立であることに注意

Q方程式を2分法を用いて解くプログラム

学校で出されたCプログラムの課題で、1問だけどうしても出来ない問題があるんです。
「方程式 f(x) = x2 - 2 = 0 を 2 分法を用いて解くプログラムを作成せよ。ここで、方程式 f(x) = x2 - 2 は関数として定義せよ。上位の方から 4 桁目まで正しい値が出たらループを止めるようにする。」
というものなのですが、この「2分法」というやり方もよく分かりません。
プログラムの作成方法と併せて教えて頂けると幸いです。

Aベストアンサー

こんな感じでしょうか?

#include <stdio.h>

/* 関数 f(x) */
double f(double x) {
 return x*x-2.0;
}

/* 二分法 初期値 x1<x2 と 誤差限界 eps を入力 */
double bisec(double x1, double x2, double eps) {
 double x;
 while (x2 - x1 >= eps) {
  x = (x1+x2)/2.0; /* 中点計算 */
  if (f(x1)*f(x) > 0.0) { /* 同符号か判定 */
   x1 = x;
  } else {
   x2 = x;
  }
 }
 return (x1+x2)/2.0;
}

int main(void) {
 double eps=0.00001;
 printf("%lf %lf\n",bisec(-2,0,eps), bisec(0,2,eps));

 return 0;
}

Qがあるのにsqrtが・・・

最初にあるプログラムを作っていたのですが、その祭sqrtでエラーが出てしまったので、別にsqrtを使う短いプログラムを作りました。それが以下のものになります。(test3.c)

#include<stdio.h>
#include<math.h>

int main(void){
int atai;
double x=2.0;
atai=(int)sqrt(x);
printf("atai is %c",atai);
}


sqrtが動作するか確かめる為のものです。このプログラム(test3.c)で以下のエラーが出てしまいました。

/tmp/ccqEejZ1.o(.text+0x4d): In function `main':
test3.c: undefined reference to `sqrt'
collect2: ld はステータス 1 で終了しました

ちなみにLinux(Fedora core 4)を使用しています。
初心者ということもありなぜエラーが出るのか分かりません。
ちなみに<math.h>を使用しないプログラムは普通に動作します。
解決方法をご存知の方がいらっしゃいましたらご教授下さいませ。
よろしくお願いします。

最初にあるプログラムを作っていたのですが、その祭sqrtでエラーが出てしまったので、別にsqrtを使う短いプログラムを作りました。それが以下のものになります。(test3.c)

#include<stdio.h>
#include<math.h>

int main(void){
int atai;
double x=2.0;
atai=(int)sqrt(x);
printf("atai is %c",atai);
}


sqrtが動作するか確かめる為のものです。このプログラム(test3.c)で以下のエラーが出てしまいました。

/tmp/ccqEejZ1.o(.text+0x4d): In function `main':
test3.c: undefined r...続きを読む

Aベストアンサー

コンパイルのオプションつけてないとかないですよね?
たとえばTerminalとかだとコンパイル時に 『-lm』とかつけますが

Q3行3列の行列の三角化(訂正)

1回同じ質問をしたのですが、訂正があったのですが訂正の方法が分からないのでもう一度書きます。

大学1年で線型代数を習っているのですが、
3行3列の三角化の方法がいまいちよく分かりません。
たとえば行列A=
 3  1  -1
-1  0  3
-1 -2  5
を三角化せよという問題で、
まず固有多項式=0が実数解を持つことを調べて、次にその解である固有値を求め(固有値は2,3、3は重解)、次にすべての固有値とその重複度についてdimKer(A-tE)=mであることを調べます。(t:固有値 m:重複度)
計算すると、Ker(A-2E)=[-1,2,1]・R(≡p1ベクトルとおく ) 
Ker(A-3E)=[0,1,1]・R(≡p2ベクトルとおく)  (R:実数)
この場合はdimKer(A-tE)=mは成り立たないので対角化ができません。
ここまでは分かりますが次がよく分からないです。
三角化する正則行列Pを求めるのに、
(P=[p1ベクトル p2ベクトル p3ベクトル])
{(A-3E)^2}xベクトル=0ベクトルを解く。
(E:単位行列)
となっているのですがなぜこのような式が出てくるのかが分かりません。答えでは上の式からP3ベクトルを出し、三角化してるようなのですが・・・
ご回答よろしくお願いいたします。

1回同じ質問をしたのですが、訂正があったのですが訂正の方法が分からないのでもう一度書きます。

大学1年で線型代数を習っているのですが、
3行3列の三角化の方法がいまいちよく分かりません。
たとえば行列A=
 3  1  -1
-1  0  3
-1 -2  5
を三角化せよという問題で、
まず固有多項式=0が実数解を持つことを調べて、次にその解である固有値を求め(固有値は2,3、3は重解)、次にすべての固有値とその重複度についてdimKer(A-tE)=mであることを調べます。(t:固有...続きを読む

Aベストアンサー

{(A-3E)^2}xp3ベクトル=0ベクトル
(A-3E)x{(A-3E)xp3ベクトル}=0ベクトル
ここで(A-3E)xp2ベクトル=0ベクトル より
(A-3E)xp3ベクトル=p2ベクトル
Axp3ベクトル=p2ベクトル+3*p3ベクトル
AxP=[2*p1ベクトル 3*p2ベクトル p2ベクトル+3*p3ベクトル]
=Px
2 0 0
0 3 1
0 0 3

∴P^-1AP=
2 0 0
0 3 1
0 0 3


k 1
0 k

のような形をした行列を2重対角行列といいます。
対角行列と2重対角行列、回転行列の複合系を
Jordan標準形といいます。これの良さはべき乗してみれば
分かります。

Qガウスの消去法、後退代入について

ガウスの消去法で、n変数n式の連立一次方程式を解くプログラムを
作っています。
ですが、前進消去およびピボット選択ははおそらくできたのですが
後退代入が悪いのか、答えが出ません。
もしかしたら前進消去部分も悪いのかもしれませんが;;

いろいろ調べたのですが
どうしたら直るのかわからなくなってしまいました。
どのようにして直せばいいのか教えてください。

プログラムは以下です。


#include<stdio.h>
#include<math.h>
#define SIZE 100/*上限MAXのマクロ定義*/
#define EPS (1.0e-5)

int main()
{
/*変数宣言*/
int n; /*連立方程式の式数*/
int i; /*1つ目のループカウンタ*/
int j; /*2つ目のループカウンタ*/
int k;/*3つ目のループカウンタ*/
int pivot; /*pivot選択を行う際に使用する変数*/
double max; /*pivot選択用の絶対値が最大の値*/
double matrix_a[SIZE][SIZE]; /*変数xijの係数aij*/
double matrix_b[SIZE]; /*式iの定数項bi*/
double a_hozon;/*matrix_aの値を一時保存する変数*/
double b_hozon;/*matrix_bの値を一時保存する変数*/
double r_hozon;/*前進消去法をする時使用する値を一時保存する変数*/
int l;
int m;

/*入力処理*/
/*未知数nの入力*/
printf("n変数n式の連立一次方程式を解きます。\n");
printf("式数n(1~100)を入力してください。 n=?\n");
scanf("%d",&n);
/*未知数nのチェック*/
if(n>SIZE||n<1)
{
printf("\n\nn=%dはプログラムの利用可能範囲外です。\n",n);
return -1;
}

printf("%d変数%d式の一次方程式を入力して下さい。\n",n,n);
printf("入力は、式毎に係数、定数項の順に行ってください。\n\n");

printf("連立一次方程式の拡大係数行列を表示します。\n");
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
scanf("%lf",&matrix_a[i][j]);

}
scanf("%lf",&matrix_b[i]);

}
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
printf("%6.2f",matrix_a[i][j]);
}
printf("|%6.2f\n",matrix_b[i]);
}

printf("計算します。\n");

/*pivot選択*/
for(k=0; k<n; k++)
{
max=0.0;
pivot=0;
for(i=k; i<n; i++)
{
if(fabs(matrix_a[i][k])>max)
{
max=fabs(matrix_a[i][k]);
pivot=i;
}
}
if(matrix_a[pivot][k]==0.0)
{
printf("正則性なし\n");
}
if(pivot!=k)
{
for(j=0; j<n; j++)
{
a_hozon = matrix_a[k][j];
matrix_a[k][j] = matrix_a[pivot][j];
matrix_a[pivot][j] = a_hozon;
}
b_hozon = matrix_b[k];
matrix_b[k] = matrix_b[pivot];
matrix_b[pivot] = b_hozon;
}

}

/*入れ換え後の行列を表示*/
for(l=0; l<n; l++)
{
for(m=0; m<n; m++)
{
printf("%6.2f",matrix_a[l][m]);
}
printf("|%6.2f\n",matrix_b[l]);
}




/*消去法*/

for(k=0; k<n; k++)
{
for(i=k+1; i<n-1; i++)
{
r_hozon = matrix_a[i][k]/matrix_a[k][k];
for(j=k; j<n; j++)
{
matrix_a[i][j] = matrix_a[i][j]-r_hozon*matrix_a[k][j];
}
matrix_b[i] = matrix_b[i]-r_hozon*matrix_b[k];
}
}

/*後退代入*/

for(i=n-1; i>=0; i--)
{
matrix_b[i]=0.0;
for(j=i+1; j<n; j++)
{
matrix_b[i]=matrix_b[i]-matrix_a[i][j]*matrix_b[j];
}
}
/*
for(i=n-1; i>0; i--)
{
temp = 0.0;
for(j=i+1; j<n; j++)
{

xn = b[n]/a[n][n];
xn-1 = (-a[n-1][n]*x[n]+b[n-1])/a[n-1][n-1];
xn-2 = (-a[n-2][n-1]*x[n-2]+a[n-2][n]*x[n]+b[n-2])/a[n-2][n-2];

xn-j = (-a[i][n-j]*x[i+1]+b[i])/a[i][i];

temp = matrix_a[][]

temp=temp+matrix_a[i][j]*matrix_a[j][n];
matrix_a[i][n]=matrix_a[i][n]-temp;
matrix_a[i][n]=matrix_a[i][n]/matrix_a[i][i];
}

}
*/

/*不定、不能の判別*/
if(matrix_a[k][k]<EPS)
{
printf("解は一意に求まらない。\n");
return -1;
}


/*出力処理*/
printf("連立一次方程式の解を表示します。\n");
for(i=0; i<n; i++)
{
printf("x%d = %6.2f\n",i,matrix_b[i]);
}

return 0;
}

ガウスの消去法で、n変数n式の連立一次方程式を解くプログラムを
作っています。
ですが、前進消去およびピボット選択ははおそらくできたのですが
後退代入が悪いのか、答えが出ません。
もしかしたら前進消去部分も悪いのかもしれませんが;;

いろいろ調べたのですが
どうしたら直るのかわからなくなってしまいました。
どのようにして直せばいいのか教えてください。

プログラムは以下です。


#include<stdio.h>
#include<math.h>
#define SIZE 100/*上限MAXのマクロ定義*/
#define EPS (1....続きを読む

Aベストアンサー

/*後退代入*/
の4行後の
matrix_b[i]=0.0;
を取り除かなければいけないのではありませんか。

Qc言語のポインタへの文字列入力についてです。

当方c言語初学者なのですがscanfを使ってポインタに文字列を入力したいのですがバグが発生して進みません・・・どういうことなのでしょうか?
#include <stdio.h>

int main(void)
{
char *a;

scanf("%s", a);
printf("%s", a);

return (0);
}

*aをa[128]; のように配列に変えるとうまくいくことはなんとかわかるのですが・・・助けてください(^_^;)

Aベストアンサー

ポインターというのは格納された値のアドレスのメモリーを指すための変数です。
一方、配列はデータを格納するためのメモリーを確保して、その先頭のアドレスが入っていますよ。

char *a;
scanf("%s", a);

と書くと、aを初期化せずにaの指す先にscanfで文字列を入れます。
大抵、プログラムが書き込むことを許されていないメモリーに書き込みを行おうとしたことを検出したOSからそのプログラムは強制終了されます。

char *a = "aaaaa";
scanf("%s", a);
となっているとどうなるか。
aは"aaaaa"が格納されているメモリーを指すように初期化されます。
ただ、大抵"aaaaa"は固定値を入れるために書き込みができないメモリーに格納されています。
よって、scanf("%s", a);も書き込みができないところに書こうとしたことをOSに検出され、強制終了となります。

2つ方向があると思います。
1. char a[128];のように宣言し、スタック上にメモリーを確保し、その先頭アドレスが入っているaを渡す方法。
2. mallocなどでヒープにメモリーを確保する方法。

1だと、
char a[128];
scanf("%127s", a);
のように書き、scanfで読み込んだ分をaから始まるメモリーに書くことになりますが、char a[128];で配列を確保しているので書き込みを行うことができ、強制終了はされません。

2だと、
char *a = malloc(128);
scanf("%127s", a);
printf("%s", a);
free(a);
のように書きます。
配列はスタック上に取られ、スタック上に取った値はプログラムがその関数を抜けるときに自動的に解放されますが、mallocで確保したメモリーは自動で解放されないので自分でfreeを呼んで開放する必要があります。

%127sがそろそろ気になっていると思います。
こうやって127文字までしか受け取らないようにscanfに指示しています。
C言語では文字列の最後は終了を示すNUL文字が入るので、確保したメモリーよりも1少ない値となっています。

というわけで、ちゃんとメモリーを確保してからscanfで書き込みましょう。ポインターはあくまでどこかのメモリーアドレスを指すだけで、指した先がちゃんと確保されているかどうかは知りませんから。

ポインターというのは格納された値のアドレスのメモリーを指すための変数です。
一方、配列はデータを格納するためのメモリーを確保して、その先頭のアドレスが入っていますよ。

char *a;
scanf("%s", a);

と書くと、aを初期化せずにaの指す先にscanfで文字列を入れます。
大抵、プログラムが書き込むことを許されていないメモリーに書き込みを行おうとしたことを検出したOSからそのプログラムは強制終了されます。

char *a = "aaaaa";
scanf("%s", a);
となっているとどうなるか。
aは"aaaaa"が格納されている...続きを読む

Qバッファとは何ですか

C言語を使用してるとバッファという言葉がよく出てきますがバッファとは何ですか
メモリとは違うものですか
訳をみても緩衝材とか一時的に蓄える場所という意味でよく分かりません
一時的でない使い方も多い気がしますが実際はどういうものですか

Aベストアンサー

#1です

寝ぼけて適当に書いたので修正。

すぐ見つけることができたもので正確なものは英語版ですがこちらくらいかも。
Data buffer - Wikipedia (en.)
http://en.wikipedia.org/wiki/Data_buffer

一応簡単なものはこちらです。
バッファとは - e-Wrods
http://e-words.jp/w/E38390E38383E38395E382A1.html

「複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを一時的に保存しておく記憶装置や記憶領域のこと。」
が現在の基本定義です。処理速度・転送速度の差のための緩衝材的な意味です。

昔はソフトウェアとハードウェア間に使うデータでソフトウェア側がデータを受け取るか、整形して送信するときに使うメモリ領域が基本的にバッファでした。
マルチプロセッサ・マルチタスクの時代になってくると、ソフトウェア間の処理速度の違いを吸収するために使うメモリ領域にもバッファという言葉が使われるようになりました。ソフトウェア間で逐次(FIFO)処理されるデータのためのメモリ領域がこちらの使われ方の主戦場といったところでしょうか。

ソフトウェア間でただ一括転送されるデータならバッファという言葉は誤用ということになるのですが、よく誤用されます。

#1です

寝ぼけて適当に書いたので修正。

すぐ見つけることができたもので正確なものは英語版ですがこちらくらいかも。
Data buffer - Wikipedia (en.)
http://en.wikipedia.org/wiki/Data_buffer

一応簡単なものはこちらです。
バッファとは - e-Wrods
http://e-words.jp/w/E38390E38383E38395E382A1.html

「複数の機器やソフトウェアの間でデータをやり取りするときに、処理速度や転送速度の差を補うためにデータを一時的に保存しておく記憶装置や記憶領域のこと。」
が現在の基本定義です。処理速度・転送速...続きを読む


人気Q&Aランキング

おすすめ情報