ページ 11

配列の対角化

Posted: 2015年12月11日(金) 10:13
by saigou
対角優位化というのは例えば以下の配列があるとしたら
3.2 1.4 -1.0
1.3 -2.3 0.1
2.1 0.1 3.1
という3×3の行列があるとする。
この左上から右下にかけての3.2,-2.3,3.1という数は
で一列目の3.2は  |3.2|>|1.4|+|-1.0|となる同じく 二列目の真ん中にある-2.3は |-2.3|>|1.3|+|0.1|
のよようなものを対角優位といいます

配列に乱数を用いり以下の配列になりました。下の配列は乱数で数をきめているので行列が対角優位にはなっていないので乱数を用いて行列を作成したあと対角優位になるようにするにはどのような0ソースコードを入れればよろしいですか?

---------------------------------------------------------------------
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{
int N;
int i,j;

int a[N][N];


srand((unsigned int)time(NULL));
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) a[j] = rand();
}

for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf(" %4d",a[j]);
}
putchar('\n');
}
return 0;
}
-------------------------------------------------------------------

Re: 配列の対角化

Posted: 2015年12月11日(金) 13:01
by みけCAT
saigou さんが書きました:乱数を用いて行列を作成したあと対角優位になるようにするにはどのような0ソースコードを入れればよろしいですか?
Nを初期化するソースコードと、対角優位にするようなソースコードを入れればいいと思います。
オフトピック
前のトピックが解決したのでしたら、解決チエックをお願いします。

Re: 配列の対角化

Posted: 2015年12月11日(金) 13:59
by saigou
すいません、対角優位にするソースコードを考えていたのですが、どうしてもわかりませんでした。
対角優位になるソースコードをおしえていただけませんか?

Re: 配列の対角化

Posted: 2015年12月11日(金) 14:31
by YuO
そもそも,行列が対角優位であるというのは特定の条件を満たす行列のことを言うのですよね。
ある行列が対角優位であるかを判定することは出来ますが,ある行列を対角優位に変換するというのは,別の行列を作ることになります。

なので,条件をちゃんと付けない限り,
saigou さんが書きました:対角優位になるようにする
のは,(有意かどうかは別にして) 方法は無限にあると思います。
極端な話,零行列をかけたあと0を除く実数倍した単位行列を足した行列はすべて対角優位になりますが,元の行列の性質等は一切なくなります。

何らかの目的を持ってある行列を対角優位にしたいのであれば,別の条件が付与されるはずです。
その条件等を書かないと,目的に合った回答は出てこないと思いますよ。
オフトピック
最初の投稿の1文目,「対角優位化というのは」から始まっているのに「対角優位といいます」で終わっていて,「何が対角優位化なのか」がわかりません。
「対角優位化とは何なのか」をちゃんと書いてみた方がよいかと思います。

Re: 配列の対角化

Posted: 2015年12月11日(金) 14:50
by saigou
説明不足ですいません


#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{
int N;
int i,j;
if (scanf("%d", &N) != 1 || N < 1 || 1000 < N) return 1;
int a[N][N];


srand((unsigned int)time(NULL));
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) a[j] = rand();
}

for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf(" %4d",a[j]);
}
putchar('\n');
}
return 0;
}


上のプログラムは以前質問させていただいた乱数を用いた行列生成です。このソースコードは乱数で生成された行列なので対角優位ではない行列なので、乱数を用いた行列を対角優位になる行列に変換するにはこのソースコードに何を付け加えればいいのか詳しく教えて欲しいです

Re: 配列の対角化

Posted: 2015年12月11日(金) 15:26
by non
例は実数なのに、プログラムでは整数ですよね。要素に範囲はあるのでしょうか?

Re: 配列の対角化

Posted: 2015年12月11日(金) 15:30
by saigou
要素の範囲は1-1000までです。 説明不足なてんが多くあると思いますので要素数が1〜1000までのソースコードが無理な場合はないものとして考えていただいて大丈夫です

Re: 配列の対角化

Posted: 2015年12月11日(金) 15:39
by YuO
saigou さんが書きました:上のプログラムは以前質問させていただいた乱数を用いた行列生成です。このソースコードは乱数で生成された行列なので対角優位ではない行列なので、乱数を用いた行列を対角優位になる行列に変換するにはこのソースコードに何を付け加えればいいのか詳しく教えて欲しいです
まず最初にすべきは,コードに手を付けることではなく,「対角優位になる行列に変換する」に関する数学的な定義なり方法なりをきちんと記述することです。
とにかく対角優位な行列を生成したいというのであれば,先に書いた方法や,ループを回して対角優位な行列が出てくるまで生成し続けるというような力業を使えばよいので。

