{double
x1,x2
x1=0.0
x2=cos(x1)
while(fabs(x2-x1)>le-6)//当误差大于10的负六次方循环。
{x1=x2
x2=cos(x1)
}
printf("x=%f\n",x2)
}
牛顿迭代法,是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0,用某种数学方法导出等价的形式
x(n+1)
=
g(x(n))
=
x(n)–f(x(n))/f‘(x(n)).然后按以下步骤执行:
(1)
选一个方程的近似根,赋给变量x1
(2)
将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0
(3)
当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。
若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就
认为是方程的根。
迭代法 matlab实现代码如下
function [x,n] = jacobi(A,b,x0,eps,varargin)
if nargin ==3
eps = 1.0e-6
M = 200
elseif nargin<3
disp('输入参数数目不足3个')
return
elseif nargin ==5
M = varargin{1}
end
D = diag(diag(A)) %%求A的对角矩阵
L = -tril(A,-1) %%求A的下三角矩阵
U = -triu(A,1) %%求A的上三角矩阵
B = D\(L+U)
f = D\b
x = B*x0+f
n = 1%迭代次数
while norm(x-x0)>=eps
x0 = x
x = B*x0+f
n = n+1
if(n>=M)
disp('Warning:迭代次数太多,可能不收敛!')
return
end
end
运行效果如下:
扩展资料:
迭代法的收敛性判别
收敛性判别条件
SOR迭代法收敛的充分必要条件是ρ(λω)<1,ρ(λω)与松弛因子ω有关。ρ(λω)与ω的关系以及SOR方法收敛的条件有如下定理。
定理1:(Kahan)对任意的A
,设其对角元皆非零,则对所有实数ω,有:ρ(λω)≥ ω-1。
推论:如果解Ax=b的SOR方法收敛,则有ω-1<1,即0<ω<2。
定理2:(Ostrowski-Reich)设A
,A对称正定,且0<ω<2,则解Ax=b的SOR方法收敛。
参考资料来源:百度百科-逐次超松驰迭代法
迭代法计算信道容量C++程序#include <iostream>
#include <vector>
#include <cfloat>
#include <cmath>
using namespace std
#define FLOAT_MINUS_PRECISION 0.00001
typedef vector<float*>VEC_PFLOAT
//迭代计算信道容量,参数值为信源,信宿符号个数和信道转移概率矩阵,返回信道容量
float GetCapacity(int nSourceSymbol,int nHostSymbol,const VEC_PFLOAT&vTransMatrix)
{
//信道容量初始化为最小值
float fCapacity = FLT_MIN
//信源概率分布
float *pfSoureProb = new float[nSourceSymbol]
//初始化信源分布为均匀分布
int i
for (i = 0i <nSourceSymboli++)
{
pfSoureProb[i] = 1.0 / nSourceSymbol
}
//初始化φ函数
VEC_PFLOAT vPhi
for (i = 0i <nSourceSymboli++)
{
float *pfTemp = new float[nHostSymbol]
vPhi.push_back(pfTemp)
}
//设置精度
const float cfDelta = 0.02f
float fPrecision
//迭代计算
int j,k
float *pfSum = new float[nSourceSymbol]
do
{
for (i = 0i <nSourceSymboli++)
{
for (j = 0j <nHostSymbolj++)
{
//计算ΣPi*Pji
float fSum = 0.0f
for (k = 0k <nSourceSymbolk++)
{
fSum += pfSoureProb[i] * vTransMatrix[k][i]
}
vPhi[i][j] = pfSoureProb[i] * vTransMatrix[j][i] / fSum
}
}
float fSumDeno = 0.0f //分母求和
for (i = 0i <nSourceSymboli++)
{
float fSum = 0.0f
for (j = 0j <nHostSymbolj++)
{
fSum += vTransMatrix[j][i] * logf(vPhi[i][j])
}
pfSum[i] = expf(fSum)
fSumDeno += pfSum[i]
}
for (i = 0i <nSourceSymboli++)
{
pfSoureProb[i] = pfSum[i] / fSumDeno
}
//计算新一轮的容量
float fNewC = logf(fSumDeno)
//计算精度
fPrecision = fabs(fNewC - fCapacity) / fCapacity
fCapacity = fNewC
} while(fPrecision - cfDelta >0.0f)
//释放临时资源...
delete []pfSum
for (i = 0i <vPhi.size()i++)
{
float* pfTemp = vPhi.at(i)
delete pfTemp
}
vPhi.clear()
return fCapacity
}
int main()
{
//转移矩阵
VEC_PFLOAT vTransMatrix
int nCol,nLine
cout<<"请输入信源符号个数:"
cin>>nLine
cout<<"请输入信宿符号个数:"
cin>>nCol
cout<<"请依次输入"<<"行信道转移概率矩阵:(以空格隔开每个概率)\n"
for (int i = 0i <nLinei++)
{
float *pfTemp = new float[nCol]
Label1:
float fSum = 0.0f
cout<<"X"<<":"
for (int j = 0j <nCol - 1j++)
{
cin>>pfTemp[j]
fSum += pfTemp[j]
}
if (1.0f - fSum <0)
{
cout<<"转移概率和应该为1,请重新输入!\n"
goto Label1
}
else
{
pfTemp[j] = 1.0f - fSum
cout<<"信源符号X"<<"的转移概率分别为:"
for(int k = 0k <nColk++)
cout<<pfTemp[k]
cout<<"\n"
}
vTransMatrix.push_back(pfTemp)
}
cout<<"信道容量为:"
for (int k = 0k <vTransMatrix.size()k++)
{
float* pfTemp = vTransMatrix.at(k)
delete pfTemp
}
vTransMatrix.clear()
return 0
}
看看对你有帮助吧!!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)