基于塞尔维斯特准则的二次型标量函数的正定性判断

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
cout<<"Fra Baidu bibliotek输入方阵的维数:";
cin>>n;
a=new double[n*n];
cout<<"请输入方阵:"<<endl;
for(int i=0;i<n*n;i++)
cin>>a[i];
A.CreateMat(n,n,DOUBLE,a);//创建矩阵A并赋值
cout<<"原矩阵:"<<endl;
void Judge_ZD(Mat A)
{
int i, n=A.cols;
int flag;//flag用来判断正负定
double *r;
r = new double[n];// r用来存放各△的值
r[n-1]=Det(A);//求出△n
for(i=n-1; i>0; i--)
{
YuZiShi(A, i,i, &A);//求出矩阵A(i,i)的余子式并覆盖在A中
A.PrintMat();//输出原矩阵
cout<<endl;
Judge(A);//判断是否为实对数矩阵、正定性
//system("pause");
}
(3)Base.cpp
#include "base.h"
#include "mat.h"
//============用递归法求行列式的值(并返回)=================
switch(flag)
{
case 0:cout<<"该二次型标量函数V(x)既不是正定的也不是负定的"<<endl;
break;
case 1:cout<<"该二次型标量函数V(x)是负定的"<<endl;
break;
case 2:cout<<"该二次型标量函数V(x)是正定的"<<endl;
break;
{
printf("该矩阵的行与列不相等");
return 0;
}
return Fun( A.cols, A.data);
}
//求A矩阵的余子式,结果放在矩阵B中
void YuZiShi(Mat A, int x, int y, Mat* B)
{
int num=0;
int n=A.cols;
B->CreateMat(n-1, n-1, DOUBLE);//创建矩阵B用来存放余子式
{
int i;
this->rows=r;
this->cols=c;
this->type=type;
data = new double[r*c];//为矩阵申请(r*c)大小的内存空间。
if(A!=NULL)switch(type)
{
case INT:
for(i=0; i<r*c; i++)//循环赋值
data[i] = (int)A[i];
break;
case DOUBLE:
for(i=0; i<r*c; i++)
data[i] = (double)A[i];
break;
default:
data = NULL;
break;
}
else
{
for(i=0; i<r*c; i++)//循环赋值
data[i] = 0;
解题步骤如下:
赛尔维斯特判据

根据赛尔维斯特(Sylvester),可以通过判断对称矩阵P的定号性来确定二次型函数的定号性。

矩阵P正定的充要条件是所有的顺子主子式都是正的,即 ;
矩阵P负定的充要条件是
(三)程序设计流程图:
(四)程序设计实现
输入:矩阵A,n阶方阵
输出:二次型标量函数V(x)是正定的、负定的、既不是正定的也不是负定的
}
}
void Judge(Mat A)
{
int flag=0;
for(int i=0; i<A.rows; i++)
{//判断是否为实对数矩阵
for(int j=i+1; j<A.cols; j++)
{
if(A.Read(i,j) != A.Read(j,i))
{
printf("P(%d,%d)!= P(%d,%d)\n",i,j,j,i);
default:break;
}
printf("\n");
}
}
}
double Mat::Read(int i,int j)
{
return this->data[i*cols+j];
}
(2)Main.cpp
#include "base.h"
void main()
{
Mat A;
int n;
double* a;
}
}
void Mat::PrintMat()
{
int j;
if(data==NULL)cout<<endl<<"还没给该矩阵赋值"<<endl;
else
{
for(int i=0;i<rows;i++)
{
switch(type)
{
case INT:
case DOUBLE:
for(j=0;j<cols;j++)cout<<”\t”<<data[i*cols+j];
for(int c=0;c<n;c++)
{
for(int i=1;i<n;i++)//实现将余子式存入数组b中
{
for(int j=0;j<n;j++)
{
if(j==c)continue;
b[num++]=a[i*n+j];
}
}
num=0;
if(c%2==0)x=1;//i+j(此时行0,故只考虑列)为偶数,加法预算
flag=1;
}
}
}
if(flag)
cout<<"该矩阵不是实对数矩阵"<<endl;
else Judge_ZD(A);
}
for(int i=0; i<n; i++)//实现将a(x,y)的余子式存入B矩阵
{
if(i==x)continue;
for(int j=0; j<n; j++)
{
if(j==y)continue;
B->data[num++] = A.Read(i,j);
}
}
num=0;
}
//========================判断正定性============================
(五)结果
(六)程序验证与测试
包含三个cpp文件
Mat.cpp包含类Mat的各成员函数、
Base.cpp实现矩阵的一些基本操作
包括:求行列式的值、
矩阵的余子式、
判断正定性
(1)Mat.cpp
#include "Mat.h"
/********类Mat成员函数************/
void Mat::CreateMat(int r,int c,int type,double *A)
窗体顶端
基于塞尔维斯特准则的二次型标量函数的正定性判断
((窗体顶端
窗体底端
(一)任务要求:
参照Leverrier-Faddeeva递推算法的程序设计范例,编写程序实现基于塞尔维斯特准则的二次型标量函数的正定性判断。
要求:编写程序设计报告,含:任务需求分析、程序流程、实现方法、测试验收、源代码等
(二)解析:
switch((i+1)%2)
{
case 0://若偶数<=0,既不是正定也不是负定
if(r[i]<=0)flag=0;
break;
case 1://若奇数>=0,既不是正定也不是负定
if(r[i]>=0)flag=0;
break;
}
}
for(i=0; i<n; i++)cout<<"△"<<i+1<<" = "<<r[i]<<endl;//输出各△的值
double Fun( int n, double *a )
{
if(1==n)return a[0];
double* b;
double sum = 0;//i,j为行与列,sum为行列式的值
int x=0,num=0; //用x判断(-1)^(i+j)的正负
b=new double[(n-1)*(n-1)];//数组用来存放代数余子式
else x=-1;//i+j为奇数,减法运算
sum += a[c] * Fun(n-1,b) * x;//计算行列式的值
}
return sum;
}
//============求行列式的值(并返回)=================
double Det(Mat A)
{
if(A.cols != A.rows)
r[A.cols-1]=Det(A);
}
if(r[0]==0)flag=0;
else if(r[0]>0)//判断△1,若>0判断是否为正定
{//若<0判断是否为负定,否则都不是
flag=2;
for(i=1; i<n; i++)
if(r[i]<=0)flag=0;
}
else
{
flag=1;
for(i=1; i<n; i++)
相关文档
最新文档