というか,単位行列を含む対角成分が全て0でない対角行列は対角優位には変わりないので,この行列を最初から作るのでは何が問題なのかを教えてもらえますか。

Re: 配列の対角化

Posted: 2015年12月11日(金) 15:51
by non
saigou さんが書きました:要素の範囲は1-1000までです。 説明不足なてんが多くあると思いますので要素数が1〜1000までのソースコードが無理な場合はないものとして考えていただいて大丈夫です
要素(成分)の範囲を教えて下さい。実数か、整数かも含めて。

まず、乱数で対角以外の要素を添付のプログラムのように発生させて、次に行ごとに対角以外の絶対の合計以上になるように対角要素の乱数を
発生させればよいのではないかな。

Re: 配列の対角化

Posted: 2015年12月11日(金) 15:57
by saigou
初心者なのでうまく説明できませんでした、、実数でお願いします。要素の範囲はnonさんの好きな範囲でおねがいします

Re: 配列の対角化

Posted: 2015年12月11日(金) 16:07
by non
saigou さんが書きました:実数でお願いします。要素の範囲はnonさんの好きな範囲でおねがいします
いや、そんないいかげんな。これって何に使うのですか?
学校の課題ですか?この後、連立方程式を解くプログラムを作る?

Re: 配列の対角化

Posted: 2015年12月11日(金) 16:09
by saigou
他の大学の友達の課題を解くのを手伝っていて、

のちに連立方程式を解くきます

Re: 配列の対角化

Posted: 2015年12月11日(金) 16:19
by non
じゃ、課題を正確に載せてもらいたいですね。
それから、貴方が勉強のために解いているのでしょうから、自分で作っていきましょう。

まず、添付のプログラムを改良し、要素を実数で発生させてください。このとき、要素の範囲を考えてください。対角要素の範囲もね。

Re: 配列の対角化

Posted: 2015年12月11日(金) 16:26
by saigou
ありがとうございます。初心者なので迷惑をかけますがお願いします

説明不足ですいません


#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{
int N;
double i,j;
double i=0.0,j=0.0;
if (scanf("%d", &N) != 1 || N < 1 || 1000 < N) return 1;
double a[N][N];


srand((unsigned int)time(NULL));
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) a[j] = rand();
}

for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf(" %4d",a[j]);
}
putchar('\n');
}
return 0;
}
ということでしょうか?

Re: 配列の対角化

Posted: 2015年12月11日(金) 16:41
by saigou
友人の課題についての詳細です

一、乱数を使用し問題ファイルの生成プログラムを作成
二、ガウス消去法のプログラム作成、求解時間評価
三、ヤコビ法を用いた連立方程式求解のプログラム生成。同じく求解時間評価
*複数のサイズをとく。問題サイズ、問題数は各自できめる
*求解の際にピボット操作を行わずして求解する
*コマンドラインで問題ファイルと解ファイルを指定。求解は解ファイルに書き出し

問題ファイルの例について
問題ファイルは一行目に問題サイズ、二行目以降に係数a。さらに右辺に定数bを。
解ファイルは一行目に問題サイズ、二行目以降に解xを
解ファイルは問題ファイル生成時に予め作成。二、三のプログラムにデバックに用いる
-------------------------
3
4.2 2.4 -2.0 2
2.3 -3.3 1.1 1
3.1 1.0 4.1 -4
--------------------------
です。

いまつまづいてるのは一番の問題です

Re: 配列の対角化

Posted: 2015年12月11日(金) 16:52
by non
自分で作ったプログラムを実行して、実数が出ているか確認しましたか?

Re: 配列の対角化

Posted: 2015年12月11日(金) 22:15
by みけCAT
saigou さんが書きました:初心者なので迷惑をかけますがお願いします
まずはcodeタグを使うようにするところから改善してはいかがでしょうか?
saigou さんが書きました: #include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{
int N;
double i,j;
double i=0.0,j=0.0;
if (scanf("%d", &N) != 1 || N < 1 || 1000 < N) return 1;
double a[N][N];


srand((unsigned int)time(NULL));
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) a[j] = rand();
}

for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf(" %4d",a[j]);
}
putchar('\n');
}
return 0;
}
ということでしょうか?

いいえ。このコードはコンパイルが通りません。
C言語やC++では、配列の添字(オーバーロードされたoperator[]の引数ではない)に実数は使えません。
C++とみなすと、変数i, jが二重に定義されているという問題もあります。
また、printfの書式が違うので、もしもコンパイルが通ったとしてもundefined behaviorになります。