⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threesamplet.cpp

📁 基于vc++的三次样条类函数的计算 ThreeSampleT
💻 CPP
字号:
// ThreeSampleT.cpp: implementation of the CThreeSampleT class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "StudyThreeSampleT.h"
#include "ThreeSampleT.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CThreeSampleT::CThreeSampleT()
{

}

CThreeSampleT::~CThreeSampleT()
{

}

void CThreeSampleT::swap(double &a, double &b)
{
 double temp; 
 temp=a; 
 a=b; 
 b=temp; 
}
//求出一阶导数B
bool CThreeSampleT::GuassSolve(double *A, double *B, double *X, int n)
{
  int i,j,k,row; 
  for(k=0;k<n-1;k++) 
  {  
    double max=0.0; 
    for(i=k;i<n;i++) 
	{  
      if(fabs(A[i*n+k])>max) 
	  {  
        max=fabs(A[i*n+k]); 
        row=i; 
	  } 
	} 
    if(max==0.0) return false; 
    if(row!=k) 
	{ 
      for(j=0;j<n;j++) 
        swap(A[row*n+j],A[k*n+j]); 
      swap(B[row],B[k]); 
	} 
    for(i=k+1;i<n;i++) 
	{  
        double m=A[i*n+k]/A[k*n+k]; 
        for(j=k+1;j<n;j++) 
		{  
           A[i*n+j]=A[i*n+j]-m*A[k*n+j]; 
		}  
        B[i]=B[i]-m*B[k]; 
	}  
  }  
  X[n-1]=B[n-1]/A[n*n-1]; 
  for(k=n-2;k>=0;k--) 
  { 
     double sum=0.0; 
     for(j=k+1;j<n;j++) 
       sum+=A[k*n+j]*X[j]; 
     X[k]=(B[k]-sum)/A[k*n+k]; 
  } 
return true; 
}
//依据边界条件来重新修正参数
void CThreeSampleT::Apend(double* miu, double *rmd, double *d, double *x, double *y, double *h, double pf1, double pf2, double ppf1, double ppf2, int n, int flag)
{
  switch(flag) 
  {  
    case 0: 
      miu[n-1]=1; 
      rmd[0]=1; 
      d[0]=6*((y[1]-y[0])/(x[1]-x[0])-pf1)/h[0]; 
      d[n-1]=6*(pf2-(y[n-1]-y[n-2])/(x[n-1]-x[n-2]))/h[n-2]; 
    break; 
    case 1: 
      rmd[0]=miu[n-1]=0; 
      d[0]=2*ppf1; 
      d[n-1]=2*ppf2; 
    break; 
    case 2: 
       rmd[0]=rmd[n-1]=h[0]/(h[n-1]+h[0]); 
       miu[0]=miu[n-1]=1-rmd[n-1]; 
       d[0]=d[n-1]=6*((y[1]-y[0])/(x[1]-x[0])-(y[n-1]-y[n-2])/(x[n-1]-x[n-2]))/(h[0]+h[n-2]); 
    break; 
  } 
}
//x,y,分别是样条的坐标,n代表点的个数
void CThreeSampleT::T(double *x, double *y,double* M,int n)
{
int flag=0; 
double   pf1=3.0; 
double   pf2=-4.0; 
double   ppf1=0; 
double   ppf2=0; 
double * h=new double [n]; //h应该是存放区间的大小
double * miu=new double [n]; //minu存放一阶的数据
double * rmd=new double [n]; 
double * d=new double[n]; 

memset(d,0,n*sizeof(double)); 
memset(rmd,0,n*sizeof(double)); 
memset(miu,0,n*sizeof(double)); 
//存放区间的长度
for(int i=1;i<n;i++) 
{ 
	h[i-1]=x[i]-x[i-1]; 
} 
//
for(i=1;i<n-1;i++) 
{ 
	rmd[i]=h[i]/(h[i-1]+h[i]); //三次样条中求的其中一个系数
	miu[i]=h[i-1]/(h[i-1]+h[i]); //三次样条中求的其中另外一个系数
	d[i]=6*((y[i+1]-y[i])/(x[i+1]-x[i])-(y[i]-y[i-1])/(x[i]-x[i-1]))/(h[i-1]+h[i]); 
   //求出d
} 
//依靠边界条件来修正前面计算的系数  rmd,miu,d
Apend(miu,rmd,d,x,y,h,pf1,pf2,ppf1,ppf2,n,0); 
//构建一个矩阵A[n*n]
//构建一个一阶导数M
double * A=new double [n*n]; 
//,* M=new double [n]
memset(A,0,n*n*sizeof(double)); 

//给矩阵赋值
for(i=1;i<n-1;i++) 
{ 
	A[i*n+i]=2; //
	A[i*n+i-1]=miu[i]; 
	A[i*n+i+1]=rmd[i]; 
} 

if(n==2) //如果数据只有2个点时的矩阵A要特别处理
{ 
	A[0]=2; 
	A[n-2]=miu[0]; 
	A[1]=rmd[0]; 
	A[(n-1)*n+n-1]=2; 
	A[(n-1)*n+n-2]=miu[n-1]; 
	A[(n-1)*n+1]=rmd[n-1]; 
} 
else //另外对两个对角线的特殊点进行处理
{ 
    A[0]=2; 
    A[1]=rmd[0]; 
    A[(n-1)*n+n-1]=2; 
    A[(n-1)*n+n-2]=miu[n-1]; 
} 
//求出一阶导数M
GuassSolve(A,d,M,n); 
//将求出一阶导数打印出来
//for(i=0;i<n;i++) 
//{ 
//	printf("M[%d]=%f\n",i+1,M[i]); 
//} 

}
//x,y,构成样条的基本点
void CThreeSampleT::Initiate(double *x, double *y)
{
    x[0]=27.7; 
	y[0]=4.1; 

	x[1]=28; 
	y[1]=4.3; 

	x[2]=29; 
	y[2]=4.1; 

	x[3]=30; 
	y[3]=3.0; 
}
//得到利用三次样条的插值--针对单点
double CThreeSampleT::GetInterpolationValue(double *M, double *OriginX, double *OriginY, int n, double x)
{
  double* h=new double[n];
  memset(h,0,sizeof(double)*n);
  //存放区间的长度
  for(int i=1;i<n;i++) 
  {  
	  h[i-1]=OriginX[i]-OriginX[i-1]; 
  } 
  //得到x目前所处的区间号
  int RegionNo=-1;
  
  //得到需要插值的数所在区间
  RegionNo=GetXRegionNo(OriginX,n,x);

  double S=-99999.0f;
  
  int IndexNo=RegionNo-1;//应用号是区间号-1
  int j=IndexNo;
  S=M[j]*pow(OriginX[j+1]-x,3)/(6*h[j])
	  +M[j+1]*pow(x-OriginX[j],3)/(6*h[j])
	  +(OriginY[j]-M[j]*pow(h[j],2)/6)*((OriginX[j+1]-x)/h[j])
	  +(OriginY[j+1]-M[j+1]*pow(h[j],2)/6)*((x-OriginX[j])/h[j]);
  return S;


}

