#include #include #include #include "xpplim.h" #define Z(a,b) z[(a)+n*(b)] #define DING ping() /* this code takes the determinant of a complex valued matrix */ extern double variable_shift[2][MAXODE],AlphaMax,OmegaMax; extern double delay_list[MAXDELAY]; extern int NDelay,del_stab_flag,WhichDelay,DelayGrid; extern (*rhs)(); double amax(); typedef struct{ double r,i; }COMPLEX; /* The code here replaces the do_sing code if the equation is a delay differential equation. */ do_delay_sing(x,eps,err,big,maxit,n,ierr,stabinfo) double *x,eps,err,big; int *ierr,n,maxit; float *stabinfo; { double rr[2]; double colnorm=0,colmax,colsum; double *work,old_x[MAXODE],sign; double *coef,yp[MAXODE],y[MAXODE],xp[MAXODE],dx; int kmem=n*(2*n+5)+50,i,j,k,okroot; int nd=NDelay; double *ev; ev=(double *)malloc(2*n*sizeof(double)); for(i=0;i<(2*n);i++)ev[i]=0.0; /* first we establish how many delays there are */ del_stab_flag=0; for(i=0;icolmax)colmax=colsum; } colnorm=colmax; for(j=0;jcolmax)colmax=colsum; } colnorm+=colmax; } /* printf("Norm= %g \n",colnorm); */ /* sign=plot_args(coef,delay_list,n,NDelay,DelayGrid,AlphaMax,OmegaMax); */ sign=plot_args(coef,delay_list,n,NDelay,DelayGrid,colnorm,colnorm); okroot=find_positive_root(coef,delay_list,n,NDelay,colnorm,err,eps,big,maxit,rr); if(okroot>0){ ev[0]=rr[0]; ev[1]=rr[1]; } free(coef); *stabinfo=(float)fabs(sign); /* if(*stabinfo>0) */ i=(int)sign; if(i==0&&okroot==1&&AlphaMax>0) i=2; create_eq_box(abs(i),2,0,0,0,x,ev,n); /* DING; */ del_stab_flag=1; free(ev); if(okroot==1)*stabinfo=AlphaMax; } COMPLEX csum(z,w) COMPLEX z,w; { COMPLEX sum; sum.r=z.r+w.r; sum.i=z.i+w.i; return sum; } COMPLEX cdif(z,w) COMPLEX z,w; { COMPLEX sum; sum.r=z.r-w.r; sum.i=z.i-w.i; return sum; } COMPLEX cmlt(z,w) COMPLEX z,w; { COMPLEX sum; sum.r=z.r*w.r-z.i*w.i; sum.i=z.r*w.i+z.i*w.r; return sum; } COMPLEX cdiv(z,w) COMPLEX z,w; { COMPLEX sum; double amp=w.r*w.r+w.i*w.i; sum.r=(z.r*w.r+z.i*w.i)/amp; sum.i=(z.i*w.r-z.r*w.i)/amp; return sum; } COMPLEX cexp2(z) COMPLEX z; { COMPLEX sum; double ex=exp(z.r); sum.r=ex*cos(z.i); sum.i=ex*sin(z.i); return sum; } switch_rows(z,i1,i2,n) COMPLEX *z; int i1,i2,n; { COMPLEX zt; int j; for(j=0;jqmax){ qmax=q; imax=i; } } if(qmax==0.0)return(rtoc(0.0,0.0)); switch_rows(z,imax,j,n); if(imax>j)sign=cmlt(rtoc(-1.0,0.0),sign); zd=Z(j,j); for(i=j+1;ieps) r=eps*fabs(xl); else r=eps*eps; xlp=xl+r; lambdap=rtoc(xlp,yl); make_z(z,delay,n,m,coef,lambdap); detp=cdeterm(z,n); jac[0]=(detp.r-det.r)/r; jac[2]=(detp.i-det.i)/r; if(fabs(yl)>eps) r=eps*fabs(yl); else r=eps*eps; ylp=yl+r; lambdap=rtoc(xl,ylp); make_z(z,delay,n,m,coef,lambdap); detp=cdeterm(z,n); jac[1]=(detp.r-det.r)/r; jac[3]=(detp.i-det.i)/r; r=jac[0]*jac[3]-jac[1]*jac[2]; if(r==0){ printf(" singular jacobian \n"); return -1; } xlp=(jac[3]*det.r-jac[1]*det.i)/r; ylp=(-jac[2]*det.r+jac[0]*det.i)/r; xl=xl-xlp; yl=yl-ylp; r=fabs(xlp)+fabs(ylp); lambda.r=xl; lambda.i=yl; if(rbig){ printf("Failed to converge \n"); return -1; } } printf("Max iterates exceeded \n"); return -1; } process_root(real,im) double real,im; { printf("Root: %g + I %g \n",real,im); } double get_arg(delay,coef,m,n,lambda) COMPLEX lambda; double *coef; double *delay; int m,n; { int i,j,k,km; COMPLEX *z; COMPLEX temp,eld; double arg; if(m==0)return(0); /* no delays so don't use this! */ z=(COMPLEX *)malloc(sizeof(COMPLEX)*n*n); for(j=0;j0.0&&new<0.0){ if(old>2.9&&new<-2.9)return 1; return(0); /* doesnt pass threshold */ } if(old<0.0&&new>0.0){ if(old<-2.9&&new>2.9)return -1; return 0; } return 0; } /* code for establishing delay stability sign=plot_args(coef,delay,n,m,npts,amax,wmax) coef is a real array of length (m+1)*n^2 each n^2 block is the jacobian with respect to the mth delay m total delays n is size of system npts is number of pts on each part of contour contour is i wmax -----<--------- amax+i wmax | | V ^ | | -i wmax ----->----------- amax-i wmax sign is the number of roots in the contour using the argument principle */ plot_args(coef,delay,n,m,npts,almax,wmax) double *coef; int n,m,npts; double almax,wmax,*delay; { int i; int sign=0; COMPLEX lambda; double x,y,arg,oldarg=0.0; double ds; /* steplength */ /* first the contour from i wmax -- -i wmax */ ds=2*wmax/npts; x=0.0; for(i=0;i