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

📄 lequations.cpp

📁 用牛顿法求解积分
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            t=pDataConst[u]; 
			pDataConst[u]=pDataConst[v]; 
			pDataConst[v]=t;
        }
        
		for (j=0;j<=nBandWidth-1;j++)
        { 
			u=k*nBandWidth+j; 
			v=is*nBandWidth+j;
            t=pBandData[u]; 
			pBandData[u]=pBandData[v]; 
			pBandData[v]=t;
        }
        
		for (j=0;j<=m-1;j++)
        { 
			u=k*m+j; 
			pDataConst[u]=pDataConst[u]/pBandData[k*nBandWidth];
		}
        
		for (j=1;j<=nBandWidth-1;j++)
        { 
			u=k*nBandWidth+j; 
			pBandData[u]=pBandData[u]/pBandData[k*nBandWidth];
		}
        
		for (i=k+1;i<=ls;i++)
        { 
			t=pBandData[i*nBandWidth];
            for (j=0;j<=m-1;j++)
            { 
				u=i*m+j; 
				v=k*m+j;
                pDataConst[u]=pDataConst[u]-t*pDataConst[v];
            }
            
			for (j=1;j<=nBandWidth-1;j++)
            { 
				u=i*nBandWidth+j; 
				v=k*nBandWidth+j;
                pBandData[u-1]=pBandData[u]-t*pBandData[v];
            }
            
			u=i*nBandWidth+nBandWidth-1; pBandData[u]=0.0;
        }
        
		if (ls!=(n-1)) 
			ls=ls+1;
    }
    
	p=pBandData[(n-1)*nBandWidth];
    if (p == 0.0)
	{
		delete[] pBandData;
		return FALSE;
	}

    for (j=0;j<=m-1;j++)
    { 
		u=(n-1)*m+j; 
		pDataConst[u]=pDataConst[u]/p;
	}
    
	ls=1;
    for (i=n-2;i>=0;i--)
    { 
		for (k=0;k<=m-1;k++)
        { 
			u=i*m+k;
            for (j=1;j<=ls;j++)
            { 
				v=i*nBandWidth+j; 
				is=(i+j)*m+k;
                pDataConst[u]=pDataConst[u]-pBandData[v]*pDataConst[is];
            }
        }
        
		if (ls!=(nBandWidth-1)) 
			ls=ls+1;
    }
    
	delete[] pBandData;

	return TRUE;
}

// 求解对称方程组的分解法
BOOL CLEquations::GetRootsetDjn(CMatrix& mtxResult)
{ 
	int i,j,l,k,u,v,w,k1,k2,k3;
    double p;

	CMatrix mtxCoef = m_mtxCoef;
	mtxResult = m_mtxConst;
	int n = mtxCoef.GetNumColumns();
	int m = mtxResult.GetNumColumns();
	double* pDataCoef = mtxCoef.GetData();
	double* pDataConst = mtxResult.GetData();

    if (pDataCoef[0] == 0.0)
		return FALSE;

    for (i=1; i<=n-1; i++)
    { 
		u=i*n; 
		pDataCoef[u]=pDataCoef[u]/pDataCoef[0];
	}
    
	for (i=1; i<=n-2; i++)
    { 
		u=i*n+i;
        for (j=1; j<=i; j++)
        { 
			v=i*n+j-1; 
			l=(j-1)*n+j-1;
            pDataCoef[u]=pDataCoef[u]-pDataCoef[v]*pDataCoef[v]*pDataCoef[l];
        }
        
		p=pDataCoef[u];
        if (p == 0.0)
			return FALSE;

        for (k=i+1; k<=n-1; k++)
        { 
			u=k*n+i;
            for (j=1; j<=i; j++)
            { 
				v=k*n+j-1; 
				l=i*n+j-1; 
				w=(j-1)*n+j-1;
				pDataCoef[u]=pDataCoef[u]-pDataCoef[v]*pDataCoef[l]*pDataCoef[w];
            }
            
			pDataCoef[u]=pDataCoef[u]/p;
        }
    }
    
	u=n*n-1;
    for (j=1; j<=n-1; j++)
    { 
		v=(n-1)*n+j-1; 
		w=(j-1)*n+j-1;
        pDataCoef[u]=pDataCoef[u]-pDataCoef[v]*pDataCoef[v]*pDataCoef[w];
    }
    
	p=pDataCoef[u];
    if (p == 0.0)
		return FALSE;

    for (j=0; j<=m-1; j++)
	{
	    for (i=1; i<=n-1; i++)
		{ 
			u=i*m+j;
			for (k=1; k<=i; k++)
			{ 
				v=i*n+k-1; 
				w=(k-1)*m+j;
				pDataConst[u]=pDataConst[u]-pDataCoef[v]*pDataConst[w];
			}
		}
	}

    for (i=1; i<=n-1; i++)
    { 
		u=(i-1)*n+i-1;
        for (j=i; j<=n-1; j++)
        { 
			v=(i-1)*n+j; 
			w=j*n+i-1;
            pDataCoef[v]=pDataCoef[u]*pDataCoef[w];
        }
    }
    
	for (j=0; j<=m-1; j++)
    { 
		u=(n-1)*m+j;
        pDataConst[u]=pDataConst[u]/p;
        for (k=1; k<=n-1; k++)
        { 
			k1=n-k; 
			k3=k1-1; 
			u=k3*m+j;
            for (k2=k1; k2<=n-1; k2++)
            { 
				v=k3*n+k2; 
				w=k2*m+j;
                pDataConst[u]=pDataConst[u]-pDataCoef[v]*pDataConst[w];
            }
            
			pDataConst[u]=pDataConst[u]/pDataCoef[k3*n+k3];
        }
    }
    
	return TRUE;
}

