Google Code Prettify

2010年12月19日 星期日

C - 矩陣運算

運算的內容包括:加法(1&4)、乘法(2&5)及反矩陣(3&6)。
作業要求:
使用一維指標來模擬二維陣列。
使用Command line argument list選擇尺寸、算法、輸入方式。



#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int IsMi0(float M[99][99], int x, int N) //指標判斷某列元素是否全為0
{
int y;
for (y = 0; y < N; y++)
if (M[x][y] == 0)
break;
if (y == N - 1)
return 1;
else
return 0;
}
int IsMi0_ptr(float *M, int x, int N) //指標判斷某列元素是否全為0
{
int y;
for (y = 0; y < N; y++)
if (*(M + x * 99 + y) == 0)
break;
if (y == N - 1)
return 1;
else
return 0;
}
void add(float R[99][99], float M1[99][99], float M2[99][99], int N) //宣告函數
{
int i, j;
FILE *out;
out = fopen("result", "w+");
for (i = 0; i < N; i++) { //進行矩陣加法運算
for (j = 0; j < N; j++)
R[i][j] = M1[i][j] + M2[i][j];
}
for (i = 0; i < N; i++) { //印出結果矩陣
for (j = 0; j < N; j++)
fprintf(out, "%.2f ", R[i][j]);
fprintf(out, "\n");
}
fclose(out);
}
void multiplication(float R[99][99], float M1[99][99], float M2[99][99], int N) //宣告函數
{
int i, j, k;
FILE *out;
out = fopen("result", "w+");
for (i = 0; i < N; i++) { //進行矩陣乘法運算
for (k = 0; k < N; k++) {
for (j = 0; j < N; j++)
R[i][k] += M1[i][j] * M2[j][k];
}
}
for (i = 0; i < N; i++) { //印出結果矩陣
for (j = 0; j < N; j++)
fprintf(out, "%.2f ", R[i][j]);
fprintf(out, "\n");
}
fclose(out);
}
void inverse(float R[99][99], float M[99][99], int N) //宣告函數
{
int x, y, k;
float temp;
FILE *out;
out = fopen("result", "w+");
for (k = 0; k < N; k++) //設定單位矩陣
R[k][k] = 1;
for (k = 0; k < N; k++) {
if ((IsMi0(M, k, N) == 1)) { //判斷某列是否全為0,若成立則反矩陣不存在。
printf("This matrix has no inverse.\n");
return;
}
if (M[k][k] == 0) { //若斜對角線之元素有0,則進行列交換。
for (x = k + 1; x < N; x++) {
for (y = 0; y < N; y++) {
temp = M[k][y];
M[k][y] = M[x][y];
M[x][y] = temp;
temp = R[k][y];
R[k][y] = R[x][y];
R[x][y] = temp;
}
if (M[k][k] != 0)
break;
}
if (M[k][k] == 0) { //若無法交換至對角線無0,則反矩陣不存在。
printf("This matrix has no inverse.\n");
return;
}
}
temp = 1 / M[k][k]; //進行高斯喬登消去法解反矩陣。
for (y = 0; y < N; y++) {
M[k][y] *= temp;
R[k][y] *= temp;
}
for (x = 0; x < N; x++) {
if (x == k)
continue;
temp = M[x][k] / M[k][k];
for (y = 0; y < N; y++) {
M[x][y] -= temp * M[k][y];
R[x][y] -= temp * R[k][y];
}
}
temp = 1 / M[k][k];
for (y = 0; y < N; y++) {
M[k][y] *= temp;
R[k][y] *= temp;
}
}
for (x = 0; x < N; x++) {
for (y = 0; y < N; y++)
fprintf(out, "%.3f ", R[x][y]);
fprintf(out, "\n");
}
}
void add1(float *R, float *M1, float *M2, int N) //宣告函數
{
int i, j;
FILE *out;
out = fopen("result", "w+");
for (i = 0; i < N; i++) { //進行矩陣加法運算
for (j = 0; j < N; j++)
*(R + i * N + j) = *(M1 + i * 99 + j) + *(M2 + i * 99 + j);
}
for (i = 0; i < N; i++) { //印出結果矩陣
for (j = 0; j < N; j++)
fprintf(out, "%.2f ", *(R + i * 99 + j));
fprintf(out, "\n");
}
fclose(out);
}
void multiplication1(float *R, float *M1, float *M2, int N) //宣告函數
{
int i, j, k;
FILE *out;
out = fopen("result", "w+");
for (i = 0; i < N; i++) { //進行矩陣乘法運算
for (k = 0; k < N; k++) {
for (j = 0; j < N; j++)
*(R + i * 99 + k) += *(M1 + i * 99 + j) * *(M2 + j * 99 + k);
}
}
for (i = 0; i < N; i++) { //印出結果矩陣
for (j = 0; j < N; j++)
fprintf(out, "%.2f ", *(R + i * 99 + j));
fprintf(out, "\n");
}
fclose(out);
}
void inverse1(float *R, float *M, int N) //宣告函數
{
int x, y, k;
float temp;
FILE *out;
out = fopen("result", "w+");
for (k = 0; k < N; k++) //設定單位矩陣
*(R + k * 99 + k) = 1;
for (k = 0; k < N; k++) {
if ((IsMi0_ptr(M, k, N) == 1)) { //判斷某列是否全為0,若成立則反矩陣不存在。
printf("This matrix has no inverse.\n");
return;
}
if (*(M + k * 99 + k) == 0) { //若斜對角線之元素有0,則進行列交換。
for (x = k + 1; x < N; x++) {
for (y = 0; y < N; y++) {
temp = *(M + k * 99 + y);
*(M + k * 99 + y) = *(M + x * 99 + y);
*(M + x * 99 + y) = temp;
temp = *(R + k * 99 + y);
*(R + k * 99 + y) = *(R + x * 99 + y);
*(R + x * 99 + y) = temp;
}
if (*(M + k * 99 + k) != 0)
break;
}
if (*(M + k * 99 + k) == 0) { //若無法交換至對角線無0,則反矩陣不存在。
printf("This matrix has no inverse.\n");
return;
}
}
temp = 1 / *(M + k * 99 + k); //進行高斯喬登消去法解反矩陣。
for (y = 0; y < N; y++) {
*(M + k * 99 + y) *= temp;
*(R + k * 99 + y) *= temp;
}
for (x = 0; x < N; x++) {
if (x == k)
continue;
temp = *(M + x * 99 + k) / *(M + k * 99 + k);
for (y = 0; y < N; y++) {
*(M + x * 99 + y) -= temp * *(M + k * 99 + y);
*(R + x * 99 + y) -= temp * *(R + k * 99 + y);
}
}
temp = 1 / *(M + k * 99 + k);
for (y = 0; y < N; y++) {
*(M + k * 99 + y) *= temp;
*(R + k * 99 + y) *= temp;
}
}
for (x = 0; x < N; x++) { //印出反矩陣
for (y = 0; y < N; y++)
fprintf(out, "%.2f ", *(R + x * 99 + y));
fprintf(out, "\n");
}
fclose(out);
}
int main(int argc, char *argv[])
{
int i, j, k, N, input, function; //宣告變數
N = atoi(argv[1]); /*將尺寸存入N*/
function = atoi(argv[2]); /*將算法對應數字存入function:1.add 2.multiplication 3.inverse 4.add1 5.multiplication1 6.inverse1*/
input = atoi(argv[3]); /*將數字輸入方式對應數字存入input:1.隨機輸入 2.自行輸入*/
float R[99][99], M1[99][99], M2[99][99], M[99][99]; //宣告陣列
if (N > 99) //若尺寸超過則終止程式
return;
for (i = 0; i < N; i++) { //矩陣初始化
for (j = 0; j < N; j++) {
R[i][j] = 0;
M1[i][j] = 0;
M2[i][j] = 0;
M[i][j] = 0;
}
}
switch (input) { //選擇數字輸入方式
case 1: if (function == 3 || function == 6) { //若選擇反矩陣運算函數,則使用M矩陣
srand(time(NULL));
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
M[i][j] = rand() % 100;
}
}
srand(time(NULL)); //若選擇非反矩陣運算函數,則使用M1、M2矩陣
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
M1[i][j] = rand() % 100;
M2[i][j] = rand() % 100;
}
}
break;
case 2: if (function == 3 || function == 6) { //若選擇反矩陣運算函數,則使用M矩陣
printf("Please enter %d numbers for matrix M:\n", N * N);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
scanf("%f", &M[i][j]);
}
}
else { //若選擇非反矩陣運算函數,則使用M1、M2矩陣
printf("Please enter %d numbers for matrix M1:\n", N * N);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
scanf("%f", &M1[i][j]);
}
printf("Please enter %d numbers for matrix M2:\n", N * N);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
scanf("%f", &M2[i][j]);
}
}
break;
}
switch (function) { //選擇運算函數並呼叫
case 1: add(R, M1, M2, N);
break;
case 2: multiplication(R, M1, M2, N);
break;
case 3: inverse(R, M, N);
break;
case 4: add1(*R, *M1, *M2, N);
break;
case 5: multiplication1(*R, *M1, *M2, N);
break;
case 6: inverse1(*R, *M, N);
break;
}
return 0;
}
view raw matrix.c hosted with ❤ by GitHub

沒有留言:

張貼留言