C语言实现线性代数中基的标准正交化
来源:互联网 发布:景观格局数据单位 编辑:程序博客网 时间:2024/05/22 07:05
线性代数中一个很重要的概念就是基,一组基是构成线性空间“最高效的方式“,即若多余这个向量个数会出现冗余,若少于这个向量个数会出现无法构成该向量空间。由一般向量构成的一组基往往不是标准正交的,所以需要进行标准正交化!
线性代数“基“的概念在很多领域都有应用,包括机器人学,图像处理,数据降维等,具体可以参考相关线性代数教材。
本文采用C语言实现了基的标准正交化,正交化方法为格兰姆-施密特正交化(参见相关线性代数教材或维基百科)。程序功能为:询问用户输入向量的维数,用户输入一组基,构成n*n的矩阵(为了符合输入习惯,采用行向量的方式进行输入),然后对矩阵进行转置,将行向量变为列向量(符合线性代数的习惯),在进行判断之前,先判断用户输入的向量能否构成一组基,判断方式在isInverse()这个函数中,采用的是消元法判断矩阵是否可逆,若可逆则进行正交化,若不可逆,输出该矩阵不可逆,退出程序,具体程序如下:
/*================================================== # Author: Joker@HIT NolanRobot@163.com # Filetype: C source code # Environment: Linux & Ubuntu 14.04 # Tool: Vim & Gcc # Date: Sat Aug 20 2016 # Descprition: Input a couple of basis as rows of a matrix. the program tansposes it,and examine it's inverse whether exists or not! If exists, orthogonizeit standardly!==================================================*/#include<stdio.h>#include<stdlib.h>#include<stdbool.h>#include<math.h>void transpose(int, double [*][*]);void show_matrix(int, double [*][*]);void orthogonize(int, double [*][*]);bool isInverse(int, double [*][*]);void exchange(int, int, double [*][*]);int main(void){int dimention, i, j;bool judge;printf("Enter the dimention of the basis: ");scanf("%d", &dimention);double basis_matrix[dimention][dimention];printf("Input the basis (as rows of the matrix):\n");for(i=0;i<dimention;i++)for(j=0;j<dimention;j++)scanf("%lf", *(basis_matrix+i)+j);transpose(dimention, basis_matrix);printf("The matrix you input as follow:\n");show_matrix(dimention, basis_matrix);judge = isInverse(dimention, basis_matrix);if(!judge){printf("The column vector of matrix can't consists of the basis!\n");exit(1);}printf("The standard orthogonal basis matrix as follow:\n");orthogonize(dimention, basis_matrix);show_matrix(dimention, basis_matrix);return 0;}void transpose(int dim, double matrix[dim][dim]){int i, j;double replica[dim][dim];for(i=0;i<dim;i++)for(j=0;j<dim;j++)*(*(replica+i)+j) = *(*(matrix+i)+j);for(i=0;i<dim;i++)for(j=0;j<dim;j++)*(*(matrix+i)+j) = *(*(replica+j)+i);return;}void show_matrix(int dim, double matrix[dim][dim]){int i, j;for(i=0;i<dim;i++){for(j=0;j<dim;j++)printf("%-9.3f", *(*(matrix+i)+j));putchar('\n');}return;}void orthogonize(int dim, double matrix[dim][dim]){int i, j, k;double numerator, demoninator;double proj_vector[dim];for(i=1;i<dim;i++){for(k=0;k<dim;k++)proj_vector[k] = 0;for(j=0;j<i;j++){numerator = demoninator = 0;for(k=0;k<dim;k++){numerator += matrix[k][i] * matrix[k][j];demoninator += matrix[k][j] * matrix[k][j];}for(k=0;k<dim;k++)proj_vector[k] += numerator / demoninator * matrix[k][j];}for(k=0;k<dim;k++)matrix[k][i] = matrix[k][i] - proj_vector[k];}for(i=0;i<dim;i++){demoninator = 0;for(j=0;j<dim;j++)demoninator += matrix[j][i] * matrix[j][i];for(j=0;j<dim;j++)matrix[j][i] = matrix[j][i] / sqrt(demoninator);}return;}bool isInverse(int dim, double matrix[dim][dim]){double replica[dim][dim];double coef;int i, j, k;bool result = true;for(i=0;i<dim;i++)for(j=0;j<dim;j++)replica[i][j] = matrix[i][j];for(i=0;i<dim-1;i++){exchange(dim, i, replica);if(fabs(replica[i][i])<0.00001){result = false;break;}for(j=i+1;j<dim;j++){coef = replica[j][i] / replica[i][i];for(k=0;k<dim;k++)replica[j][k] = replica[j][k] - coef * replica[i][k];}}if(fabs(replica[dim-1][dim-1])<0.00001)result = false;return result;}void exchange(int dim, int flag, double matrix[dim][dim]){double temp[dim];int i, j;for(i=flag+1;i<dim;i++)if(fabs(matrix[flag][flag])<fabs(matrix[i][flag])){for(j=0;j<dim;j++){temp[j] = matrix[flag][j];matrix[flag][j] = matrix[i][j];matrix[i][j] = temp[j];}}return;}
运行结果如下图所示:
其实上述代码在exchange()函数中可以进行一定的改进,采用指针数组的方式,然后排序操作是对指针进行排序,而不是对数组进行排序,优化程序运行时间和空间!
若是读者对代码有什么意见,欢迎留言或者邮箱探讨
0 0
- C语言实现线性代数中基的标准正交化
- 线性代数(三十九) :格拉姆-施密特正交化与标准正交基
- 【线性代数】标准正交矩阵与Gram-Schmidt正交化
- matlab-线性代数 施密特正交化
- 漫步线性代数十七——正交基和格拉姆-施密特正交化(上)
- 漫步线性代数十八——正交基和格拉姆-施密特正交化(下)
- 标准正交基
- MIT18.06线性代数课程笔记17:正交标准矩阵
- matlab-线性代数 正交矩阵的判断
- Matlab与线性代数--矩阵的正交分解
- 线性代数 -- 正交矩阵和Gram-Schmidt正交化
- 标准Gabor滤波器的C语言实现
- C语言标准库函数getenv的实现
- C语言中常用的标准库函数
- C语言标准库string.h中常用的字符串函数的实现
- C语言的标准
- C语言的标准
- C语言的标准
- 【深度学习】环境配置之Anaconda安装
- ICT:IT与CT的融合之路
- iOS中通知中心NSNotificationCenter应用总结
- volley二次封装
- log4net使用教程
- C语言实现线性代数中基的标准正交化
- Unity 2D 终结手册 (4) - 精灵打包_Unity3d 开发技术
- openwrt下载代码的网站
- Flex入门--Flex基本语法
- 【转载】牛客网Java面试题
- 将HTML5 Canvas的内容保存为图片借助toDataURL实现
- 不进则退|进取,可以解决一切问题.
- 2160: 拉拉队排练
- QT:打包