c Scilab ( http://www.scilab.org/ ) - This file is part of Scilab c Copyright (C) 1986-2008 - INRIA - Francois DELBECQUE c Copyright (C) 1990-2008 - INRIA - Serge STEER c c This file must be used under the terms of the CeCILL. c This source file is licensed as described in the file COPYING, which c you should have received as part of this distribution. The terms c are also available at c http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt subroutine sfact1(b,n,w,maxit,ierr) c!but c on cherche une factorisation spectrale d'un polynome a donne c par : a*(a(1/z) = b(n)*z**-n+....+b(0)+ ... +b(n)*z**n c!liste d'appel c subroutine sfact1(b,n,w,maxit,ierr) c c double precision b(n+1),w(6*(n+1)) c integer n,maxit,ierr c c b : contient les coeffs b(n),b(n-1),....,b(0) c apres execution b contient les coeff du resultat c n : degre de a c w : tableau de travail de taille 6*(n+1) c maxit : nombre maxi d'iterations admis c ierr : indicateur d'erreur c si ierr=0 : ok c si ierr<0 : convergence a 10**ierr pres c si ierr=1 : non convergence c si ierr=2 : b(0) est negatif ou nul. c c!origine c V Kucera : Discrete Linear control (john Wiley& Sons) 1979 c! dimension b(n+1),w(*) double precision b,b0,w,a0,temp,b00,s,dlamch,eps,best c eps=dlamch('p')*10.0d+0 c lb=n+1 ierr=0 c lomeg=1 lalpha=lomeg+lb lro=lalpha+lb leta=lro+lb lbold=leta+lb lambda=lbold+lb lsave=lambda+lb c call dcopy(lb,b,-1,w(lbold),1) call dcopy(lb,w(lbold),1,b,1) b00=w(lbold) if(b00.le.0.0d+0) goto 91 b0=sqrt(b00) do 1 j=1,lb w(lalpha-1+j)=b(j)/b0 1 continue c do 40 i=1,maxit c call dcopy(lb,w(lbold),1,b,1) call dcopy(lb,w(lalpha),1,w(lomeg),1) c premier tableau do 15 k=1,lb-1 call dcopy(lb-k+1,w(lalpha),-1,w(lro),1) w(lambda+k-1)=w(lalpha+lb-k)/w(lro+lb-k) do 11 j=1,lb-k w(lalpha-1+j)=w(lalpha-1+j)-w(lambda+k-1)*w(lro+j-1) 11 continue a0=w(lalpha) c calcul de eta w(leta+lb-k)=2.0d+0*b(lb-k+1)/a0 if (k.lt.lb-1) then do 12 j=2,lb-k b(j)=b(j)-0.50d+0*w(leta+lb-k)*w(lalpha+lb-k-j+1) 12 continue endif 15 continue w(leta)=b(1)/w(lalpha) c deuxieme tableau do 21 k=lb-1,1,-1 call dcopy(lb-k+1,w(leta),-1,b,1) do 19 j=1,lb-k+1 w(leta+j-1)=w(leta+j-1)-w(lambda+k-1)*b(j) 19 continue 21 continue s=0.0d+0 do 22 j=1,lb w(lalpha-1+j)=0.50d+0*(w(leta+j-1)+w(lomeg+j-1)) s=s+w(lalpha-1+j)*w(lalpha-1+j) 22 continue c c test de convergence c calcul de l'erreur element par elements c$$$ call dcopy(lb,w(lbold),-1,b,1) c$$$ do 900 iii=0,n c$$$ x=b(iii+1)-ddot(iii+1,w(lalpha),1,w(lalpha+n-iii),1) c$$$ write(6,'(10x,e10.3,'','',e10.3,'';'')') x,b(1+iii) c$$$ 900 continue temp=abs(s-b00)/b00 if(temp.le.eps) goto 50 if(i.eq.1) best=temp if(temp.lt.best) then call dcopy(lb,w(lalpha),1,w(lsave),1) best=temp endif 40 continue goto 90 c 50 do 51 i=1,lb b(i)=w(lalpha-1+i) 51 continue return c c retours en erreur c 90 continue if(best.le.1.d-3) then call dcopy(lb,w(lsave),1,b,1) ierr=nint(log10(best)) else c non convergence ierr=1 endif return 91 continue c b00 est negatif ou nul ierr=2 return end