開始重新學習數學了,然而路途總是不那麼平坦,儘管是先挑選的最簡單的線性代數,然而一開始就進展不順
當然我承認數學一直都是乙個難以言說的傷痛,但是像什麼三階行列式計算還是老是算錯我就有點難以忍受了
於是編寫乙個程式解決行列式的計算問題,記得好像當初學線性代數的時候也想過程式設計實現,最終好像因為水平問題沒能成功?哎,反正也是很早之前的事情了。
廢話少說,先介紹一下大體的思路吧。核心的計算方法採用的是同濟大學數學系 工程數學線性代數第六版中的行列式定義,數表中項的全排列的冠以排列逆序確定的符號位的求和(描述不清,詳情參考標準表述),我記得我們學校的教材好像並沒有這些內容(lll¬ω¬)。於是乎實現方式完全依照定義的方法,在獲取到乙個矩陣之後,計算出其全排列,然後按排列值取對應項的乘積並計算排列的奇偶逆序確定是否需要乘以-1.
完整**直接貼上如下,主要流程就是從stdin讀取矩陣資料,計算出行列值,然後以行列值計算全排列,全排列的演算法是很久之前寫的了,相關細節都忘了,直接改了一下就拿來用了。得到全排列值後就按照定義計算即可。其中主要涉及了幾個簡單的數學計算比如al_factorial計算階乘,用來計算全排列需要的儲存空間,al_reverseidx計算逆序,直接按照定義來的,感覺可以有更高效的演算法,al_fullarray計算全排列。大部分**其實都是在處理io,理論上能夠處理各種不太完美的輸入,但是具體是否還有bug就不得而知了,可能還是存在問題的,不過本來也是寫著玩的,也不想過多糾纏於此了。
執行截圖如下:#include #include #include #include struct matrix
;#define matrix_init (struct matrix)
#define max_factorial 10
#define max_matrix max_factorial
static int* al_full_idx;
static int al_full_i;
int al_factorial(int n);
int al_fullarray(int* array, int len);
int al_reverseidx(int* array, int len);
int matrix_init(struct matrix* m, int r, int c, int* vals, size_t len)
if (len < (c * r) * sizeof(int))
if (r > max_matrix || c > max_matrix)
m->r = r;
m->c = c;
m->vals = vals;
return 0;
}int matrix_det(struct matrix* m)
if (m->r != m->c)
int* array = malloc(sizeof(int) * m->r);
for (int i = 0; i < m->r; i++)
if (al_fullarray(array, m->r) < 0)
free(array);
int fac = al_factorial(m->r);
int reverse;
int tmpres;
int res = 0;
for (int i = 0; i < fac; i++)
if (al_reverseidx(al_full_idx + i * m->r, m->r) % 2 != 0)
res += tmpres;
} free(al_full_idx);
return res;
}static void al_full(int* array, int idx, int len)
// printf("\n");
return ;
} else }
}int al_fullarray(int* array, int len)
al_full_idx = null;
al_full_i = 0;
if (len > max_factorial)
al_full_idx = malloc(sizeof(int) * al_factorial(len) * len);
if (al_full_idx == null)
al_full(array, 0, len);
return 0;
}int al_factorial(int n)
static int res = 1;
static int pre = 0;
if (pre == n)
res = 1;
for (int i = 2; i <= n; i++)
pre = n;
return res;
}int al_reverseidx(int* array, int len)
} }return c;
}void puts_int(int i)
int is_blank(char c)
return 0;
}int is_valid_input(char c)
return 0;
}void matrix_print(struct matrix* m)
puts("");
} return ;
}int main(void)
ccount = 0;
memset(cbuf, 0, sizeof(cbuf));
}} else if (is_valid_input(c))
else
}if (arr[0] != '\0') }
if (count == 0)
int row = (int)sqrt(count);
int col = row;
if (row * col != count)
return 0;
} if (matrix_init(&m, row, col, arr, sizeof(arr)) < 0)
printf("\nmatrix you input:\n");
matrix_print(&m);
puts_int(matrix_det(&m));
}
環境windows10,mingw64,powershell,無編譯選項
環境unbuntu1604,gcc,bash,-lm
注意,以終端裝置作為標準輸入時windows上使用ctrl z,ubuntu上使用ctrl d傳送eof標識,然而這個東西在兩種作業系統/shell上表現並不一致。目前已經發現的問題是在windows powershell輸入資料時,輸入完成後必須鍵入乙個換行符然後ctrl z在接乙個換行符完成輸入操作,否則會使得fgetc讀取到乙個不可列印字元導致出錯,(猜測是那個字元被讀入了)。具體shell如何處理標準輸入的eof問題本人尚未深入學習,有興趣的人可以自行查閱相關文件。
ubuntu上可以輸入完成之後換行接ctrl d,或者兩次ctrl d均可。
矩陣行列式
對於乙個 n 行 n 列的矩陣 a 有矩陣的行列式 常用 det a a 表示 如果將矩陣的每一行視為乙個 n 維向量,則 n 階行列式的意義可以看做是 有向長度 面積 體積在 n 為空間下的擴充套件 具體的例子 n 1 時,a a 即有向長度 n 2 時,a a a a a vec times v...
行列式計算(程式設計實現)
write programs that do one thing and do it well doug mcilroy unix哲學 如果你學過線代,又恰巧你是個coder,那麼你應該寫個計算行列式的program。計算行列式 數學知識 每行都按行座標排序,求出列座標排列的逆序數 根據逆序數的奇偶...
行列式與矩陣
說明 本公式只針對在二維或三通道的計算機視覺中所遇到的問題,不代表傳統意義上數學知識點範圍。矩陣的行列式,稱之為det,是基於矩陣所包含的行列資料計算得到的標量。本質上是乙個數。高階行列式計算比較複雜。對於三通道未進行壓縮的影象而言,描述該影象的矩陣所計算的det甚至手動計算是幾乎不可能的,故在這裡...