int CThreeSampleT::GetXRegionNo(double *OriginX, int n, double x)
{
  int RegionNo=-1;
  for(int i=1;i<n;i++)
  {
	  if(x>OriginX[i-1]&&x<OriginX[i])
	  {
         RegionNo=i;
		 break;
	  }
	  else
	  {
		  if(x==OriginX[0])
		  {
			  RegionNo=i;
			  break;
		  }
		  else
		  {
              if(x==OriginX[i])
			  {
				  RegionNo=i;
				  break;
			  }
			  else
			  {
				  if(x==OriginX[n-1])
                  {
					  RegionNo=n-1;
					  break;
				  }

			  }
		  }
	  }
  }
  return RegionNo;
}
//针对单点的案例
double CThreeSampleT::CaseTest()
{
  int n=4; 
  double * x=new double[n]; 
  double * y=new double[n]; 
  double * M=new double[n];
  Initiate(x,y); 

  T(x,y,M,n); 
  double Temp;
  Temp=GetInterpolationValue(M,x,y,n,28.5f);
  delete x;
  x=NULL;
  delete y;
  y=NULL;
  delete M;
  M=NULL;
  return Temp;
}
//针对多点的案例
void CThreeSampleT::GetInterpolationValue_MultiP(double *M, double *OriginX, double *OriginY, int n, double *OutputX, double *OutputY,int MultiPN)
{
 double x=-9999.0f;
 for(int i=0;i<MultiPN;i++)
 {
	 x=OutputX[i];
	 OutputY[i]=GetInterpolationValue(M,OriginX,OriginY,n,x);
 }
}

void CThreeSampleT::CaseTest_MultiP()
{
  int n=4; 
  double * x=new double[n]; 
  double * y=new double[n]; 
  double * M=new double[n];
  double * OutputX=new double[n];
  double * OutputY=new double[n];
  
  memset(OutputY,0,sizeof(double)*n);

  OutputX[0]=27.9;
    OutputX[1]=28.5;
	  OutputX[2]=29.2;
	    OutputX[3]=29.6;

  Initiate(x,y); 

  T(x,y,M,n); 
  double Temp;
  GetInterpolationValue_MultiP(M,x,y,n,OutputX,OutputY,n);
  delete x;
  x=NULL;
  delete y;
  y=NULL;
  delete M;
  M=NULL;
 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -