Cholesky平方根算法C语言

合集下载

c语言sqrt函数用法

c语言sqrt函数用法

c语言sqrt函数用法C语言中的sqrt函数是一个用于计算一个数的平方根的函数,它的用法非常简单,但是对于初学者来说可能会有些困惑。

在本篇文章中,我们将分步骤阐述sqrt函数的用法。

1. 概述sqrt函数是math.h头文件中的一个函数,用于计算一个数的平方根。

它的原型如下所示:double sqrt(double x);其中x是需要计算平方根的数,函数的返回值是该数的平方根。

2. 参数和返回值2.1 参数sqrt函数只接受一个参数,即需要计算平方根的数。

该参数必须是一个非负实数,否则将会产生一个错误。

2.2 返回值sqrt函数的返回值是计算出的平方根。

3. 使用方法要使用sqrt函数,需要先引入math.h头文件。

可以使用以下代码实现:#include <math.h>接下来,可以将需要计算平方根的数作为sqrt函数的参数,如下所示:int main(){double x = 9.0;double result = sqrt(x);printf("The square root of %lf is %lf\n", x, result);return 0;}上述代码中,我们将9.0作为参数传递给sqrt函数,并将返回值存储在result变量中。

然后,我们使用printf函数输出计算结果。

输出如下:The square root of 9.000000 is 3.0000004. 可能的错误如果我们将一个负数作为sqrt函数的参数,将会产生一个错误。

例如,下面的代码将会导致程序崩溃:int main(){double x = -1.0;double result = sqrt(x);printf("The square root of %lf is %lf\n", x, result);return 0;}输出如下:Segmentation fault: 11因此,在使用sqrt函数时应该确保参数是一个非负实数。

C语言求平方根源程序

C语言求平方根源程序

编程序求10000之内的完全平方数的平方根#include <stdio.h>main(){int a,b,d,e,f;int A;int i,j;printf("\n\n***** 先把100以内的自然数打出来*****\n\n"); /*在Tc2.0下要注意把汉字改为英文*/for(i=0;i<100;i++){ j=i*i;printf(" %d*%d=%d ",i,i,j);if(i%5==0)printf("\n");}printf("\nPlsease enter a number:");scanf("%d",&A);while(A!=0) /* A是1到9999之间的任意一个完全平方数*/{if(A>=100)/* 对A分情况讨论*/{ a=A/100; /* A除以100取整赋给a */ if(a>=1&&a<=3)b=1;if(a>=4&&a<=8)b=2;if(a>=9&&a<=15)b=3;if(a>=16&&a<=24)b=4;if(a>=25&&a<=35)b=5;if(a>=36&&a<=48)b=6;if(a>=49&&a<=63)b=7;if(a>=64&&a<=80)b=8;if(a>=81&&a<=99)b=9;}if(A<100){ if(A==1){ b=1;printf("\nthe root of A is %d",b);printf("\nPlsease enter a number:");scanf("%d",&A);}if(A==4){ b=2;printf("\nthe root of A is %d",b);printf("\nPlsease enter a number:"); scanf("%d",&A);}if(A==9){ b=3;printf("\nthe root of A is %d",b);printf("\nPlsease enter a number:"); scanf("%d",&A);}if(A==16){ b=4;printf("\nthe root of A is %d",b); printf("\nPlsease enter a number:"); scanf("%d",&A);}if(A==25){ b=5;printf("\nthe root of A is %d",b); printf("\nPlsease enter a number:"); scanf("%d",&A);}if(A==36){ b=6;printf("\nthe root of A is %d",b); printf("\nPlsease enter a number:"); scanf("%d",&A);}if(A==49){ b=7;printf("\nthe root of A is %d",b); printf("\nPlsease enter a number:"); scanf("%d",&A);}if(A==64){ b=8;printf("\nthe root of A is %d",b);printf("\nPlsease enter a number:"); scanf("%d",&A);}if(A==81){ b=9;printf("\nthe root of A is %d",b);printf("\nPlsease enter a number:"); scanf("%d",&A);}}d=A-b*b*100; /* 变量b是第一次试商*/ e=d/(b*20); /* e 是第二次试商*/if(e>=10)e=e-1;while(((b*20+e)*e)!=d)e=e-1;f=b*10+e;/* 变量f是所求平方根*/ printf("\nthe root of A is %d",f);printf("\nPlsease enter a number:");scanf("%d",&A);}}此程序在VC++6.0 下编译运行通过,在Tc2.0也可以运行但要注意把汉字注释删除运行结果如下***** 先把100以内的自然数打出来*****0*0=01*1=1 2*2=4 3*3=9 4*4=16 5*5=256*6=36 7*7=49 8*8=64 9*9=81 10*10=10011*11=121 12*12=144 13*13=169 14*14=196 15*15=22516*16=256 17*17=289 18*18=324 19*19=361 20*20=40021*21=441 22*22=484 23*23=529 24*24=576 25*25=62526*26=676 27*27=729 28*28=784 29*29=841 30*30=90031*31=961 32*32=1024 33*33=1089 34*34=1156 35*35=1225 36*36=1296 37*37=1369 38*38=1444 39*39=1521 40*40=160041*41=1681 42*42=1764 43*43=1849 44*44=1936 45*45=202546*46=2116 47*47=2209 48*48=2304 49*49=2401 50*50=250051*51=2601 52*52=2704 53*53=2809 54*54=2916 55*55=302556*56=3136 57*57=3249 58*58=3364 59*59=3481 60*60=360061*61=3721 62*62=3844 63*63=3969 64*64=4096 65*65=422566*66=4356 67*67=4489 68*68=4624 69*69=4761 70*70=490071*71=5041 72*72=5184 73*73=5329 74*74=5476 75*75=562576*76=5776 77*77=5929 78*78=6084 79*79=6241 80*80=640081*81=6561 82*82=6724 83*83=6889 84*84=7056 85*85=722586*86=7396 87*87=7569 88*88=7744 89*89=7921 90*90=810091*91=8281 92*92=8464 93*93=8649 94*94=8836 95*95=902596*96=9216 97*97=9409 98*98=9604 99*99=9801 Plsease enter a number:4096the root of A is 64Plsease enter a number:7569the root of A is 87Plsease enter a number:4761the root of A is 69Plsease enter a number:5476the root of A is 74Plsease enter a number:。

平方根法

平方根法
数值线性代数实验报告
实验名称 平方根法 小组成员 一、实验目的与内容 计算结果的分析 一、实验目的与内容 1.了解平方根法的原理和意义; 2.编程实现用平方根法求解线性方程组。 二、相关背景知识介绍 平方根法又叫 Cholesky 分解法,是求解对称正定线性方程组最常用的方法之一。 我们知道,对于一般方阵,为了消除 LU 分解的局限性和误差的过分积累,而采用了选主元的 方法。但对于对称正定矩阵而言,选主元却是完全不必要的。 若线性方程组 Ax=b 的系数矩阵是对称正定的,我们可按如下的步骤求其解: 1.求 A 的 Cholesky 分解: A LLT ;[1] 2.求解 Ly=b 得到 y, 3.将 y 回代求解 LT x y 得到 x。 三、代码 用平方根法求解下列方程组. n=5,10,100,…( 到你们小组计算能力的极限)求解,对计算解 和准确解比较,观察准确程度
10
15
20
五、计算结果分析 从数据结果可以看出,利用平方根法较为准确,且计算高阶矩阵时较快。在编程过程中 有的组员对计算出 L 阵后的计算不太清楚,造成了计算结果的错误,经过讨论对平方根法的 理解更加深刻了一层。
4教 师 评 语指导教 Nhomakorabea: 年 月 日
5
2.0000,-2.3094,-1.6330,-1.2649,-1.0328 -0.8729,-0.7559,-0.6667,-0.5963,-0.5394 -0.4924,-0.4529,-0.4193,-0.3904,3.7428 2.0000,-2.3094,-1.6330,-1.2649,-1.0328 -0.8729,-0.7559,-0.6667,-0.5963,-0.5394 -0.4924,-0.4529,-0.4193,-0.3904,-0.3651 -0.3430,-0.3234,-0.3059,-0.2902,3.8644

数值代数上机实验报告

数值代数上机实验报告

数值代数课程设计实验报告姓名: 班级: 学号: 实验日期:一、实验名称 代数的数值解法 二、实验环境 MATLAB7.0实验一、平方根法与改进平方根法一、实验要求:用熟悉的计算机语言将不选主元和列主元Gasuss 消元法编写成通用的子程序,然后用编写的程序求解下列方程组⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡=⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡--⨯14151515157681681681681681612321n n n n n x x x x x x 用所编的程序分别求解40、84、120阶方程组的解。

二、算法描述及实验步骤GAuss 程序如下:(1)求A 的三角分解:LU A =;(2)求解b y =L 得y ; (3)求解y x =U 得x ;列主元Gasuss 消元法程序如下: 1求A 的列主元分解:LU PA =;2求解b y P L =得y ; 3求解y x =U 得x ;三、调试过程及实验结果:%----------------方程系数---------------->> A1=Sanduijiaozhen(8,6,1,40); >> A2=Sanduijiaozhen(8,6,1,84); >> A3=Sanduijiaozhen(8,6,1,120); >> b1(1)=7;b2(1)=7;b3(1)=7;>> for i=2:39b1(i)=15;end>> b1(40)=14;>> for i=2:83b2(i)=15;end>> b2(40)=14;>> for i=2:119b1(i)=15;end>> b3(120)=14;%----------------方程解---------------->> x11=GAuss(A1,b1')>> x12=GAuss Zhu(A1,b1')>> x21=GAuss(A2,b2')>> x22=GAuss Zhu(A3,b3')>> x31=GAuss(A3,b3')>> x32=GAuss Zhu(A3,b3')运行结果:(n=40)GAuss消元法的解即为x11 =1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.0000列主元GAuss消元法的解即为x12 =1 1 1 1 1 1 1 1 1 1 111111111111111111111111111111六、源程序:function A=Sanduijiaozhen(a,b,c,n)%生成n阶以a,b,c为元素的三对角阵A=diag(b*ones(1,n),0)+diag(c*ones(1,n-1),1)+diag(a*ones(1,n-1),-1);function x=GAuss(A,b)n=length(b);x=b;%-------分解---------------for i=1:n-1for j=i+1:nmi=A(j,i)/A(i,i);b(j)=b(j)-mi*b(i);for k=i:nA(j,k)=A(j,k)-mi*A(i,k);endAB=[A,b];endend%-----------回代------------------x(n)=b(n)/A(n,n);for i=n-1:-1:1s=0;for j=i+1:ns=s+A(i,j)*x(j);endx(i)=(b(i)-s)/A(i,i);endfunction x=GAussZhu(A,b)n=length(b);x=b;%----------------------选主元---------------------for k=1:n-1a_max=0;for i=k:nif abs(A(i,k))>a_maxa_max=abs(A(i,k));r=i;endendif r>kfor j=k:nz=A(k,j);A(k,j)=A(r,j);A(r,j)=z;endz=b(k);b(k)=b(r);b(r)=z;end%--------------消元-----------------for i=k+1:nm=A(i,k)/A(k,k);for j=k:nA(i,j)=A(i,j)-m*A(k,j);endb(i)=b(i)-m*b(k);endendif abs(A(n,n))==0return;endAbZhu=[A,b];%----------------回代-----------------------x(n)=b(n)/A(n,n);for i=n-1:-1:1for j=i+1:nb(i)=b(i)-A(i,j)*x(j);endx(i)=b(i)/A(i,i);end实验二、平方根法与改进平方根法一、实验要求:用计算机语言将平方根法和改进的平方根法编成通用的子程序,然后用编写的程序求解对称正定方程组100阶方程组AX=b,二、算法描述及实验步骤:平方根法函数程序如下:1、求A 的Cholesky 分解:L L A T=;2、求解b y =L 得y ;3、求解y x =TL 得x ; 改进平方根法函数程序如下:1、求A 的Cholesky 分解:T=LDL A ; 2、求解b y =L 得y ; 3、求解y x =TDL 得x ;三、调试过程及实验结果:clear;clc;%----------------方程系数---------------->> A=Sanduijiaozhen(1,10,1,100); >> b(1)=11; >> for i=2:99 b(i)=12; end>> b(100)=11;>> x1=Cholesky(A,b') >> x2=GJCholesky(A,b')运行结果:平方根法的解即为 x1 =1.0000 1.00001.0000 1.00001.0000 1.00001.0000 1.00001.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.0000改进平方根法解得的解即为x2 =1.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.0000 1.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00001.00000.99991.00090.99081.09080.1010四、源程序:function x=Cholesky(A,b)n=size(A);n=n(1);% x=A^-1*b;% disp('Matlab自带解即为x');%-----------------Cholesky分解-------------------for k=1:nA(k,k)=sqrt(A(k,k));A(k+1:n,k)=A(k+1:n,k)/A(k,k);for j=k+1:n;A(j:n,j)=A(j:n,j)-A(j:n,k)*A(j,k);endend%------------------前代法求解Ly=b----------------------------for j=1:n-1b(j)=b(j)/A(j,j);b(j+1:n)=b(j+1:n)-b(j)*A(j+1:n,j);endb(n)=b(n)/A(n,n);%-----------------回代法求解L'x=y-----------------------------A=A';for j=n:-1:2b(j)=b(j)/A(j,j);b(1:j-1)=b(1:j-1)-b(j)*A(1:j-1,j);endb(1)=b(1)/A(1,1);disp('平方根法的解即为');function b=GJCholesky(A,b)n=size(A);n=n(1);v=zeros(n,1);%----------------------LDL'分解-----------------------------for j=1:nfor i=1:j-1v(i)=A(j,i)*A(i,i);endA(j,j)=A(j,j)-A(j,1:j-1)*v(1:j-1);A(j+1:n,j)=(A(j+1:n,j)-A(j+1:n,1:j-1)*v(1:j-1))/A(j,j);endB=diag(A);D=zeros(n);for i=1:nD(i,i)=B(i);A(i,i)=1;end%-------------------前代法---------------------------A=tril(A); %得到L和Dfor j=1:n-1b(j)=b(j)/A(j,j);b(j+1:n)=b(j+1:n)-b(j)*A(j+1:n,j);endb(n)=b(n)/A(n,n);%-----------------回代法-----------------------------A=D*(A');for j=n:-1:2b(j)=b(j)/A(j,j);b(1:j-1)=b(1:j-1)-b(j)*A(1:j-1,j);endb(1)=b(1)/A(1,1);disp('改进平方根法解得的解即为');实验三、二次多项式拟合一、实验要求:用计算机语言编制利用QR分解求解线性最小二乘问题的通用子程序,用编写的程序求解一个二次多项式使在残向量的范数最小的意义下拟合下面的数据t-1 -0.75 -0.5 0 0.25 0.5 0.75iy 1.00 0.8125 0.75 1.00 1.3125 1.75 2.3125i二、算法描述及实验步骤:QR分解求解程序如下:1、求A 的QR 分解;2、计算b c 11T =Q ;3、求解上三角方程1c x =R 得x ;三、调试过程及实验结果:>> t=[-1 -0.75 -0.5 0 0.25 0.5 0.75];>> y=[ 1.00 0.8125 0.75 1.00 1.3125 1.75 2.3125]; >> plot(t,y,'r*');>> legend('实验数据(ti,yi)'); >> xlabel('t'), ylabel('y');>> title('二次多项式拟合的数据点(ti,yi)的散点图');运行后屏幕显示数据的散点图(略).(3)编写下列MATLAB 程序计算)(x f 在),(i i y x 处的函数值,即输入程序 >> syms a b c>> t=[-1 -0.75 -0.5 0 0.25 0.5 0.75]; >> fi=a.*t.^2+ b.*t+c%运行后屏幕显示关于 ,,a b c 的线性方程组fi =[a-b+c,9/16*a-3/4*b+c,1/4*a-1/2*b+c,c,1/16*a+1/4*b+c,1/4*a+1/2*b+c,9/16*a+3/4*b +c]编写构造残向量2范数的MATLAB 程序>> y=[ 1.00 0.8125 0.75 1.00 1.3125 1.75 2.3125]; >> y=[ 1.00 0.8125 0.75 1.00 1.3125 1.75 2.3125]; >> fy=fi-y; fy2=fy.^2; J=sum(fy.^2); 运行后屏幕显示误差平方和如下 J=(a-b+c-1)^2+(9/16*a-3/4*b+c-13/16)^2+(1/4*a-1/2*b+c-3/4)^2+(c-1)^2+(1/16*a+1/4*b+c-21/16)^2+(1/4*a+1/2*b+c-7/4)^2+(9/16*a+3/4*b+c-37/16)^2为求,,a b c 使J 达到最小,只需利用极值的必要条件0J a ∂=∂,0J b ∂=∂,0J c∂=∂,得到关于,,a b c 的线性方程组,这可以由下面的MATLAB 程序完成,即输入程序 >> Ja1=diff(J,a); Ja2=diff(J,b); Ja3=diff(J,c);>> Ja11=simple(Ja1), Ja21=simple(Ja2), Ja31=simple(Ja3) 运行后屏幕显示J 分别对,,a b c 的偏导数如下 Ja11 =451/128*a-63/32*b+43/8*c-887/128 Ja21 =-63/32*a+43/8*b-3/2*c-61/32Ja31 =43/8*a-3/2*b+14*c-143/8解线性方程组112131000Ja Ja Ja ===,,,输入下列程序 >> A=[451/128, -63/32, -3/2 ;-63/32,43/8,-3/2;43/8,-3/2,14]; >> B=[887/128,61/32,143/8]; >> C=B/A, f=poly2sym(C)运行后屏幕显示拟合函数f 及其系数C 如下 C =0.3081 0.8587 1.4018 f =924/2999*x^2+10301/11996*x+4204/2999 故所求的拟合曲线为2()0.30810.8581 1.4018f x x x =++四、源程序:>> t=[-1 -0.75 -0.5 0 0.25 0.5 0.75];>> y=[ 1.00 0.8125 0.75 1.00 1.3125 1.75 2.3125]; >> plot(t,y,'r*');>> legend('实验数据(ti,yi)'); >> xlabel('t'), ylabel('y');>> title('二次多项式拟合的数据点(ti,yi)的散点图'); >> syms a b c>> t=[-1 -0.75 -0.5 0 0.25 0.5 0.75]; >> fi=a.*t.^2+ b.*t+c fi =[ a-b+c, 9/16*a-3/4*b+c, 1/4*a-1/2*b+c, c, 1/16*a+1/4*b+c, 1/4*a+1/2*b+c, 9/16*a+3/4*b+c]>> y=[ 1.00 0.8125 0.75 1.00 1.3125 1.75 2.3125]; >> y=[ 1.00 0.8125 0.75 1.00 1.3125 1.75 2.3125]; >> fy=fi-y; fy2=fy.^2; J=sum(fy.^2) J =(a-b+c-1)^2+(9/16*a-3/4*b+c-13/16)^2+(1/4*a-1/2*b+c-3/4)^2+(c-1)^2+(1/16*a+1/4*b+c-21/16)^2+(1/4*a+1/2*b+c-7/4)^2+(9/16*a+3/4*b+c-37/16)^2>> Ja1=diff(J,a); Ja2=diff(J,b); Ja3=diff(J,c);>> Ja11=simple(Ja1), Ja21=simple(Ja2), Ja31=simple(Ja3)Ja11 =451/128*a-63/32*b+43/8*c-887/128Ja21 =-63/32*a+43/8*b-3/2*c-61/32Ja31 =43/8*a-3/2*b+14*c-143/8>> A=[451/128, -63/32, -3/2 ;-63/32,43/8,-3/2;43/8,-3/2,14]; >> B=[887/128,61/32,143/8];>> C=B/A, f=poly2sym(C)C =0.3081 0.8587 1.4018f =924/2999*x^2+10301/11996*x+4204/2999>>。

c语言math库对sqrt的实现

c语言math库对sqrt的实现

C语言是一种非常重要的计算机编程语言,广泛应用于系统软件、应用软件、嵌入式系统、驱动程序等领域。

math库是C语言中非常常用的数学库,提供了很多数学函数供程序员使用。

其中,sqrt函数是math库中的一个常用函数,用于计算一个数的平方根。

本文将讨论C 语言math库对sqrt函数的实现方法。

1. sqrt函数概述让我们来了解一下sqrt函数的概述。

sqrt函数用于计算一个数的平方根,其原型如下:double sqrt(double x);其中,x为要计算平方根的数,函数返回x的平方根。

sqrt函数定义在math.h头文件中,因此在使用sqrt函数之前,需要包含math.h头文件。

2. sqrt函数的实现原理接下来,我们来分析一下sqrt函数的实现原理。

在C语言中,sqrt函数通常是由系统底层的数学库实现的,具体的实现方式可能因系统而异。

一种常见的实现方式是使用牛顿迭代法来计算平方根。

牛顿迭代法是一种用途广泛的求解方程近似解的方法,其具体步骤如下:(1) 选取一个初始值作为计算的起点,假设为y0;(2) 根据迭代公式y = (y0 + x / y0) / 2计算下一个近似值y;(3) 判断计算结果与精度要求的差距,如果小于精度要求,则停止迭代,取当前的y值作为最终结果;否则,将y作为新的y0,重复步骤(2);(4) 最终得到的y值即为所求的平方根。

3. sqrt函数的具体实现针对不同的系统和评台,sqrt函数的实现可能会有一定的差异。

我们以标准的C语言为例,来简单介绍一种可能的sqrt函数实现方法。

```c#include <math.h>double sqrt(double x) {double y0, y = x, temp;if (x == 0.0 || x == 1.0) {return x;}do {y0 = y;temp = x / y0;y = (y0 + temp) / 2;} while (y != y0);return y;}```上述代码是对sqrt函数的一种简单实现,采用了牛顿迭代法来计算平方根。

单片机C语言求平方根函数

单片机C语言求平方根函数

转自:/article/304.html在单片机中要开平方.可以用到下面算法:算法1:本算法只采用移位、加减法、判断和循环实现,因为它不需要浮点运算,也不需要乘除运算,因此可以很方便地运用到各种芯片上去。

我们先来看看10进制下是如何手工计算开方的。

先看下面两个算式,x = 10*p + q (1)公式(1)左右平方之后得:x^2 = 100*p^2 + 20pq + q^2 (2)现在假设我们知道x^2和p,希望求出q来,求出了q也就求出了x^2的开方x了。

我们把公式(2)改写为如下格式:q = (x^2 - 100*p^2)/(20*p+q) (3)这个算式左右都有q,因此无法直接计算出q来,因此手工的开方算法和手工除法算法一样有一步需要猜值。

我们来一个手工计算的例子:计算1234567890的开方首先我们把这个数两位两位一组分开,计算出最高位为3。

也就是(3)中的p,最下面一行的334为余数,也就是公式(3)中的(x^2 - 100*p^2)近似值3 --------------- | 12 34 56 78 90 9 --------------- | 3 34下面我们要找到一个0-9的数q使它最接近满足公式(3)。

我们先把p乘以20写在334左边:3 q --------------- | 12 34 56 78 90 9 --------------- 6q| 3 34我们看到q为5时(60+q*q)的值最接近334,而且不超过334。

于是我们得到:3 5 --------------- | 12 34 56 78 90 9 --------------- 65| 3 34 | 325 --------------- 9 56接下来就是重复上面的步骤了,这里就不再啰嗦了。

这个手工算法其实和10进制关系不大,因此我们可以很容易的把它改为二进制,改为二进制之后,公式(3)就变成了:q = (x^2 - 4*p^2)/(4*p+q) (4)我们来看一个例子,计算100(二进制1100100)的开方:1 0 1 0 --------------- | 1 10 01 00 1 --------------- 100| 0 10 | 000 --------------- | 10 011001| 10 01 --------------- 0 00这里每一步不再是把p乘以20了,而是把p乘以4,也就是把p右移两位,而由于q的值只能为0或者1,所以我们只需要判断余数(x^2 - 4*p^2)和(4*p+1)的大小关系,如果余数大于等于(4*p+q)那么该上一个1,否则该上一个0。

c语言开方函数

c语言开方函数

c语言开方函数
c语言的开方函数是:
sqrt()函数。

1、功能:计算一个非负实数的平方根。

2、函数原型:在VC6.0中的math。

h头文件的函数原型为double sqrt(double)。

3、说明:sqrt系。

C语言中平方根的函数是怎么样的?
1、C语言中平方根的函数是:double sqrt(double);参数介绍:()中是double,返回值可能是double 也可能是int;
2、该函数头文件:math。

h;
3、该函数功能:计算一个非。

在c中类似开方,取绝对值
sqrt()
include int main() { double x,y; printf("请输入x:");scanf("%f",&x); if (0
#include#include int main() { double x,y; printf("请输入x:"); scanf("%f",&x); if (0
若开平方,可以使用函数sqrt()完成,若开其他次方,可以
借助函数pow()完成。

开平方示例:#include//sqrt函数使用到
的头文件#include int main(。

牛顿迭代求根法,自己去查一下公式,这里我给出C语言代码,可自行修改一下。

double sqrt_db(double the Input) { double si=1;uint16_t times=0; if (the Input==0) { return 0; } 。

用函数SQRT(A)即可。

c语言平方根

c语言平方根

c语言平方根在计算机编程中,平方根是一个非常重要的数学运算。

在C语言中,我们可以使用数学库函数来计算平方根。

本文将介绍如何使用C 语言计算平方根,并讨论一些与平方根相关的数学知识。

一、C语言中计算平方根的方法在C语言中,我们可以使用数学库函数来计算平方根。

数学库函数sqrt()可以计算任意实数的平方根。

sqrt()函数的定义如下:double sqrt(double x);sqrt()函数的参数x是要计算平方根的实数。

函数返回值为x的平方根。

下面是一个使用sqrt()函数计算平方根的示例程序:#include <stdio.h>#include <math.h>int main(){double x, result;printf('Enter a number: ');scanf('%lf', &x);result = sqrt(x);printf('The square root of %.2f is %.2f', x, result);return 0;}在上面的程序中,我们首先使用scanf()函数从用户输入中读取一个实数x。

然后,我们调用sqrt()函数计算x的平方根,并将结果存储在变量result中。

最后,我们使用printf()函数输出结果。

二、平方根的数学知识平方根是一个非常重要的数学运算,它有许多重要的应用。

下面我们将讨论一些与平方根相关的数学知识。

1. 平方根的定义平方根是一个数的平方等于它的被称为这个数的平方根。

例如,2的平方根是1.41421356...,因为1.41421356...的平方等于2。

2. 平方根的性质平方根有许多重要的性质。

下面是一些常见的平方根性质:(1)平方根是非负数。

对于任意正实数x,它的平方根是非负数。

如果x是负实数,则它没有实数平方根。

(2)平方根的值是唯一的。

对于任意正实数x,它的平方根是唯一的。

c语言sqrt函数的用法

c语言sqrt函数的用法

c语言sqrt函数的用法哎,说起C语言里的sqrt函数,咱们得聊聊这个“求平方根”的小家伙。

说起来,这sqrt函数,它可是C语言里算术库中的一个宝贝,就像咱小时候数学课上学的那个“求根号”一样,但比那个强多了,它不是手动算,而是直接用计算机算,快得很。

首先你得知道,这sqrt函数长啥样。

它俩字儿,“sqrt”,一看就知道,求平方根的,对吧?咱们就用这俩字儿去咱的C语言头文件里找找。

咦,找到了,它在“math.h”这个头文件里藏着呢。

你想想,数学嘛,肯定得跟数学有关的头文件打交道。

我有个习惯,喜欢动手实践,所以我就先在电脑上打开编辑器,写个小程序试试。

我写了个简单的例子,比如我写个int num = 4;,然后调用sqrt函数,让它算出4的平方根来。

代码是这样的:```c#include <stdio.h>#include <math.h>int main() {int num = 4;printf("The square root of %d is %f\n", num, sqrt(num));return 0;}```把这段代码一跑,结果出来了,4的平方根是2.000000,多精确啊!你看,这sqrt函数多好用,直接就帮咱们算出了结果。

当然了,这sqrt函数也不是万能的。

比如,你给它个负数,它就不高兴了,得个编译错误。

因为数学上负数没有实数平方根,所以咱们在使用的时候可得小心点,别让它算出个负数来。

再说说这sqrt函数的用法吧。

其实很简单,只要你在你的程序里包含“math.h”头文件,然后直接用sqrt函数名,再跟上你想要求平方根的数字,就这么简单。

有时候,我会跟学生们说:“这sqrt函数就像你小时候求根号一样,只是你长大了,它帮你把繁重的计算工作都做了。

”有时候,学生们会问我:“刘老师,那sqrt函数能求非整数的平方根吗?”我就会笑,说:“当然了,它可是个全能选手,你给它个1.44,它就能给你算出根号1.44来,多厉害!”然后他们会好奇地问:“那具体怎么算呢?”我就说:“咱们看代码就知道了。

c语言中的根号2

c语言中的根号2

C语言中的根号21. 引言C语言是一种广泛应用于系统编程和嵌入式开发的高级编程语言。

它的设计目标是提供一种简单、高效、可移植的编程语言,使开发者能够方便地编写出效率高、可靠性强的程序。

在C语言中,数学计算是非常重要的一部分,而根号是数学计算中常用的运算符之一。

本文将介绍C语言中如何计算根号2,并提供示例代码和详细说明。

2. 根号2的定义根号2是一个无理数,它的值约为1.41421356237。

在C语言中,我们可以使用数值计算的方法来近似计算根号2的值。

3. 使用数值计算方法计算根号2在C语言中,我们可以使用牛顿迭代法来计算根号2的近似值。

牛顿迭代法是一种通过不断逼近的方式来求解方程的方法,它的基本思想是通过迭代计算来逼近方程的解。

对于根号2的计算,我们可以使用以下的迭代公式:x = (x + 2 / x) / 2其中,x是根号2的近似值。

通过不断迭代计算,我们可以逐步逼近根号2的真实值。

4. 根号2的计算示例代码下面是使用C语言编写的计算根号2的示例代码:#include <stdio.h>double sqrt2() {double x = 1.0; // 初始近似值为1.0double delta = 1e-6; // 迭代精度为0.000001while (1) {double y = (x + 2 / x) / 2; // 使用迭代公式计算下一个近似值if (fabs(y - x) < delta) { // 判断迭代精度是否满足要求return y;}x = y; // 更新近似值}}int main() {double result = sqrt2();printf("根号2的近似值为:%f\n", result);return 0;}5. 代码说明在示例代码中,我们首先定义了一个名为sqrt2的函数,该函数用于计算根号2的近似值。

函数中使用了一个while循环来进行迭代计算,直到满足迭代精度要求为止。

c语言 平方根

c语言 平方根

c语言平方根
C语言中计算平方根的方法有多种,其中比较常用的是数值逼近法和二分法。

数值逼近法是利用数学公式,通过不断迭代来逼近平方根的值。

而二分法则是利用二分查找的思想,通过不断缩小范围来逼近平方根的值。

数值逼近法中,牛顿迭代法是比较常用的一种方法。

其基本思想是通过对函数进行泰勒展开,得到一个近似值,然后不断迭代该近似值,直到收敛到真实值为止。

在计算平方根时,我们可以选择一个初值,然后通过牛顿迭代公式来不断逼近平方根的值。

具体实现步骤如下:
1. 选择一个初值x0,比如可以选择x0=1。

2. 根据牛顿迭代公式,计算出下一个近似值x1:x1 = (x0 + num/x0)/2,其中num表示要求平方根的数。

3. 将x1作为新的初值,重复上述步骤,不断迭代直到收敛。

二分法的实现比较简单,其基本思想是首先确定一个初始区间[a,b],然后通过不断缩小区间的范围,逼近平方根的值。

具体实现步骤如下:
1. 确定一个初始区间[a,b],比如可以选择a=0,b=num。

2. 根据区间的中点c=(a+b)/2,计算出c的平方c*c。

3. 如果c*c大于num,则平方根应该在区间[a,c]内,否则应该在区间[c,b]内。

4. 根据上一步的结果,缩小区间范围,重复步骤2和步骤3,
直到区间足够小,平方根的值就在该区间内。

Cholesky分解法的思想及C语言编程

Cholesky分解法的思想及C语言编程

Cholesky分解法Cholesky分解法又称三角分解法,或称因子化法设线性方程组Ax b=(1)式中A为对称、正定的矩阵。

对于对称、正定的矩阵A,可进行分解TA LDL=(2)式中L是下单位三角阵,D是对角线矩阵。

右端项列向量(列阵)也作相应的分解b LDb=(3)将式(2)和式(3)代入方程(1),得到上三角方程组TL x b=再按诸如高斯消元法的回代过程就可解出x下面,通过编写一个完整的C语言程序求1234121312235416155118341720xxxx⎛⎫⎛⎫⎛⎫⎪⎪ ⎪- ⎪⎪ ⎪=⎪⎪ ⎪--⎪⎪ ⎪-⎝⎭⎝⎭⎝⎭,完整的C语言程序代码如下:#include<>#include<>#include<>#define N 4void Cholesky(int n,double A[N][N],double x[N],double b[N]) {int i,j,k;double L[N][N],D[N][N],b2[N];i=1;D[i-1][i-1]=A[i-1][i-1];for(i=2;i<=n;i++){j=1;L[i-1][j-1]=A[i-1][j-1]/D[j-1][j-1];if(j==i-1){D[i-1][i-1]=0;for(k=1;k<=i-1;k++)D[i-1][i-1]+=pow(L[i-1][k-1],2)*D[k-1][k-1];D[i-1][i-1]=A[i-1][i-1]-D[i-1][i-1];continue;}else{for(j=2;j<=i-1;j++){L[i-1][j-1]=0;for(k=1;k<=j-1;k++)L[i-1][j-1]+=L[i-1][k-1]*L[j-1][k-1]*D[k-1][k-1];L[i-1][j-1]=(A[i-1][j-1]-L[i-1][j-1])/D[j-1][j-1];if(j==i-1){D[i-1][i-1]=0;for(k=1;k<=i-1;k++)D[i-1][i-1]+=pow(L[i-1][k-1],2)*D[k-1][k-1];D[i-1][i-1]=A[i-1][i-1]-D[i-1][i-1];continue;}}}}i=1;b2[i-1]=b[i-1]/D[i-1][i-1];for(i=2;i<=n;i++){b2[i-1]=0;for(k=1;k<=i-1;k++)b2[i-1]+=L[i-1][k-1]*D[k-1][k-1]*b2[k-1];b2[i-1]=(b[i-1]-b2[i-1])/D[i-1][i-1];}x[n-1]=b2[n-1] ;for(i=n-1;i>=1;i--){x[i-1]=;for(k=i+1;k<=n;k++)x[i-1]+=L[k-1][i-1]*x[k-1];x[i-1]=b2[i-1]-x[i-1];}for(i=0;i<=n-1;i++)printf("%f\n",x[i]);}void main(){double A[4][4]={{1,2,1,3},{2,3,-5,4},{1,-5,5,-1},{3,4,-1,7}}; double x[4]={0};double b[4]={12,16,18,20};Cholesky(4,A,x,b);}程序运行结果:。

c语言中sqrt用法

c语言中sqrt用法

C语言中sqrt用法1. 引言在C语言中,sqrt函数是一个用于计算平方根的数学函数。

平方根是一个常见的数学运算,在数学和计算机科学中经常使用。

本文将详细介绍sqrt函数的用法,包括函数原型、功能、参数和返回值等。

2. 函数原型sqrt函数的函数原型如下:double sqrt(double x);sqrt函数接受一个参数x,该参数表示要计算平方根的数值。

函数返回一个double 类型的结果,表示计算得到的平方根值。

需要注意的是,sqrt函数只能计算非负数的平方根,对于负数输入会返回NaN(不是一个数字)。

3. 功能sqrt函数的功能很简单,即计算给定数值的平方根。

平方根的定义是,对于非负数x,平方根是使得y * y = x成立的y。

sqrt函数通过数值计算的方法,返回与给定数值最接近的平方根值。

4. 参数sqrt函数只有一个参数x,表示要计算平方根的数值。

这个参数的类型是double,即双精度浮点数。

需要注意的是,sqrt函数只能计算非负数的平方根,对于负数输入会返回NaN。

5. 返回值sqrt函数的返回值是一个double类型的数值,表示计算得到的平方根值。

如果输入参数为非负数,则返回与参数最接近的平方根值;如果输入参数为负数,则返回NaN。

6. 使用示例下面是一个使用sqrt函数的示例代码:#include <stdio.h>#include <math.h>int main() {double x = 16.0;double result = sqrt(x);printf("The square root of %f is %f\n", x, result);return 0;}运行以上代码,将输出:The square root of 16.000000 is 4.000000以上示例代码中,我们包含了头文件math.h,这个头文件声明了sqrt函数。

平方根法计求解线性方程组

平方根法计求解线性方程组

解线性n 阶方程组直接法—Cholesky 方法解n 阶线性方程组Ax=b 的choleskly 方法也叫做平方根法,这里对系数矩阵A 是有要求的,需要A 是对称正定矩阵,根据数值分析的相关理论,如果A 对称正定,那么系数矩阵就可以被分解为的T A=L L ∙形式,其中L 是下三角矩阵,将其代入Ax=b 中,可得:T LL x=b进行如下分解:T L x L b y y ⎧=⎨=⎩那么就可先计算y,再计算x ,由于L 是下三角矩阵,是T L 上三角矩阵,这样的计算比直接使用A 计算简便,同时你应该也发现了工作量就转移到了矩阵的分解上面,那么对于对称正定矩阵A 进行Cholesky 分解,我再描述一下过程吧: 如果你对原理很清楚那么这一段可以直接跳过的。

设T A=L L ∙,即1112111112112122221222221212....................................n n n n n n nn n n nn nn a a a l l l l a a a l l l l a a a l l l l ⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦⎣⎦其中,,1,2,...,ij ji a a i j n ==第1步,由矩阵乘法,211111111,i i a l a l l == 故求得111111,2,3,...i i a l l i n a === 一般的,设矩阵L 的前k-1列元素已经求出第k 步,由矩阵乘法得112211k k kk km kkik im km ik kk m m a l l a l l l l --===+=+∑∑, 于是11(2,3,...,n)1(),1,2,...kk k ik ik im km m kk l k l a l l i k k n l -=⎧=⎪⎪=⎨⎪=-=++⎪⎩∑ 注意到21kkk km m a l ==∑,于是有21max km kk ii i nl a a ≤≤≤≤ 这充分说明分解过程中元素2km l 的平方不会超过系数矩阵A 的最大对角元,因而分解过程中舍入误差的放大收到了控制,用平方根法解对称正定方程组时可以不考虑选主元问题。

c语言中sqrt是啥意思

c语言中sqrt是啥意思

c语言中sqrt是啥意思
c语言中的sqrt函数是一个用于计算平方根的数学函数。

在C语言中,sqrt函数属于math.h头文件中的标准库函数,可以用来计算一个数的平方根。

sqrt(即square root的缩写)函数接受一个浮点数作为参数,并返回该浮点数的平方根。

它的基本语法如下:
```c
#include <math.h>
double sqrt(double x);
```
其中,x为要计算平方根的数字,函数返回一个double类型的浮点值,表示x的平方根。

需要注意的是,sqrt函数只能计算非负数的平方根。

对于负数的平方根计算,可以使用复数库中的函数。

1
下面是一个使用sqrt函数计算平方根的示例:
```c
#include <stdio.h>
#include <math.h>
int main() {
double num = 16.0;
double result = sqrt(num);
printf(\
2。

c语言 平方根

c语言 平方根

c语言平方根在c语言中,计算平方根是很常见的操作。

平方根通常是求解一个数的平方根。

在这篇文章中,我们将着重讨论计算平方根的方法和实例,并且解释一些在c语言中计算平方根时需要知道的概念和技巧。

第一步,理解平方根的概念。

平方根是一个操作,是指一个数的平方根,或者说是一个数的二次方根。

例如,2的平方根是1.41421356,这个数字也称为2的根号2次幂。

您可以通过求解平方根来解决许多问题,比如在几何学中计算三角形的斜边长,或者在计算机程序中生成随机数。

第二步,了解计算平方根的方法。

计算平方根的方法有很多,但是在c语言中,最常见的方法是使用牛顿-拉弗森方法和二分法。

在这里,我们着重讨论牛顿-拉弗森方法。

牛顿-拉弗森方法基于下面的公式:x = (x + n/x) / 2。

该公式用来计算一个数的平方根,其中n是要求解的数字,而x则是估计的平方根。

在每个迭代周期中,我们将x更新为上述公式中的新值,直到结果的误差满足一定的精度要求为止。

第三步,编写一个计算平方根的c语言程序。

下面是一个使用牛顿-拉弗森方法计算平方根的示例c语言程序:#include <stdio.h>#include <math.h>double square_root(double n){double x = n; // initialize guessdouble precision = 0.000001; // set desired precisionwhile(fabs(x * x - n) > precision) // check for desired precision{x = (x + n / x) / 2.0; // update guess using Newton-Raphson method}return x;}int main(){double n = 2; // number to find square root ofprintf("The square root of %f is %f\n", n, square_root(n)); return 0;}在此示例中,我们定义了一个名为square_root的函数,它接受一个数字参数n并通过牛顿-拉弗森方法计算n的平方根。

c语言 平方根倒数 -回复

c语言 平方根倒数 -回复

c语言平方根倒数-回复C语言是一种通用的程序设计语言,广泛应用于科学计算、嵌入式系统和系统编程等领域。

它是一种高级编程语言,能够进行各种复杂的计算和处理操作。

而平方根倒数则是一个数学计算中常见的问题,求一个数的平方根的倒数。

在本文中,我们将以C语言中的平方根倒数为主题,介绍一步一步如何通过编程实现这个功能。

首先,我们需要明确问题的需求:给定一个实数x,我们需要计算并返回它的平方根的倒数。

在C语言中,我们可以使用math.h头文件中的sqrt 函数来计算平方根,并使用1/x来计算倒数。

接下来,我们需要定义一个函数来实现这个功能。

我们可以将函数命名为sqrt_reciprocal,并在函数的参数列表中指定一个实数型参数x。

函数的返回值类型设置为double,以保证精度。

然后,在函数的实现代码中,我们需要使用math.h头文件中的sqrt函数来计算x的平方根。

之后,利用1/x来计算平方根的倒数。

最后,将倒数作为函数的返回值返回。

具体的代码如下所示:c#include <stdio.h>#include <math.h>double sqrt_reciprocal(double x) {double square_root = sqrt(x);double reciprocal = 1 / square_root;return reciprocal;}int main() {double x = 16;double result = sqrt_reciprocal(x);printf("The reciprocal of the square root of .2f is .5f\n", x, result); return 0;}在这段代码中,我们在main函数中定义一个变量x,并将其赋值为16。

然后,我们调用了sqrt_reciprocal函数,并传递x作为参数。

改进的平方根法及其程序实现

改进的平方根法及其程序实现

目录摘要 (2)0 引言 (3)1 预备知识 (3)1.1 TLL分解理论 (3)1.2 Cholesky分解法 (4)1.3 算法描述 (5)2改进的平方根法 (6)3TLDL分解算法描述 (7)4 应用举例 (8)5 程序实现 (10)5.1 程序码源 (10)5.2 实例计算 (12)6 结束语 (13)参考文献 (14)致谢 (15)改进的平方根法及其程序实现摘要: 针对对称正定方程组的解法,本文先对Cholesky分解法进行了分析研究,在此基础上给出了改进的平方根法(即TLDL分解法),此方法有效地避免了原平方根法开方运算所带来的误差和不便,并通过算法描述、实例计算,用C程序实现了TLDL分解,进一步提高了矩阵运算的速度和精度.关键词: 对称正定矩阵, 平方根法, TLDL分解, 算法Improved Methods of Square Root and Realizationof Its ProgramAbstract: Aiming at studying solutions of symmetric positive definition matrix in linear equations. Initially, the text has conducted a series of analyses and researches towards decomposition proposed by Cholesky. Then based on theses researches and analyses, it offers the improved methods of square–root (also called TLDL decom- position), which effectively avoid some errors and inconvenience brought by the process of extracting root. At the same time, it achieves the TLDL decomposition through the means of algorithm description, example calculation as well as applicat- ion of C program, further enhancing the speed and accuracy in matrix operation.Key words: Symmetric positive definition matrix, method of square root,TLDL decomposition, algorithm0 引言很多工程中的科学计算,例如应用有限元法解结构力学问题时,最后往往归结为求解系数矩阵为对称正定方程组解的问题.由于对称正定矩阵各阶顺序主子式以及全部的特征值均大于零, 这种特征也使得其三角分解具有更为简单的形式, 不同的分解也导出了一些不同的解法. 平方根法(即Cholesky 分解法), 就是利用对称正定矩阵的三角分解而得到的求解对称正定方程组的一种有效方法, 其计算量和存储量约为普通消去法的一半, 且无需选主元就能求得较为精确的数值解, 但由于在平方根法中含有多次开方运算, 因此给计算带来了许多不便, 而在原平方根法的基础上, 给出改进的平方根法(即T LDL 分解法), 成功避免了开方运算带来的的麻烦, 因此在各种工程计算中应用更为广泛.1 预备知识1.1 T LL 分解理论定理 1.1(矩阵的LU 分解定理) 设A 为n 阶矩阵, 如果A 的顺序主子式0(1,2,,1)i D i n ≠=- , 则A 可分解为一个单位下三角矩阵L 和一个上三角矩阵U 的乘积, 且这种分解是唯一的.定理1.2(对称正定矩阵的T LL 分解定理) 设A 为n 阶对称正定矩阵, 则必存在非奇异下的三角矩阵L , 使T A LL = , (1.1) 并且当L 的对角线元素均为正数时, 这种分解是唯一的.证明 因为A 对称正定, 则它的各阶顺序主子式均大于零. 由LU 分解定理可知, 矩阵A 存在唯一的Doolitle 分解, 即 1A LU = 其中, 1L 为单位下三角矩阵, U 为上三角矩阵. 记 D =diag 11(,,)nn u u ,1P D U -=, 则P 为单位上三角矩阵, 且1A L DP =. 由A 的对称性有T A A =, 可得 11T T T T A P D L L DP A ===由于T P 为单位下三角矩阵, T D D =, 从而由分解的唯一性可知, 1T P L =, 于是 11T A L DL =显然有110,(1,2,)k k k k k kk A L U L U u u k n ==⋅=>= ,这样0kk u >,(1,2,)k n = , 故可令 12D =diag则111122221111()()T TT A L D D L L D L D LL ===其中,121L L D =为非奇异的下三角矩阵. 而知限定L 的对角元素为正数时,这种分解是唯一的, 定理得证.1.2 Cholesky 分解法设A 为对称正定矩阵, 由上面T LL 分解定理可知, 则存在一个实的非奇异下三角矩阵L , 使T A LL =, 当限定L 的对角线元素为正数时, 这时A 的分解是唯一的.设11212212n n nn l l l L l l l ⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎣⎦ (1.2) 其中, 0(1,2,,)ii l i n >= , 0()ij l i j =<.由T A LL =比较A 和T LL 的对应元素, 可求得L 的元素ij l 如下:由 21111a l =,1111i i a l l =, 得11l =,1111/,1,2,,i i l a l i n == .假设L 的第1k -列元素已经求得, 下面求L 的第k 列元素,,,ik l i k n = . 注意到 11k ik ij kj ik kk j a l l l l -==+∑,得计算公式, 对1,2,,j n = , 有121/2111(),(1,2,,)()/,(,1,,1)k kk kk kj j k ik ik ij kj kkj l a l k n l a l l l k n n -=-=⎧=-=⎪⎪⎨⎪=-=-⎪⎩∑∑ (1.3) 由此可逐行求得L 的全部元素, 从而由Ly b =及T L x y =得到求解方程组Ax b =的公式111()/,(1,2,,)()/,(,1,,1)k k k kj j kk j nk k jk j kk j k y b l y l k n x y l x l k n n -==+⎧=-=⎪⎪⎨⎪=-=-⎪⎩∑∑ (1.4) 上述方法称为Cholesky 分解法. 由于计算的对角线元素要作n 次开平方运算, 故Cholesky 分解法又称平方根法.1.3 算法描述步1 输入对称正定矩阵A 和右端向量b ; 步2 Cholesky 分解:11111111,/,2,,,i i d t a l a d i n ==== 对2,,k n = 计算: 11,k k kk kj kj j d a t l -==-∑11,/,1,,;k ik ik ij kj ik ik k j t a t l l t d i k n -==-==+∑步3 用向前消去法解下三角方程组Ly b =: 11y b =,对2,,k n = 计算 11k k k kj j j y b l y -==-∑;步4 解对角形方程组Dz y =:对1,,k n = 计算 /k k k z y d =;步5 用回代法解上三角形方程组T L x z =:n n x z =,对1,,1k n =- 计算 1nk k jkj j k x z lx =+=-∑.不难验证Cholesky 分解法的乘除计算总量约为32/6()n O n +, 为一般矩阵LU 分解计算量的一半. 虽然如此, 但其增加的n 次开平方运算是非常不利的,下面引出改进的平方根法—T LDL 分解法.2 改进的平方根法为了避免开方运算, 对A 作LU 分解, 即A LU =, 则111212122212111n n n n nn u u u l u u A l l u ⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦/ 提出U 矩阵的对角元素 / 121112122212111111n n n n nn u u u l u u l l u ⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦⎣⎦由A 对称正定, 可得0ii u >, 令111222nn n u d u d D u d ⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦ 可证1212111n n Tu u u L ⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎣⎦即T A LDL =.1121212212111111n n n n n d l l l d l A l l d ⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦⎣⎦ (1.5) L 是对角元素为1的单位下三角矩阵.对矩阵A 作LU 分解, 共计算2n 个矩阵元素; 对称矩阵的T LDL 分解, 只需计算(1)2n n -个元素, 减少了近一半的工作量. 借助LU 分解计算公式, 容易得到T LDL 分解计算公式.设A 有LU 分解形式111211~212221211()1n n T n n n d d l d l l d d l A L DL LU l l d ⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥===⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦其中~ij i ij i ji u d l d l ==.在分解中可套用LU 分解公式, 只要计算下三角矩阵L 和D 的对角元素k d .计算中只需要保存()ij L l =的元素, T L 的i 行j 列的元素用L 的ji l 表示. 由于对称正定矩阵的各阶主子式均大于零, 直接调用LU 分解公式可完成T LDL 分解计算.对于1,,k n = ,有11~~11k k k kk kk kj jk kk kj j jk j j d u a l u a l d l --====-=-∑∑121k k kk j kj j d a d l -==-∑ (1.6)11~~11()/()/k k ik ik ij jk kk ik j ij kj k j j l a l u u a d l l d --===-=-∑∑11()/,1,,k ik ik j ij kj k j l a d l l d i k n -==-=+∑ . (1.7)3 T LDL 分解算法描述步1 输入方程组阶数n 、系数矩阵A 和常数项b . 步2 FOR :1k = TO n ;121:k k kk j kj j d a d l -==-∑;FOR :1i k =+ TO n ; 11:()/k ik ik j ij kj k j l a d l l d -==-∑;步3 解方程组的步骤从略.由()T L DL x b =, 解方程组Ax b =可分为三步完成: (1)解方程组Lz b =, 其中T z DL x =. 11,1,2,,i i i ij j j z b l z i n -==-=∑ (1.8)(2)解方程组Dy z =, 其中T y L x =. /,1,2,,i i i y z d i n == (1.9)(3)解方程组T L x y =. 1,,1,,1ni i jij j i x y lx i n n =+=-=-∑ . (1.10)可以看出, 改进后的T LDL 分解乘除运算量约为32/6()n O n +, 计算过程也无需开方运算, 使得其运算更加简单易行, 因此改进后的T LDL 分解法相对于原平方根法具有更好的实效性和可行性.4 应用举例例 试用T LDL 分解法求解方程组123164844543842210x x x -⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥-=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥-⎣⎦⎣⎦⎣⎦ 解 由T A LDL =, 可得Ax b =的方程组T LDL x b =, 令T DL x y =, 则Ly b =.计算步骤:(1)将A 直接分解为T A LDL =, 求出,L D ; (2)求解方程组Ly b =; (3)求解方程组1T L x D y -=. 现有1.16d =, 1214d l =, 2114l =, 1318d l =, 3112l =2122.154d d l =-=, 21312.3214d l d l l =--, 3232l =-, 39d =即由Ly b =可得1231411341013122y y y ⎡⎤⎢⎥-⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦⎢⎥-⎣⎦解得1234418y y y -⎡⎤⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦ 由1T L x D y -=有21311212323132311648145411842211l l d A l d l l l d ⎡⎤⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥=-=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥-⎣⎦⎣⎦⎣⎦⎣⎦111413122L ⎡⎤⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥-⎣⎦1649D ⎡⎤⎢⎥=⎢⎥⎢⎥⎣⎦1231111424311221x x x ⎡⎤⎡⎤⎢⎥-⎢⎥⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥-=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎢⎥⎢⎥⎣⎦⎢⎥⎣⎦解得1232494x x x ⎡⎤⎢⎥⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦-⎢⎥⎣⎦5 程序实现5.1 程序码源应用TLDL 分解法解线性方程组, 为了便于计算, 编写如下程序, 通过计算机来实现线性方程组的求解, 简洁方便. 具体程序如下: Purpose :T LDL 分解法解方程组 # include <stdio.h> # include <math.h># define MAX_N 20 //(x_i,y_i)的最大维数//int main() { int n; int i,j,k;int mi;double mx,tmp;static double a[MAX_N][MAX_N],b[MAX_N],x[MAX_N],y[MAX_N],z[MAX_N];static double L[MAX_N][MAX_N],d[MAX_N];//输入Ax=b的维数//printf("\n Input n value(dim of Ax=b):");scanf("%d",&n);if(n>MAX_N){printf("The input n is larger then MAX_N,please redefine the MAX_N.\n");return 1;}if(n<=0){printf("Please input a number between 1 and %d.\n", MAX_N);return 1;}//输入Ax=b的A矩阵//printf("Now input the matrix a(i,j),i,j=0,…, %d:\n", n-1);for(i=0;i<n;i++)for(j=0;j<n;j++)scanf("%lf",&a[i][j]);//输入b矩阵//printf("Now input the matrix b(i),i=0,…, %d:\n", n-1);for(i=0;i<n;i++)scanf("%lf",&b[i]);for(i=0;i<n;i++)L[i][i]=1; //u矩阵对角元素为1//for(k=0;k<n;k++){d[k]=a[k][k]; //计算d_i//for(j=0;j<=k-1;j++)d[k]-=(L[k][j] *d[j]*L[k][j]);for(i=k+1;i<n;i++) //计算L矩阵// {L[i][k]=a[i][k];for(j=0;j<=k-1;j++)L[i][k]-=(L[i][j] *d[j]*L[k][j]);L[i][k]/=d[k];}}for(i=0;i<n;i++) //求解L′z=b的z// {z[i]=b[i];for(j=0;j<=i-1;j++)z[i]-=L[i][j]*z[j];}for(i=0;i<n;i++) //求解Dy=z的y//y[i]=z[i]/d[i];for(i=n-1;i>=0;i--) //求解Ly=x// {x[i]=y[i];for(j=i+1;j<n;j++)x[i]-=L[j][i]*x[j];}printf("Solve … x_i=\n"); //输出//for(i=0;i<n;i++)printf("%f\n",x[i]);return 0;}5.2 实例计算用T LDL 分解法求解方程组:123164844543842210x x x -⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥-=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥-⎣⎦⎣⎦⎣⎦ 程序输入输出Input n value(dim of Ax=b): 3Now input the matrix a(i,j),i,j=0, (2)16 4 8 4 5 -4 8 -4 22Now input the matrix b(i),i=0, (2)-4 3 10Solve … x_i=2.0000004.000000-2.2500006 结束语从矩阵分解角度看, T LDL 分解法与消元法本质上没有多大的区别, 其基本思想还是通过等价变换将线性方程组化为结构简单、易于求解的形式. 在实际问题中经常遇到对称正定矩阵方程组的求解问题, 对于这种具有特殊性质的系数矩阵, 采用改进的平方根法是一种行之有效的计算方法, 它是在普通消去法的基础上建立起来的, 算法思想虽有些复杂, 但其计算量约为普通消去法的一半, 且有效地避免了开方运算所带来的不便, 因此改进后的T LDL 分解法相对于原平方根法具有更好的实效性和可行性. 并通过C 程序求解使得这类问题变得更加简单易行, 在大量工程计算中有着广泛而重要的应用.参考文献[1] 刘元亮. Matlab 在对称正定矩阵的改进平方根分解法中的应用[J]. 湖南: 怀化学院学报. 2004,(02).[2] 郭丽杰, 周硕, 秦万广. 对称矩阵的改进Cholesky 分解在特征值问题中的应用[J]. 吉林: 东北电力学院学报. 2003,(02).[3] 杜廷松,沈艳君,覃太贵.数值分析及实验[M].北京:科学出版社.2007.[4] 肖筱南,赵来军,党林立.数值计算方法与上机实习指导[M].北京:北京大学出版社. 2004.[5] 马昌凤,林伟川.现代数值计算方法[M].北京: 科学出版社.2008.[6] 张韵华,奚梅成,陈长松.数值计算方法与算法[M].北京:科学出版社.2000.[7] 李庆扬,王能超,易大义.数值分析(4版)[M].武汉:华中科技大学出版社.2006.[8]严克明,欧志英,刘树群.数值计算基础[M].甘肃:甘肃人民出版社.2006.[9] Ferenc Szidsrovzky, Sidney Yokowitz. Principles and procedures of numerical analysis[M].上海:上海科学技术文献出版社.1982.[10] Rainer Kress. Numerical analysis[M].北京:世界图书出版社.2003.致谢本论文经过将近半年的努力即将告以尾声, 从论文的选题到最后完稿, 整个过程都经过了认真地考虑、仔细地查阅和细心地修改. 在此, 我首先要感谢我的导师郭晓斌老师, 不管是我的论文选题还是论文的撰写, 以及资料的查阅等各方面, 他都给了我莫大的帮助与启发, 尤其是在论文的几次修改过程中, 郭老师以他广博的专业学识、严谨的治学精神和他耐心的指导态度, 才使我的论文能顺利完成. 谨再次向郭老师致以崇高的敬意和诚挚的感谢. 也祝愿郭老师身体健康、工作顺利, 在学术研究上取得更加辉煌的成就, 为更多的学子导航.同时, 我也要对给予本论文参考文献的所有学术专家和老师致以真挚的谢意, 是他们出版的书籍与发表的学术论文给了我很大的启示与指导, 才将论文完成.其次, 在即将毕业之际, 我要感谢数信学院所有的老师对我的细心教育与培养, 让我在四年的学习生涯中不仅学到了扎实的专业知识, 而且他们的言传身教使我受益匪浅, 他们严谨的治学态度和耐心教导学生的博爱精神也是我永远学习的榜样, 并将积极影响着我今后的学习和工作.最后, 我还要再次感谢我的母校——西北师范大学给了我发展的平台, 感谢各位老师四年来对我的耐心教导和栽培.张登科 2011年5月。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
for(j = 0 ; j < H ; j++)
for(i = j+1 ; i < H ; i++)
a[j][i] = a[i][j]; //转置
/************** 检验方程是否错误 ***************/
for(i = 0 ,flag = 0 ; i < H ; j++)
{
for(k = 0 ; k <= i ; k++)
printf("%lf ",a[i][k]);
printf("\n");
}
printf("\nL的转置矩阵为:\n");
for(j = 0 ; j< H ; j++)
{
for(i = 0 ; i < H ; i++)
{
if(a[i][i] == 0)
{
printf("方程系数输入有误\n");
flag = 1 ; //flag置1
}break;
}
if(flag != 1) // flag标志位不为0时继续计算
{/******************* 求解y[i] ******************/
printf("\nY的值为:\n");
for(i = 0 ; i < H ; i++)
printf("y%d=%lf\n",i+1,y[i]);
/***************** 打印X的值 *******************/
printouble s; int i , j ,k ;
/*********** 求解L矩阵,L下三角 *************/
a[0][0] = sqrt(a[0][0]); //求解a11
for (i = 1; i < H; i++) //第一列
}
/******************* 求解x[i] ******************/
b[H-1]= y[H-1] / a[H-1][H-1]; //先求xn
for (k = H-2; k >= 0; k--)
{
for (s = 0, j = k+1; j < H; j++)
y[0]= b[0] / a[0][0]; //先求y1
for (k = 0; k < H; k++)
{
for (s = 0, j = 0; j < k; j++)
s += a[k][j] * y[j];
y[k] = (b[k] - s) / a[k][k]; //再求yk...n
Cholesky(a,b,H);
} free(b); //释放动态开辟的空间
for (i = 0; i < H; ++i)
free(a[i]); //a行
free(a); //a列
}
for (i = 0; i < H; i++)
for (j = 0; j < H; j++)
scanf("%lf",&a[i][j]);
printf("请输入向量b:\n");
for (i = 0; i < H; i++)
scanf("%lf",&b[i]);
{
if(i < j)
printf(" ");
else
printf("%lf ",a[i][j]);
}
printf("\n");
}
/***************** 打印Y的值 *******************/
}
int main()
{ double **a , *b;
int i, j , H;
while(flag == 1)
{ printf("请输入未知数个数n:\n");
scanf("%d", &H);
a = (double**)malloc(sizeof(double*)*H); //为二维数组分配H行
#include<stdio.h>
#include <malloc.h>
#include<math.h>
extern int flag=1; //0时正确 1时错误
int Cholesky(double **a , double *b , int H)
{
double *y = (double *) malloc(sizeof(double)*H);
for(i = 0 ; i < H ; i++)
printf("x%d=%lf\n",i+1,b[i]);
free(y); //释放动态开辟的空间
return 0;
}
else if(flag == 1)
flag = 1; //flag标志位置1,退出
return 0;
a[i][0] = a[i][0] / a[0][0]; //求解ai1
for (k = 1; k < H; k++) //第k列
{
for (i = k; i < H; i++) //下三角,i>k
{ //求aik
else if (i == k) //akk,主对角线元素
a[i][k] = sqrt(a[i][k] - s);
}
}
/*********** 求解L矩阵转置,L上三角 *************/
b = (double *) malloc(sizeof(double)*H);
for (i = 0; i < H; i++) //为每列分配H个大小空间
a[i] = (double*)malloc(sizeof(double)*H);
printf("请输入系数矩阵:\n"); //初始化
s += a[j][k] * b[j];
b[k] = (y[k] - s) / a[k][k]; //再求xi...1
}
/************** 打印L矩阵,L转置 ****************/
printf("\nL的下三角矩阵为:\n");
for(i = 0 ; i < H ; i++)
for (s = 0, j = 0; j < k; j++)
s += a[i][j] * a[k][j]; //求中间和
if (i > k) //下三角元素
a[i][k] = (a[i][k] - s) / a[k][k];
相关文档
最新文档