// 求解对称正定方程组的平方根法
BOOL CLEquations::GetRootsetCholesky(CMatrix& mtxResult)
{ 
	int i,j,k,u,v;
    
	CMatrix mtxCoef = m_mtxCoef;
	mtxResult = m_mtxConst;
	int n = mtxCoef.GetNumColumns();
	int m = mtxResult.GetNumColumns();
	double* pDataCoef = mtxCoef.GetData();
	double* pDataConst = mtxResult.GetData();
    
	if (pDataCoef[0] <= 0.0)
		return FALSE;

	pDataCoef[0]=sqrt(pDataCoef[0]);
    for (j=1; j<=n-1; j++) 
		pDataCoef[j]=pDataCoef[j]/pDataCoef[0];
    
	for (i=1; i<=n-1; i++)
    { 
		u=i*n+i;
        for (j=1; j<=i; j++)
        { 
			v=(j-1)*n+i;
            pDataCoef[u]=pDataCoef[u]-pDataCoef[v]*pDataCoef[v];
        }
        
		if (pDataCoef[u] <= 0.0)
			return FALSE;

        pDataCoef[u]=sqrt(pDataCoef[u]);
        if (i!=(n-1))
        { 
			for (j=i+1; j<=n-1; j++)
            { 
				v=i*n+j;
                for (k=1; k<=i; k++)
					pDataCoef[v]=pDataCoef[v]-pDataCoef[(k-1)*n+i]*pDataCoef[(k-1)*n+j];
                pDataCoef[v]=pDataCoef[v]/pDataCoef[u];
            }
        }
    }
    
	for (j=0; j<=m-1; j++)
    { 
		pDataConst[j]=pDataConst[j]/pDataCoef[0];
        for (i=1; i<=n-1; i++)
        { 
			u=i*n+i; 
			v=i*m+j;
            for (k=1; k<=i; k++)
				pDataConst[v]=pDataConst[v]-pDataCoef[(k-1)*n+i]*pDataConst[(k-1)*m+j];
            pDataConst[v]=pDataConst[v]/pDataCoef[u];
        }
    }
    
	for (j=0; j<=m-1; j++)
    { 
		u=(n-1)*m+j;
        pDataConst[u]=pDataConst[u]/pDataCoef[n*n-1];
        for (k=n-1; k>=1; k--)
        { 
			u=(k-1)*m+j;
            for (i=k; i<=n-1; i++)
            { 
				v=(k-1)*n+i;
                pDataConst[u]=pDataConst[u]-pDataCoef[v]*pDataConst[i*m+j];
            }
            
			v=(k-1)*n+k-1;
            pDataConst[u]=pDataConst[u]/pDataCoef[v];
        }
    }
    
	return TRUE;
}

// 求解大型稀疏方程组的全选主元高斯-约去消去法
BOOL CLEquations::GetRootsetGgje(CMatrix& mtxResult)
{ 
	int *pnJs,i,j,k,nIs,u,v;
    double d,t;
    
	CMatrix mtxCoef = m_mtxCoef;
	mtxResult = m_mtxConst;
	int n = mtxCoef.GetNumColumns();
	double* pDataCoef = mtxCoef.GetData();
	double* pDataConst = mtxResult.GetData();

	pnJs = new int[n];

    for (k=0; k<=n-1; k++)
    { 
		d=0.0;
        for (i=k; i<=n-1; i++)
		{
			for (j=k; j<=n-1; j++)
			{ 
				t=fabs(pDataCoef[i*n+j]);
				if (t>d) 
				{
					d=t; 
					pnJs[k]=j; 
					nIs=i;
				}
			}
		}

        if (d == 0.0)
		{
			delete[] pnJs;
			return FALSE;
		}

        if (nIs!=k)
        { 
			for (j=k; j<=n-1; j++)
            { 
				u=k*n+j; 
				v=nIs*n+j;
                t=pDataCoef[u]; 
				pDataCoef[u]=pDataCoef[v]; 
				pDataCoef[v]=t;
            }
            
			t=pDataConst[k]; 
			pDataConst[k]=pDataConst[nIs]; 
			pDataConst[nIs]=t;
        }
        
		if (pnJs[k]!=k)
        {
			for (i=0; i<=n-1; i++)
            { 
				u=i*n+k; 
				v=i*n+pnJs[k];
				t=pDataCoef[u]; 
				pDataCoef[u]=pDataCoef[v]; 
				pDataCoef[v]=t;
            }
		}

        t=pDataCoef[k*n+k];
        for (j=k+1; j<=n-1; j++)
        { 
			u=k*n+j;
            if (pDataCoef[u]!=0.0) 
				pDataCoef[u]=pDataCoef[u]/t;
        }
        
		pDataConst[k]=pDataConst[k]/t;
        for (j=k+1; j<=n-1; j++)
        { 
			u=k*n+j;
            if (pDataCoef[u]!=0.0)
            { 
				for (i=0; i<=n-1; i++)
                { 
					v=i*n+k;
                    if ((i!=k)&&(pDataCoef[v]!=0.0))
                    { 
						nIs=i*n+j;
                        pDataCoef[nIs]=pDataCoef[nIs]-pDataCoef[v]*pDataCoef[u];
                    }
                }
            }
        }
        
		for (i=0; i<=n-1; i++)
        { 
			u=i*n+k;
            if ((i!=k)&&(pDataCoef[u]!=0.0))
				pDataConst[i]=pDataConst[i]-pDataCoef[u]*pDataConst[k];
        }
    }
    
	for (k=n-1; k>=0; k--)
    {
		if (k!=pnJs[k])
        { 
			t=pDataConst[k]; 
			pDataConst[k]=pDataConst[pnJs[k]]; 
			pDataConst[pnJs[k]]=t;
		}
	}

    delete[] pnJs;
    
	return TRUE;
}

// 求解托伯利兹方程组的列文逊方法
BOOL CLEquations::GetRootsetTlvs(CMatrix& mtxResult)
{ 
	int i,j,k;
    double a,beta,q,c,h,*y,*s;

    int n = m_mtxCoef.GetNumColumns();

	mtxResult.Init(n, 1);
	double* x = mtxResult.GetData();

	double* pDataConst = m_mtxConst.GetData();

	double* t = new double[n];

	// 构造T数组
    for (i=0; i<n; ++i)
		t[i] = m_mtxCoef.GetElement(0, i);

	s = new double[n];
    y = new double[n];

    a=t[0];
    if (a == 0.0)
    { 
		delete[] s;
		delete[] y;
		delete[] t;
		return FALSE;
	}

    y[0]=1.0; 
	x[0]=pDataConst[0]/a;
    for (k=1; k<=n-1; k++)
    { 
		beta=0.0; 
		q=0.0;
        for (j=0; j<=k-1; j++)
        { 
			beta=beta+y[j]*t[j+1];
            q=q+x[j]*t[k-j];
        }
        
		if (a == 0.0)
		{ 
			delete[] s;
			delete[] y;
			delete[] t;
			return FALSE;
		}

        c=-beta/a; 
		s[0]=c*y[k-1]; 
		y[k]=y[k-1];
        if (k!=1)
        {
			for (i=1; i<=k-1; i++)
				s[i]=y[i-1]+c*y[k-i-1];
		}

        a=a+c*beta;
		if (a == 0.0)
		{ 
			delete[] s;
			delete[] y;
			delete[] t;
			return FALSE;
		}

        h=(pDataConst[k]-q)/a;
        for (i=0; i<=k-1; i++)
        { 
			x[i]=x[i]+h*s[i]; 
			y[i]=s[i];
		}
        
		x[k]=h*y[k];
    }
    
	delete[] s;
	delete[] y;
	delete[] t;

    return TRUE;
}

// 高斯-赛德尔迭代法
BOOL CLEquations::GetRootsetGaussSeidel(CMatrix& mtxResult, double eps /*= 0.000001*/)
{ 
	int i,j,u,v;
    double p,t,s,q;

    int n = m_mtxCoef.GetNumColumns();

	mtxResult.Init(n, 1);
	double* x = mtxResult.GetData();

	double* pDataCoef = m_mtxCoef.GetData();
	double* pDataConst = m_mtxConst.GetData();
    
	for (i=0; i<=n-1; i++)
    { 
		u=i*n+i; 
		p=0.0; 
		x[i]=0.0;
        for (j=0; j<=n-1; j++)
        {
			if (i!=j)
            { 
				v=i*n+j; 
				p=p+fabs(pDataCoef[v]);
			}
		}

        if (p>=fabs(pDataCoef[u]))
			return FALSE;
    }

    p=eps+1.0;
    while (p>=eps)
    { 
		p=0.0;
        for (i=0; i<=n-1; i++)
        { 
			t=x[i]; 
			s=0.0;
            for (j=0; j<=n-1; j++)
				if (j!=i) 
					s=s+pDataCoef[i*n+j]*x[j];

            x[i]=(pDataConst[i]-s)/pDataCoef[i*n+i];
            q=fabs(x[i]-t)/(1.0+fabs(x[i]));
            if (q>p) 
				p=q;
        }
    }
    
	return TRUE;
}

// 求解对称正定方程组的共轭梯度法
void CLEquations::GetRootsetGrad(CMatrix& mtxResult, double eps /*= 0.000001*/)
{ 
	int i,k;
    double *p,*r,*s,*q,alpha,beta,d,e;

    int n = GetNumUnknowns();

	mtxResult.Init(n, 1);
	double* x = mtxResult.GetData();

	CMatrix mtxP(n, 1);
    p = mtxP.GetData();

	double* pDataCoef = m_mtxCoef.GetData();
	double* pDataConst = m_mtxConst.GetData();

    r = new double[n];

    for (i=0; i<=n-1; i++)
    { 
		x[i]=0.0; 
		p[i]=pDataConst[i]; 
		r[i]=pDataConst[i]; 
	}
    
	i=0;
    while (i<=n-1)
    { 
		CMatrix mtxS = m_mtxCoef * mtxP;
	    s = mtxS.GetData();
        
		d=0.0; 
		e=0.0;
        for (k=0; k<=n-1; k++)
        { 
			d=d+p[k]*pDataConst[k]; 
			e=e+p[k]*s[k]; 
		}
        
		alpha=d/e;
        for (k=0; k<=n-1; k++)
			x[k]=x[k]+alpha*p[k];
        
		CMatrix mtxQ = m_mtxCoef * mtxResult;
	    q = mtxQ.GetData();
        
		d=0.0;
        for (k=0; k<=n-1; k++)
        { 
			r[k]=pDataConst[k]-q[k]; 
			d=d+r[k]*s[k]; 
		}
        
		beta=d/e; d=0.0;
        for (k=0; k<=n-1; k++) 
			d=d+r[k]*r[k];
        
		d=sqrt(d);
        if (d<eps)
			break;

        for (k=0; k<=n-1; k++)
			p[k]=r[k]-beta*p[k];
        
		i=i+1;
    }

	delete[] r;
}

