# hw1 ###### tags: `tutorials` ```c++ #include <iostream> #include <iomanip> using namespace std; void printMatrix(float arr[][4]); void qr_decomposition(float arr[4][4], int temp); float global[4][4]; int main() { // input matrix float arr[4][4] = { {1,2,3,4}, {0,-1,3,2}, {0,0,3,3}, {0,0,0,2}}; qr_decomposition(arr, 1); } // print the 4x4 matrix void printMatrix(float arr[][4]) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++)cout << fixed <<setprecision(5) << arr[i][j] << " "; cout << endl; }cout << endl; } // assign one matrix to another void copyMatrix(float a[4][4], float b[4][4]) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { a[i][j] = b[i][j]; } } } // multiply two matrix and assign the value result to global variable void multiply(float a[4][4], float b[4][4]) { for (int i = 0; i < 4; i++) { float temp = 0; for (int j = 0; j < 4; j++) { global[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j] + a[i][3] * b[3][j]; } } } // caculate the value of two matrix float multiply_1d(float a[4], float b[4]) { float temp = 0; for (int i = 0; i < 4; i++) { temp += (a[i] * b[i]); } return temp; } /* apply QR algorithm @param arr : input matrix @param temp : iterator time */ void qr_decomposition(float matrix[4][4], int temp) { if (temp > 15) { cout << "最後結果" << endl; printMatrix(matrix); return; } float q[4][4]; float q_transpose[4][4]; // initialize matrix q and matrix q_transpose copyMatrix(q, matrix); copyMatrix(q_transpose, matrix); // caculate Q1~Q4 and assign to matrix q for (int i = 0; i < 4; i++) { for (int a = 0; a < 4; a++) { for (int b = 0; b < 4; b++) { q_transpose[a][b] = q[b][a]; } } /* iterate Q1~Q4 the Qk needs k-1 times iteration */ int iterator = i; while (iterator) { // do the prog algorithm for (int j = 0; j < 4; j++) { q[j][i] -= (multiply_1d(q_transpose[i], q_transpose[iterator -1]) / multiply_1d(q_transpose[iterator - 1], q_transpose[iterator - 1])) * q[j][iterator - 1]; } iterator--; } } /* * * // 將每個 q 矩陣列進行單位向量化 (e.g. A/|A|) for (int i = 0; i < 4; i++) { float base = 0; for (int j = 0; j < 4; j++) { base += pow(q[j][i],2); } for (int j = 0; j < 4; j++) { q[j][i] /= sqrt(base); } } // 計算出 R 矩陣 (R = q_transpose*A) float r[4][4]; for (int a = 0; a < 4; a++) { for (int b = 0; b < 4; b++) { q_transpose[a][b] = q[b][a]; } } multiply(q, matrix); memcpy(r, global, 4 * 4 * sizeof(float)); multiply(r, q_transpose); qr_decomposition(global, temp + 1); */ float matrix_temp[4][4]; // non change original matrix copyMatrix(matrix_temp, matrix); // 找出特徵向量,先遍歷四個特徵值 for (int i = 3; i < 4; i++) { cout << "EigenValue : " << q[i][i] << endl; cout << endl; // 遍歷整個矩陣,計算(A+I) cout << "A-λI" << endl; copyMatrix(matrix, matrix_temp); for (int j = 0; j < 4; j++) { matrix[j][j] -= q[i][i]; } printMatrix(matrix); // 以高斯消去法求 homogeneous 線性方程組 // 先把不為零的首項都變一 for (int row = 0; row < 4; row++) { int j = 0; while (j < 4) { if (matrix[row][j] != 0) { for (int k = 3; k >= 0; k--) { matrix[row][k] /= matrix[row][j]; } break; } j++; } } cout << endl; cout <<"首項化為1"<< endl; printMatrix(matrix); //進行高斯消去,從底部開始 for (int row = 3; row >= 0; row--) { if (!matrix[row][row])continue; // 剩下幾行 for (int j = row - 1; j >= 0; j--) { float mag = matrix[j][row]; // 幾個元素要處理 for (int k = row ; k < 4; k++) { matrix[j][k] -= matrix[row][k]*mag; } } } // 找特徵矩陣,先求最大交集是哪一個 float eigenVector[5] = {0,0,0,0,0}; // 去掉一定為零行(方便程式而已) for (int row = 0; row < 4; row++) { int count = 0; for (int col = 0; col < 4; col++) { if (matrix[row][col] == 0) { count++; } } if (count == 3) { for (int j = 0; j < 4; j++) { matrix[row][j] = 0; } } } cout << endl; cout << "去掉一定為零行(方便程式而已)" << endl; printMatrix(matrix); // 遍歷列,出現最多次非零值的其特徵向量為1 int most = 0; int last_time = 0; for (int col = 0; col < 4; col++) { int count = 0; for (int j = 0; j < 4; j++) { if (matrix[j][col] != 0) { count++; } } if (count == 0) continue; if (count == last_time and most==0) { most = col; last_time = count; } else if (count > last_time) { most = col; last_time = count; } } eigenVector[most+1] = 1; cout << endl; cout << "找到設為 x = 1 的列" << endl; cout << most << endl; // 遍歷行,若其主對角線值存在則計算其特徵向量值,不存在(或全零)則跳過 for (int row = 0; row < 4; row++) { int count = 0; for (int col = 0; col < 4; col++) { if (matrix[row][col] == 0) { count++; } } if (count == 4)continue; eigenVector[row + 1] = -(matrix[row][most]); } cout << endl; cout << "主對角線值不為零則計算其特徵向量值" << endl; printMatrix(matrix); // 打印特徵向量 cout << "EigenVector : ["; for (int j = 1; j < 5; j++) { if (j == 4) { cout << eigenVector[j] << "]" << endl; break; } cout << eigenVector[j] << ","; } cout << "================" << endl; } } ```