大家还记得施密特正交规范化吗?不记得了?那么请David给大家介绍一下:
我们要将向量组
正交规范化。
(1). 正交化:
(2). 规范化:对所有的
这样,求出来的即为正交规范化的向量。
David每次一看这个式子就头疼。为了David的头的健康着想,请你给他写一个程序,按照以上规则完成正交规范化的工作。
注:请不要交换向量的顺序。
输入格式:
第1行,输入整数n,d。分别表示向量的数目和维数
第2~n+1行,每行d个浮点数,用空格隔开,表示一个向量
输出格式:
共n行,每行输出d个浮点数(保留2位小数),用空格隔开,表示一个向量
样例输入:
3 3
1 4 6
2 4 5
2 6 4
样例输出:
0.14 0.55 0.82
0.89 0.31 -0.35
-0.44 0.78 -0.44
数据范围:
1≤n≤10
1≤d≤10
-100≤其他数值≤100
#include <stdio.h>
#include <math.h>
/*为了David的头的健康着想,请你给他写一个程序,按照以上规则完成正交规范化的工作。
注:请不要交换向量的顺序。
输入格式:
第1行,输入整数n,d。分别表示向量的数目和维数
第2~n+1行,每行d个浮点数,用空格隔开,表示一个向量
输出格式:
共n行,每行输出d个浮点数(保留2位小数),用空格隔开,表示一个向量
样例输入:
3 3
1 4 6
2 4 5
2 6 4
样例输出:
0.14 0.55 0.82
0.89 0.31 -0.35
-0.44 0.78 -0.44
数据范围:
1≤n≤10
1≤d≤10
-100≤其他数值≤100
*/
double Inner_fact(double a[],double b[],int d)//求向量内积
{
double sum=0;
for(int i=0;i<d;i++)
{
sum+=a[i]*b[i];
}
return sum;
}
int main()
{
int n,d;
scanf("%d %d",&n,&d);//维数和向量数
double alpha[10][10]={0};//原始向量
double beta[10][10]={0};
double eta[10][10]={0};
double factor;//暂存
for(int i=0;i<n;i++)
{
for(int j=0;j<d;j++)
{
scanf("%lf",&alpha[i][j]);//存原始向量
}
}
for(int i=0;i<n;i++)
{
for(int k=0;k<d;k++)//由题目样例,向量为横向量,元素左到右
{
beta[i][k]=alpha[i][k];//暂存向量
}
for(int j=0;j<i;j++)
{ //求公式中用来减的向量的系数
factor=Inner_fact(alpha[i],beta[j],d) / Inner_fact(beta[j],beta[j],d);
//分子 //分母
for(int k=0;k<d;k++)
{
beta[i][k]-=factor*beta[j][k];//公式求 正交化矩阵
} //向量减向量就是对应元素相减
}
}
for(int i=0;i<n;i++)
{
factor=sqrt(Inner_fact(beta[i],beta[i],d));//求向量的模 用于规范化
for(int k=0;k<d;k++)
{
eta[i][k]=beta[i][k]/factor;//正交化,存结果
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<d;j++)//输出结果
{
printf("%.2lf",eta[i][j]);
if(j!=d-1)//只要不是最后一个元素,输出空格
{
printf(" ");
}
}
printf("\n");
}
return 0;
}