C语言程序设计 迭代法

C语言程序设计 迭代法,第1张

main()

{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

}

看看对你有帮助吧!!!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8107109.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存