// 求解线性最小二乘问题的豪斯荷尔德变换法
BOOL CLEquations::GetRootsetMqr(CMatrix& mtxResult, CMatrix& mtxQ, CMatrix& mtxR)
{ 
	int i,j;
    double d;

    int m = m_mtxCoef.GetNumRows();
    int n = m_mtxCoef.GetNumColumns();
	if (m < n)
		return FALSE;

	mtxResult = m_mtxConst;
	double* pDataConst = mtxResult.GetData();

	mtxR = m_mtxCoef;
	double* pDataCoef = mtxR.GetData();

    if (! mtxR.SplitQR(mtxQ))
		return FALSE;

	double* c = new double[n];
	double* q = mtxQ.GetData();

    for (i=0; i<=n-1; i++)
    { 
		d=0.0;
        for (j=0; j<=m-1; j++)
			d=d+q[j*m+i]*pDataConst[j];
    
		c[i]=d;
    }
    
	pDataConst[n-1]=c[n-1]/pDataCoef[n*n-1];
    for (i=n-2; i>=0; i--)
    { 
		d=0.0;
        for (j=i+1; j<=n-1; j++)
			d=d+pDataCoef[i*n+j]*pDataConst[j];
        
		pDataConst[i]=(c[i]-d)/pDataCoef[i*n+i];
    }
    
	delete[] c;

	return TRUE;
}

// 求解线性最小二乘问题的广义逆法
BOOL CLEquations::GetRootsetGinv(CMatrix& mtxResult, CMatrix& mtxAP, CMatrix& mtxU, CMatrix& mtxV, double eps /*= 0.000001*/)
{ 
	int i,j;
    
    int m = m_mtxCoef.GetNumRows();
    int n = m_mtxCoef.GetNumColumns();

	mtxResult.Init(n, 1);

	double* pDataConst = m_mtxConst.GetData();
	double* x = mtxResult.GetData();

	CMatrix mtxA = m_mtxCoef;

    if (! mtxA.GInvertUV(mtxAP, mtxU, mtxV, eps))
		return FALSE;

	double* pAPData = mtxAP.GetData();

    for (i=0; i<=n-1; i++)
    { 
		x[i]=0.0;
        for (j=0; j<=m-1; j++)
			x[i]=x[i]+pAPData[i*m+j]*pDataConst[j];
    }
    
	return TRUE;
}

// 病态方程组的求解
BOOL CLEquations::GetRootsetMorbid(CMatrix& mtxResult, int nMaxIt /*= 60*/, double eps /*= 0.000001*/)
{ 
	int i, k;
    double q, qq;
    
	// 方程的阶数
    int n = GetNumUnknowns();

	// 设定迭代次数, 缺省为60
	i = nMaxIt;
    
	// 用全选主元高斯消元法求解
	CLEquations leqs(m_mtxCoef, m_mtxConst);
	if (! leqs.GetRootsetGauss(mtxResult))
		return FALSE;
	double* x = mtxResult.GetData();
    
	q=1.0+eps;
    while (q>=eps)
    { 
		// 迭代次数已达最大值,仍为求得结果,求解失败
		if (i==0)
			return FALSE;
        
		// 迭代次数减1
		i=i-1;
		
		// 矩阵运算
		CMatrix mtxE = m_mtxCoef*mtxResult;
		CMatrix mtxR = m_mtxConst - mtxE;

		// 用全选主元高斯消元法求解
		CLEquations leqs(m_mtxCoef, mtxR);
		CMatrix mtxRR;
		if (! leqs.GetRootsetGauss(mtxRR))
			return FALSE;

		double* r = mtxRR.GetData();
        
		q=0.0;
        for ( k=0; k<=n-1; k++)
        { 
			qq=fabs(r[k])/(1.0+fabs(x[k]+r[k]));
            if (qq>q) 
				q=qq;
        }
        
		for ( k=0; k<=n-1; k++) 
			x[k]=x[k]+r[k];

    }
    
	// 求解成功
	return TRUE;
}

⌨️ 快捷键说明

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