예제 #1
0
void retris(complex *data,complex *a,complex *c, complex *b,
		complex endl,complex endr, int nx, complex *d)
{
		 
	int ix;
	complex *e,den;
	complex *f;

	e=alloc1complex(nx);
	f=alloc1complex(nx);
	e[0]=cdiv(cneg(a[0]),endl);
	f[0]=cdiv(d[0],endl);

	for(ix=1;ix<nx-1;++ix){
		den=cadd(b[ix],cmul(c[ix],e[ix-1]));
		e[ix]=cdiv(cneg(a[ix]),den);
		f[ix]=cdiv(csub(d[ix],cmul(f[ix-1],c[ix])),den);
	}
		 

	data[nx-1]=cdiv(csub(d[nx-1],cmul(f[nx-2],c[nx-2])),cadd(endr,cmul(c[nx-2],e[nx-2])));
		
	for(ix=nx-2;ix>-1;--ix)
	data[ix]=cadd(cmul(data[ix+1],e[ix]),f[ix]);

	free1complex(e);
	free1complex(f);
	return;  
}
예제 #2
0
파일: tetra.c 프로젝트: 99years/plan9
int
Xtetra(struct place *place, double *x, double *y)
{
	int i,j;
	struct place pl;
	register struct tproj *tpp;
	double vr, vi;
	double br, bi;
	double zr,zi,z2r,z2i,z4r,z4i,sr,si,tr,ti;
	twhichp(place,&i,&j);
	copyplace(place,&pl);
	norm(&pl,&tproj[i][j].projpl,&tproj[i][j].projtw);
	Xstereographic(&pl,&vr,&vi);
	zr = vr/2;
	zi = vi/2;
	if(zr<=TFUZZ)
		zr = TFUZZ;
	csq(zr,zi,&z2r,&z2i);
	csq(z2r,z2i,&z4r,&z4i);
	z2r *= two_rt3;
	z2i *= two_rt3;
	cdiv(z4r+z2r-1,z4i+z2i,z4r-z2r-1,z4i-z2i,&sr,&si);
	csqrt(sr-1,si,&tr,&ti);
	cdiv(tcon*tr,tcon*ti,root3+1-sr,-si,&br,&bi);
	if(br<0) {
		br = -br;
		bi = -bi;
		if(!elco2(br,bi,tk,1.,1.,&vr,&vi))
			return 0;
		vr = fpir - vr;
		vi = fpii - vi;
	} else 
		if(!elco2(br,bi,tk,1.,1.,&vr,&vi))
			return 0;
	if(si>=0) {
		tr = f0r - vi;
		ti = f0i + vr;
	} else {
		tr = f0r + vi;
		ti = f0i - vr;
	}
	tpp = &tproj[i][j];
	*x = tr*tpp->postrot.c +
	     ti*tpp->postrot.s + tx[i];
	*y = ti*tpp->postrot.c -
	     tr*tpp->postrot.s + ty[i];
	return(1);
}
예제 #3
0
파일: hex.c 프로젝트: 00001/plan9port
static int
Xhex(struct place *place, double *x, double *y)
{
	int ns;
	int i;
	double zr,zi;
	double sr,si,tr,ti,ur,ui,vr,vi,yr,yi;
	struct place p;
	copyplace(place,&p);
	ns = place->nlat.l >= 0;
	if(!ns) {
		p.nlat.l = -p.nlat.l;
		p.nlat.s = -p.nlat.s;
	}
	if(p.nlat.l<HFUZZ) {
		for(i=0;i<3;i++)
			if(fabs(reduce(p.wlon.l-hcut[i]))<HFUZZ) {
				if(i==2) {
					*x = 2*cr[0] - cr[1];
					*y = 0;
				} else {
					*x = cr[1];
					*y = 2*ci[2*i];
				}
				return(1);
			}
		p.nlat.l = HFUZZ;
		sincos(&p.nlat);
	}
	norm(&p,&hem,&twist);
	Xstereographic(&p,&zr,&zi);
	zr /= 2;
	zi /= 2;
	cdiv(1-zr,-zi,1+zr,zi,&sr,&si);
	csq(sr,si,&tr,&ti);
	ccubrt(1+3*tr,3*ti,&ur,&ui);
	csqrt(ur-1,ui,&vr,&vi);
	cdiv(rootroot3+vr,vi,rootroot3-vr,-vi,&yr,&yi);
	yr /= rootk;
	yi /= rootk;
	elco2(fabs(yr),yi,hkc,1.,1.,x,y);
	if(yr < 0)
		*x = w2 - *x;
	if(!ns) reflect(hcut[0]>place->wlon.l?0:
			hcut[1]>=place->wlon.l?1:
			2,*x,*y,x,y);
	return(1);
}
예제 #4
0
static complex *
c_tan(complex *cc, int length)
{
    complex *c;
    int i;

    c = alloc_c(length);
    for (i = 0; i < length; i++) {
	double u, v;

	rcheck(cos(degtorad(realpart(&cc[i]))) *
	       cosh(degtorad(imagpart(&cc[i]))), "tan");
	rcheck(sin(degtorad(realpart(&cc[i]))) *
	       sinh(degtorad(imagpart(&cc[i]))), "tan");
	u = degtorad(realpart(&cc[i]));
	v = degtorad(imagpart(&cc[i]));
        /* The Lattice C compiler won't take multi-line macros, and
         * CMS won't take >80 column lines....
         */
#define xx1 sin(u) * cosh(v)
#define xx2 cos(u) * sinh(v)
#define xx3 cos(u) * cosh(v)
#define xx4 sin(u) * sinh(v)
        cdiv(xx1, xx2, xx3, xx4, realpart(&c[i]), imagpart(&c[i]));
    }
    return c;
}
int main()
{
	int x,y,result;
	char operator;
	while (1)
	{
		printf("Please input the calculation as form: number operator number\n");
                scanf ("%d %c %d",&x,&operator,&y);	//Get parameters
		fflush(stdin);                                                          
        	switch(operator)	//judge which operator                                                        
        	{                                                                       
                	case '+':                                                       
                        	result = add(x,y);                                     
                        	break;                                                  
                	case '-':                                                       
                        	result = sub(x,y);                                       
                        	break;                                                  
                	case '*':                                                       
                        	result = mul(x,y);                                  
                        	break;                                                  
                	case '/':                                                       
                        	result = cdiv(x,y);                                       
                        	break;                                                  
                	case '%':                                                       
                        	result = mod(x,y);                                       
                        	break;                                                  
                	default:	//wrong input, exit with 0                                                
                        	exit(0);                                                
        	}
		printf ("%d\n",result);	//print out result in new line                
	}
	return 0;
}
예제 #6
0
파일: nzmg.c 프로젝트: ndonnelly/concord
void nzmg_geod( double e, double n, double *ln, double *lt )
{
    complex z0, z1, zn, zd, tmp1, tmp2;
    double sum,tmp;
    int i, it;

    z0.real = (n-n0)/a;     z0.imag = (e-e0)/a;
    z1.real = cfb2[5].real; z1.imag = cfb2[5].imag;
    for (i=5; i--; ) cadd(&z1, cmult(&z1, &z1, &z0), cfb2+i );
    cmult(&z1,&z1,&z0);

    for(it=2; it--; )
    {
        cscale( &zn, cfb1+5, 5.0);
        cscale( &zd, cfb1+5, 6.0);
        for (i=4; i; i--)
        {
            cadd( &zn, cmult(&tmp1, &zn, &z1), cscale(&tmp2, cfb1+i, (double) i));
            cadd( &zd, cmult(&tmp1, &zd, &z1), cscale(&tmp2, cfb1+i, (double) (i+1)));
        }
        cadd( &zn, &z0, cmult( &zn, cmult( &zn, &zn, &z1), &z1));
        cadd( &zd, cfb1, cmult( &zd, &zd, &z1 ));
        cdiv( &z1, &zn, &zd );
    }

    *ln = ln0/rad2deg + z1.imag;

    tmp = z1.real;
    sum = cfl[8];
    for (i=8; i--;) sum = sum*tmp + cfl[i];
    sum *= tmp/3600.0e-5;
    *lt = (lt0+sum)/rad2deg;
}
예제 #7
0
파일: lune.c 프로젝트: dancrossnyc/harvey
static int
Xlune(struct place *place, double *x, double *y)
{
	double stereox, stereoy;
	double z1x, z1y, z2x, z2y;
	double w1x, w1y, w2x, w2y;
	double numx, numy, denx, deny;
	if(place->nlat.l < eastpole.nlat.l-FUZZ)
		return	-1;
	Xstereographic(place, &stereox, &stereoy);
	stereox *= scale;
	stereoy *= scale;
	z1x = 1 + stereox;
	z1y = stereoy;
	z2x = 1 - stereox;
	z2y = -stereoy;
	cpow(z1x,z1y,&w1x,&w1y,pwr);
	cpow(z2x,z2y,&w2x,&w2y,pwr);
	numx = w1x - w2x;
	numy = w1y - w2y;
	denx = w1x + w2x;
	deny = w1y + w2y;
	cdiv(numx, numy, denx, deny, x, y);
	return 1;
}
예제 #8
0
//
//	The real cpu killer: this function is called once for every
//	sample that comes from the dongle. So, it really should be
//	optimized.
bool	DecimatingFIR::Pass (DSPCOMPLEX z, DSPCOMPLEX *z_out) {
int16_t		i;
DSPCOMPLEX	tmp	= 0;
int16_t		index;

	Buffer [ip] = z;
	if (++decimationCounter < decimationFactor) {
	   ip =  (ip + 1) % filterSize;
	   return false;
	}

	decimationCounter = 0;
//
//	we are working with a circular buffer, we take two steps
//	we move from ip - 1 .. 0 with i going from 0 .. ip -1
	for (i = 0; i <= ip; i ++) {
	   index =  ip - i;
	   tmp 	+= Buffer [index] * filterKernel [i];
	}
//	and then we take the rest
	for (i = ip + 1; i < filterSize; i ++) {
	   index =  filterSize + ip - i;
	   tmp 	+= Buffer [index] * filterKernel [i];
	}

	ip = (ip + 1) % filterSize;
	*z_out =  cdiv (tmp, filterSize);
	return true;
}
예제 #9
0
/*
 * Returns the magnitude of the transfer function Hs(s) for a 1/3
 * octave 6-pole Butterworth bandpass filter of the given frequency.
 *
 * @param w is relative frequency (1.0 = center freq)
 */
static double
butter(double w)
{
    COMPLEX denom, num, h;
    double gammaval, k1, k2, k3, k4;

    /* 1/3 octave gammaval */
    gammaval = pow(2.0, 1.0/6.0) - pow(2.0, -1.0/6.0);

    /* coefficients */
    k1 = pow(gammaval, 3.0);
    k2 = 2.0 * gammaval;
    k3 = 3.0 + 2.0 * pow(gammaval, 2.0);
    k4 = gammaval * (4.0 + pow(gammaval, 2.0));

    num.re = 0.0;
    num.im = -k1 * pow(w, 3.0);

    denom.re = 1.0 - k3 * pow(w, 2.0)
	+ k3 * pow(w, 4.0) - pow(w, 6.0);
    denom.im = k2 * w - k4 * pow(w, 3.0)
	+ k2 * pow(w, 5.0);

    cdiv(&h, &num, &denom);

    /* printf("(%f, %f)\n", h.re, h.im);*/

    return hypot(h.re, h.im);
}
void csqrt( cmplx *z, cmplx *w )
{
    cmplx q, s;
    double x, y, r, t;
    x = z->r;
    y = z->i;
    if( y == 0.0 )
    {
        if( x < 0.0 )
        {
            w->r = 0.0;
            w->i = sqrt(-x);
            return;
        }
        else
        {
            w->r = sqrt(x);
            w->i = 0.0;
            return;
        }
    }
    if( x == 0.0 )
    {
        r = fabs(y);
        r = sqrt(0.5*r);
        if( y > 0 )
            w->r = r;
        else
            w->r = -r;
        w->i = r;
        return;
    }

    /* Approximate  sqrt(x^2+y^2) - x  =  y^2/2x - y^4/24x^3 + ... .
     * The relative error in the first term is approximately y^2/12x^2 .
     */
    if( (fabs(y) < 2.e-4 * fabs(x))
            && (x > 0) )
    {
        t = 0.25*y*(y/x);
    }
    else
    {
        r = cabs(z);
        t = 0.5*(r - x);
    }

    r = sqrt(t);
    q.i = r;
    q.r = y/(2.0*r);
    /* Heron iteration in complex arithmetic */
    cdiv( &q, z, &s );
    cadd( &q, &s, w );
    w->r *= 0.5;
    w->i *= 0.5;
}
예제 #11
0
// HIGHPASS
pzkContainer * t2hp(pzkContainer * pzk, real w0) {
	pzkContainer * f = createPzkContainer(pzk->nextPole, pzk->nextZero);
	uint i;
	complex tmp;
	
	f->amp = pzk->amp * pow(w0,(real)pzk->no_wz);
	f->no_wz = -pzk->no_wz;

	for( i = 0; i < pzk->nextPole; i++ ) {
		tmp.re = w0;
		tmp.im = 0;
		f->no_wz++;
		if( cisreal(pzk->poles[i]) ) {
			f->amp /= -pzk->poles[i].re;
			tmp.re /= pzk->poles[i].re;
		} else {
			tmp = cdiv(tmp, pzk->poles[i]);
			f->amp /= cabs2(pzk->poles[i]);
			f->no_wz++;
		}
		addPole(f, tmp);
	}
	
	for( i = 0; i < pzk->nextZero; i++ ) {
		tmp.re = w0;
		tmp.im = 0;
		f->no_wz--;	
		if( cisreal(pzk->zeros[i]) ) {
			f->amp *= -pzk->zeros[i].re;
			tmp.re /= pzk->zeros[i].re;
		} else {
			tmp = cdiv(tmp, pzk->zeros[i]);
			f->amp *= cabs2(pzk->zeros[i]);
			f->no_wz--;
		}
		addZero(f, tmp);
	}
	
	f->type = highpass;
	return f;
	
}
예제 #12
0
파일: MulDiv.c 프로젝트: elff1/myCodes
int main(void) {
    char Choice;
    short int a,b;
    unsigned short int x,q;
    unsigned char y,r;
    long int c;

    instruction();

    printf("\nChoice:");
    Choice=getchar();
    getchar();
    while(Choice!='0') {
        switch(Choice) {
        case '5':
            printf("Input two 16-bit short ints:\n");
            scanf("%d%d",&a,&b);
            c=cmul(a,b);
            printf("%d * %d = %d\n",a,b,c);
            break;
        case '6':
            printf("Input a 16-bit unsigned short int and a 8-bit unsigned int:\n");
            scanf("%d%d",&x,&y);
            if(!y)
                printf("Divisor should be positive.\n");
            else {
                cdiv(x,y,&q,&r);
                printf("%d / %d = %d remains %d\n",x,y,q,r);
            }
            break;
        default:
            printf("Wrong choice number!\n\n");
            instruction();
        }

        printf("\nChoice:");
        do {
            Choice=getchar();
        } while(Choice>'9'||Choice<'0');
    }
}
예제 #13
0
void EigenvalueDecomposition::hqr2(){
    
    // Initialize
    int nn = this->n;
    int n = nn-1;
    int low = 0;
    int high = nn-1;
    Float eps = pow(2.0,-52.0);
    Float exshift = 0.0;
    Float p=0,q=0,r=0,s=0,z=0,t,w,x,y;
    
    // Store roots isolated by balanc and compute matrix norm
    Float norm = 0.0;
    for(int i = 0; i < nn; i++) {
        if( (i < low) | (i > high) ){
            realEigenvalues[i] = h[i][i];
            complexEigenvalues[i] = 0.0;
        }
        for (int j = findMax(i-1,0); j < nn; j++) {
            norm = norm + fabs(h[i][j]);
        }
    }
    
    // Outer loop over eigenvalue index
    int iter = 0;
    while (n >= low) {
        
        // Look for single small sub-diagonal element
        int l = n;
        while (l > low) {
            s = fabs(h[l-1][l-1]) + fabs(h[l][l]);
            if (s == 0.0) {
                s = norm;
            }
            if(fabs(h[l][l-1]) < eps * s) {
                break;
            }
            l--;
        }
        
        // Check for convergence
        // One root found
        if(l == n) {
            h[n][n] = h[n][n] + exshift;
            realEigenvalues[n] = h[n][n];
            complexEigenvalues[n] = 0.0;
            n--;
            iter = 0;
            
            // Two roots found
        } else if (l == n-1) {
            w = h[n][n-1] * h[n-1][n];
            p = (h[n-1][n-1] - h[n][n]) / 2.0;
            q = p * p + w;
            z = sqrt(fabs(q));
            h[n][n] = h[n][n] + exshift;
            h[n-1][n-1] = h[n-1][n-1] + exshift;
            x = h[n][n];
            
            // Real pair
            if (q >= 0) {
                if (p >= 0) {
                    z = p + z;
                } else {
                    z = p - z;
                }
                realEigenvalues[n-1] = x + z;
                realEigenvalues[n] = realEigenvalues[n-1];
                if (z != 0.0) {
                    realEigenvalues[n] = x - w / z;
                }
                complexEigenvalues[n-1] = 0.0;
                complexEigenvalues[n] = 0.0;
                x = h[n][n-1];
                s = fabs(x) + fabs(z);
                p = x / s;
                q = z / s;
                r = sqrt(p * p+q * q);
                p = p / r;
                q = q / r;
                
                // Row modification
                for(int j = n-1; j < nn; j++) {
                    z = h[n-1][j];
                    h[n-1][j] = q * z + p * h[n][j];
                    h[n][j] = q * h[n][j] - p * z;
                }
                
                // Column modification
                for(int i = 0; i <= n; i++) {
                    z = h[i][n-1];
                    h[i][n-1] = q * z + p * h[i][n];
                    h[i][n] = q * h[i][n] - p * z;
                }
                
                // Accumulate transformations
                for(int i = low; i <= high; i++) {
                    z = eigenvectors[i][n-1];
                    eigenvectors[i][n-1] = q * z + p * eigenvectors[i][n];
                    eigenvectors[i][n] = q * eigenvectors[i][n] - p * z;
                }
                
                // Complex pair
            } else {
                realEigenvalues[n-1] = x + p;
                realEigenvalues[n] = x + p;
                complexEigenvalues[n-1] = z;
                complexEigenvalues[n] = -z;
            }
            n = n - 2;
            iter = 0;
            
            // No convergence yet
        } else {
            
            // Form shift
            x = h[n][n];
            y = 0.0;
            w = 0.0;
            if (l < n) {
                y = h[n-1][n-1];
                w = h[n][n-1] * h[n-1][n];
            }
            
            // Wilkinson's original ad hoc shift
            if (iter == 10) {
                exshift += x;
                for (int i = low; i <= n; i++) {
                    h[i][i] -= x;
                }
                s = fabs(h[n][n-1]) + fabs(h[n-1][n-2]);
                x = y = 0.75 * s;
                w = -0.4375 * s * s;
            }
            
            // MATLAB's new ad hoc shift
            if (iter == 30) {
                s = (y - x) / 2.0;
                s = s * s + w;
                if (s > 0) {
                    s = sqrt(s);
                    if (y < x) {
                        s = -s;
                    }
                    s = x - w / ((y - x) / 2.0 + s);
                    for(int i = low; i <= n; i++) {
                        h[i][i] -= s;
                    }
                    exshift += s;
                    x = y = w = 0.964;
                }
            }
            
            iter = iter + 1;   // (Could check iteration count here.)
            
            // Look for two consecutive small sub-diagonal elements
            int m = n-2;
            while (m >= l) {
                z = h[m][m];
                r = x - z;
                s = y - z;
                p = (r * s - w) / h[m+1][m] + h[m][m+1];
                q = h[m+1][m+1] - z - r - s;
                r = h[m+2][m+1];
                s = fabs(p) + fabs(q) + fabs(r);
                p = p / s;
                q = q / s;
                r = r / s;
                if(m == l){
                    break;
                }
                if(fabs(h[m][m-1]) * (fabs(q) +fabs(r)) <
                    eps * (fabs(p) * (fabs(h[m-1][m-1]) + fabs(z) +
                                          fabs(h[m+1][m+1])))) {
                    break;
                }
                m--;
            }
            
            for(int i = m+2; i <= n; i++) {
                h[i][i-2] = 0.0;
                if (i > m+2) {
                    h[i][i-3] = 0.0;
                }
            }
            
            // Double QR step involving rows l:n and columns m:n
            for(int k = m; k <= n-1; k++) {
                bool notlast = (k != n-1);
                if(k != m) {
                    p = h[k][k-1];
                    q = h[k+1][k-1];
                    r = (notlast ? h[k+2][k-1] : 0.0);
                    x = fabs(p) + fabs(q) + fabs(r);
                    if (x != 0.0) {
                        p = p / x;
                        q = q / x;
                        r = r / x;
                    }
                }
                if(x == 0.0){
                    break;
                }
                s = sqrt(p * p + q * q + r * r);
                if(p < 0){
                    s = -s;
                }
                if(s != 0){
                    if(k != m){
                        h[k][k-1] = -s * x;
                    }else if(l != m){
                        h[k][k-1] = -h[k][k-1];
                    }
                    p = p + s;
                    x = p / s;
                    y = q / s;
                    z = r / s;
                    q = q / p;
                    r = r / p;
                    
                    // Row modification
                    for(int j = k; j < nn; j++) {
                        p = h[k][j] + q * h[k+1][j];
                        if(notlast){
                            p = p + r * h[k+2][j];
                            h[k+2][j] = h[k+2][j] - p * z;
                        }
                        h[k][j] = h[k][j] - p * x;
                        h[k+1][j] = h[k+1][j] - p * y;
                    }
                    
                    // Column modification
                    for (int i = 0; i <= findMin(n,k+3); i++) {
                        p = x * h[i][k] + y * h[i][k+1];
                        if(notlast){
                            p = p + z * h[i][k+2];
                            h[i][k+2] = h[i][k+2] - p * r;
                        }
                        h[i][k] = h[i][k] - p;
                        h[i][k+1] = h[i][k+1] - p * q;
                    }
                    
                    // Accumulate transformations
                    for(int i = low; i <= high; i++) {
                        p = x * eigenvectors[i][k] + y * eigenvectors[i][k+1];
                        if(notlast){
                            p = p + z * eigenvectors[i][k+2];
                            eigenvectors[i][k+2] = eigenvectors[i][k+2] - p * r;
                        }
                        eigenvectors[i][k] = eigenvectors[i][k] - p;
                        eigenvectors[i][k+1] = eigenvectors[i][k+1] - p * q;
                    }
                }  // (s != 0)
            }  // k loop
        }  // check convergence
    }  // while (n >= low)
    
    // Backsubstitute to find vectors of upper triangular form
    if(norm == 0.0){
        return;
    }
    
    for(n = nn-1; n >= 0; n--) {
        p = realEigenvalues[n];
        q = complexEigenvalues[n];
        
        // Real vector
        if (q == 0) {
            int l = n;
            h[n][n] = 1.0;
            for(int i = n-1; i >= 0; i--) {
                w = h[i][i] - p;
                r = 0.0;
                for(int j = l; j <= n; j++) {
                    r = r + h[i][j] * h[j][n];
                }
                if(complexEigenvalues[i] < 0.0) {
                    z = w;
                    s = r;
                } else {
                    l = i;
                    if (complexEigenvalues[i] == 0.0) {
                        if (w != 0.0) {
                            h[i][n] = -r / w;
                        } else {
                            h[i][n] = -r / (eps * norm);
                        }
                        
                        // Solve real equations
                    } else {
                        x = h[i][i+1];
                        y = h[i+1][i];
                        q = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) + complexEigenvalues[i] * complexEigenvalues[i];
                        t = (x * s - z * r) / q;
                        h[i][n] = t;
                        if(fabs(x) > fabs(z)) {
                            h[i+1][n] = (-r - w * t) / x;
                        } else {
                            h[i+1][n] = (-s - y * t) / z;
                        }
                    }
                    
                    // Overflow control
                    t = fabs(h[i][n]);
                    if ((eps * t) * t > 1) {
                        for(int j = i; j <= n; j++) {
                            h[j][n] = h[j][n] / t;
                        }
                    }
                }
            }
            
            // Complex vector
        } else if (q < 0) {
            int l = n-1;
            
            // Last vector component imaginary so matrix is triangular
            if (fabs(h[n][n-1]) > fabs(h[n-1][n])) {
                h[n-1][n-1] = q / h[n][n-1];
                h[n-1][n] = -(h[n][n] - p) / h[n][n-1];
            } else {
                cdiv(0.0,-h[n-1][n],h[n-1][n-1]-p,q);
                h[n-1][n-1] = cdivr;
                h[n-1][n] = cdivi;
            }
            h[n][n-1] = 0.0;
            h[n][n] = 1.0;
            for(int i = n-2; i >= 0; i--) {
                Float ra,sa,vr,vi;
                ra = 0.0;
                sa = 0.0;
                for (int j = l; j <= n; j++) {
                    ra = ra + h[i][j] * h[j][n-1];
                    sa = sa + h[i][j] * h[j][n];
                }
                w = h[i][i] - p;
                
                if(complexEigenvalues[i] < 0.0) {
                    z = w;
                    r = ra;
                    s = sa;
                } else {
                    l = i;
                    if(complexEigenvalues[i] == 0) {
                        cdiv(-ra,-sa,w,q);
                        h[i][n-1] = cdivr;
                        h[i][n] = cdivi;
                    } else {
                        
                        // Solve complex equations
                        x = h[i][i+1];
                        y = h[i+1][i];
                        vr = (realEigenvalues[i] - p) * (realEigenvalues[i] - p) + complexEigenvalues[i] * complexEigenvalues[i] - q * q;
                        vi = (realEigenvalues[i] - p) * 2.0 * q;
                        if((vr == 0.0) & (vi == 0.0)){
                            vr = eps * norm * (fabs(w) + fabs(q) + fabs(x) + fabs(y) + fabs(z));
                        }
                        cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
                        h[i][n-1] = cdivr;
                        h[i][n] = cdivi;
                        if (fabs(x) > (fabs(z) + fabs(q))) {
                            h[i+1][n-1] = (-ra - w * h[i][n-1] + q * h[i][n]) / x;
                            h[i+1][n] = (-sa - w * h[i][n] - q * h[i][n-1]) / x;
                        } else {
                            cdiv(-r-y*h[i][n-1],-s-y*h[i][n],z,q);
                            h[i+1][n-1] = cdivr;
                            h[i+1][n] = cdivi;
                        }
                    }
                    
                    // Overflow control
                    t = findMax(fabs(h[i][n-1]),fabs(h[i][n]));
                    if ((eps * t) * t > 1) {
                        for(int j = i; j <= n; j++) {
                            h[j][n-1] = h[j][n-1] / t;
                            h[j][n] = h[j][n] / t;
                        }
                    }
                }
            }
        }
    }
    
    // Vectors of isolated roots
    for (int i = 0; i < nn; i++) {
        if((i < low) | (i > high)){
            for (int j = i; j < nn; j++) {
                eigenvectors[i][j] = h[i][j];
            }
        }
    }
    
    // Back transformation to get eigenvectors of original matrix
    for (int j = nn-1; j >= low; j--) {
        for (int i = low; i <= high; i++) {
            z = 0.0;
            for (int k = low; k <= findMin(j,high); k++) {
                z = z + eigenvectors[i][k] * h[k][j];
            }
            eigenvectors[i][j] = z;
        }
    }
    
    return;
}
int ChebyshevFilter::zplna()
{
    cmplx r, cnum, cden, cwc, ca, cb, b4ac;
    double C;
    if( kind == 3 )
        C = c;
    else
        C = wc;
    for( i=0; i<ARRSIZ; i++ )
    {
        z[i].r = 0.0;
        z[i].i = 0.0;
    }
    nc = np;
    jt = -1;
    ii = -1;
    for( icnt=0; icnt<2; icnt++ )
    {
        /* The maps from s plane to z plane */
        do
        {
            ir = ii + 1;
            ii = ir + 1;
            r.r = zs[ir];
            r.i = zs[ii];
            switch( type )
            {
            case 1:
            case 3:
                /* Substitute  s - r  =  s/wc - r = (1/wc)(z-1)/(z+1) - r
                 *
                 *     1  1 - r wc (       1 + r wc )
                 * =  --- -------- ( z  -  -------- )
                 *    z+1    wc    (       1 - r wc )
                 *
                 * giving the root in the z plane.
                 */
                cnum.r = 1 + C * r.r;
                cnum.i = C * r.i;
                cden.r = 1 - C * r.r;
                cden.i = -C * r.i;
                jt += 1;
                cdiv( &cden, &cnum, &z[jt] );
                if( r.i != 0.0 )
                {
                    /* fill in complex conjugate root */
                    jt += 1;
                    z[jt].r = z[jt-1 ].r;
                    z[jt].i = -z[jt-1 ].i;
                }
                break;
            case 2:
            case 4:
                /* Substitute  s - r  =>  s/wc - r
                 *
                 *     z^2 - 2 z cgam + 1
                 * =>  ------------------  -  r
                 *         (z^2 + 1) wc
                 *
                 *         1
                 * =  ------------  [ (1 - r wc) z^2  - 2 cgam z  +  1 + r wc ]
                 *    (z^2 + 1) wc
                 *
                 * and solve for the roots in the z plane.
                 */
                if( kind == 2 )
                    cwc.r = cbp;
                else
                    cwc.r = c;
                cwc.i = 0.0;
                cmul( &r, &cwc, &cnum );     /* r wc */
                csub( &cnum, &cone, &ca );   /* a = 1 - r wc */
                cmul( &cnum, &cnum, &b4ac ); /* 1 - (r wc)^2 */
                csub( &b4ac, &cone, &b4ac );
                b4ac.r *= 4.0;               /* 4ac */
                b4ac.i *= 4.0;
                cb.r = -2.0 * cgam;          /* b */
                cb.i = 0.0;
                cmul( &cb, &cb, &cnum );     /* b^2 */
                csub( &b4ac, &cnum, &b4ac ); /* b^2 - 4 ac */
                csqrt( &b4ac, &b4ac );
                cb.r = -cb.r;  /* -b */
                cb.i = -cb.i;
                ca.r *= 2.0; /* 2a */
                ca.i *= 2.0;
                cadd( &b4ac, &cb, &cnum );   /* -b + sqrt( b^2 - 4ac) */
                cdiv( &ca, &cnum, &cnum );   /* ... /2a */
                jt += 1;
                cmov( &cnum, &z[jt] );
                if( cnum.i != 0.0 )
                {
                    jt += 1;
                    z[jt].r = cnum.r;
                    z[jt].i = -cnum.i;
                }
                if( (r.i != 0.0) || (cnum.i == 0) )
                {
                    csub( &b4ac, &cb, &cnum );  /* -b - sqrt( b^2 - 4ac) */
                    cdiv( &ca, &cnum, &cnum );  /* ... /2a */
                    jt += 1;
                    cmov( &cnum, &z[jt] );
                    if( cnum.i != 0.0 )
                    {
                        jt += 1;
                        z[jt].r = cnum.r;
                        z[jt].i = -cnum.i;
                    }
                }
            } /* end switch */
        }
        while( --nc > 0 );

        if( icnt == 0 )
        {
            zord = jt+1;
            if( nz <= 0 )
            {
                if( kind != 3 )
                    return(0);
                else
                    break;
            }
        }
        nc = nz;
    } /* end for() loop */
    return 0;
}
예제 #15
0
void fdmig( complex **cp, int nx, int nw, float *v,float fw,float
	dw,float dz,float dx,float dt,float vc,int dip)
{
	int iw,ix;
	float *p,*s1,*s2,w,coefa,coefb,v1,vn,trick=0.1;
	complex cp2,cp3,cpnm1,cpnm2;
	complex a1,a2,b1,b2;
	complex endl,endr;
	complex *data,*d,*a,*b,*c;

	p=alloc1float(nx);
	s1=alloc1float(nx);
	s2=alloc1float(nx);

	data=alloc1complex(nx);
	d=alloc1complex(nx);
	a=alloc1complex(nx);
	b=alloc1complex(nx);
	c=alloc1complex(nx);

	for(ix=0;ix<nx;ix++){
		p[ix]=vc/v[ix];
		p[ix]=(p[ix]*p[ix]+p[ix]+1.0);
	}

	
	if(dip!=65){
		coefa=0.5;coefb=0.25;
	} else {
		coefa=0.4784689;
		coefb=0.37607656;
	}

	v1=v[0];
	vn=v[nx-1];

	for(iw=0,w=fw;iw<nw;iw++,w+=dw){
		if(fabs(w)<=1.0e-10)w=1.0e-10/dt; 

		for(ix=0;ix<nx;ix++){
			s1[ix]=(v[ix]*v[ix])*p[ix]*coefb/(dx*dx*w*w)+trick;
			s2[ix]=-(1-vc/v[ix])*v[ix]*dz*coefa/(w*dx*dx)*0.5;
		}

		for(ix=0;ix<nx;ix++){
			data[ix]=cp[iw][ix];
		}

		cp2=data[1];
		cp3=data[2];
		cpnm1=data[nx-2];
		cpnm2=data[nx-3];
		a1=crmul(cmul(cp2,conjg(cp3)),2.0);
		b1=cadd(cmul(cp2,conjg(cp2)),cmul(cp3,conjg(cp3)));

		if(b1.r==0.0 && b1.i==0.0)
			a1=cwp_cexp(cmplx(0.0,-w*dx*0.5/v1));
		else
			a1=cdiv(a1,b1);

		if(a1.i>0.0)
			a1=cwp_cexp(cmplx(0.0,-w*dx*0.5/v1));

		a2=crmul(cmul(cpnm1,conjg(cpnm2)),2.0);
		b2=cadd(cmul(cpnm1,conjg(cpnm1)),cmul(cpnm2,conjg(cpnm2)));

		if(b2.r==0.0 && b2.i==0.0)
			a2=cwp_cexp(cmplx(0.0,-w*dx*0.5/vn));
		else
			a2=cdiv(a2,b2);

		if(a2.i>0.0)
			a2=cwp_cexp(cmplx(0.0,-w*dx*0.5/vn));

		for(ix=0;ix<nx;ix++){
			a[ix]=cmplx(s1[ix],s2[ix]);
			b[ix]=cmplx(1.0-2.0*s1[ix],-2.0*s2[ix]);
		}

		for(ix=1;ix<nx-1;ix++){

			d[ix]=cadd(cadd(cmul(data[ix+1],a[ix+1]),
					cmul(data[ix-1],a[ix-1])),
					cmul(data[ix],b[ix]));
		}

		d[0]=cadd(cmul(cadd(b[0],cmul(a[0],a1)),
				data[0]),cmul(data[1],a[1]));

		d[nx-1]=cadd(cmul(cadd(b[nx-1],
			cmul(a[nx-1],a2)),data[nx-1]),
			cmul(data[nx-2],a[nx-2]));

		for(ix=0;ix<nx;ix++){
			data[ix]=cmplx(s1[ix],-s2[ix]);
			b[ix]=cmplx(1.0-2.0*s1[ix],2.0*s2[ix]);
		}
		endl=cadd(b[0],cmul(data[0],a1));
		endr=cadd(b[nx-1],cmul(data[nx-1],a2));

		
		for(ix=1;ix<nx-1;ix++){
			a[ix]=data[ix+1];
			c[ix]=data[ix-1];
		}
		a[0]=data[1];
		c[nx-1]=data[nx-2];
			
		retris(data,a,c,b,endl,endr,nx,d);

		for(ix=0;ix<nx;ix++){
			cp[iw][ix]=data[ix];
		}

	}


	free1complex(data);
	free1float(p);
	free1complex(d);
	free1complex(b);
	free1complex(c);
	free1complex(a);
	free1float(s1);
	free1float(s2);
		
	return;
}
예제 #16
0
파일: elco2.c 프로젝트: aahud/harvey
int
elco2(double x, double y, double kc, double a, double b, double *u, double *v)
{
	double c,d,dn1,dn2,e,e1,e2,f,f1,f2,h,k,m,m1,m2,sy;
	double d1[13],d2[13];
	int i,l;
	if(kc==0||x<0)
		return(0);
	sy = y>0? 1: y==0? 0: -1;
	y = fabs(y);
	csq(x,y,&c,&e2);
	d = kc*kc;
	k = 1-d;
	e1 = 1+c;
	cdiv2(1+d*c,d*e2,e1,e2,&f1,&f2);
	f2 = -k*x*y*2/f2;
	csqr(f1,f2,&dn1,&dn2);
	if(f1<0) {
		f1 = dn1;
		dn1 = -dn2;
		dn2 = -f1;
	}
	if(k<0) {
		dn1 = fabs(dn1);
		dn2 = fabs(dn2);
	}
	c = 1+dn1;
	cmul(e1,e2,c,dn2,&f1,&f2);
	cdiv(x,y,f1,f2,&d1[0],&d2[0]);
	h = a-b;
	d = f = m = 1;
	kc = fabs(kc);
	e = a;
	a += b;
	l = 4;
	for(i=1;;i++) {
		m1 = (kc+m)/2;
		m2 = m1*m1;
		k *= f/(m2*4);
		b += e*kc;
		e = a;
		cdiv2(kc+m*dn1,m*dn2,c,dn2,&f1,&f2);
		csqr(f1/m1,k*dn2*2/f2,&dn1,&dn2);
		cmul(dn1,dn2,x,y,&f1,&f2);
		x = fabs(f1);
		y = fabs(f2);
		a += b/m1;
		l *= 2;
		c = 1 +dn1;
		d *= k/2;
		cmul(x,y,x,y,&e1,&e2);
		k *= k;

		cmul(c,dn2,1+e1*m2,e2*m2,&f1,&f2);
		cdiv(d*x,d*y,f1,f2,&d1[i],&d2[i]);
		if(k<=CC) 
			break;
		kc = sqrt(m*kc);
		f = m2;
		m = m1;
	}
	f1 = f2 = 0;
	for(;i>=0;i--) {
		f1 += d1[i];
		f2 += d2[i];
	}
	x *= m1;
	y *= m1;
	cdiv2(1-y,x,1+y,-x,&e1,&e2);
	e2 = x*2/e2;
	d = a/(m1*l);
	*u = atan2(e2,e1);
	if(*u<0)
		*u += PI;
	a = d*sy/2;
	*u = d*(*u) + f1*h;
	*v = (-1-log(e1*e1+e2*e2))*a + f2*h*sy + a;
	return(1);
}
예제 #17
0
// BANDSTOP
pzkContainer * t2bs(pzkContainer * pzk, real w0, real dw) {
	uint nop, noz, i;
	pzkContainer * f;
	const real w02 = w0*w0;
	complex tmp, beta, gamma, cw0, cdwp2;

	cw0.re = w0;
	cw0.im = 0;

	cdwp2.re = dw / 2;
	cdwp2.im = 0;
	
	noz = 2*pzk->nextZero;
	nop = 2*pzk->nextPole;
	
	if( pzk->no_wz > 0 ) {
		noz += pzk->no_wz;
	}
	if( pzk->no_wz < 0 ) {
		nop -= pzk->no_wz;
	}
	
	f = createPzkContainer(nop, noz);
	
	f->wz = w0;
	f->no_wz = -pzk->no_wz;
	f->amp = pzk->amp * pow(dw, (real)(pzk->no_wz));
		
	gamma.re = 0;
	gamma.im = 0;
	if( pzk->no_wz > 0 ) {
		for( i = 0; i < pzk->no_wz; i++ ) {
			addZero(f, gamma);
		}
	}
	if( pzk->no_wz < 0 ) {
		for( i = 0; i < -pzk->no_wz; i++ ) {
			addPole(f, gamma);
		}
	}

	for( i = 0; i < pzk->nextPole; i++ ) {
		if( cisreal(pzk->poles[i]) ) {
			beta.re = cdwp2.re / pzk->poles[i].re;
			tmp.re = 1 - ( w02/(beta.re*beta.re) );

			if( tmp.re >= 0 ) {
				tmp.re = sqrt( tmp.re );
				gamma.im = 0;
				gamma.re = beta.re * (1 + tmp.re);
				addPole(f, gamma);
				gamma.re = beta.re * (1 - tmp.re);
				addPole(f, gamma);
			} else {
				tmp.im = sqrt( -tmp.re );
				tmp.re = 1;
				gamma = cmul2( beta.re, tmp );
				addPole(f, gamma);
			}

			f->amp /= -pzk->poles[i].re;
			f->no_wz++;
		}
		else {
			beta = cdiv(cdwp2, pzk->poles[i]);	
			tmp = cdiv(cw0, beta);
			tmp = csqrt( csub2(1, cmlt(tmp, tmp)) );

			gamma = cmlt(beta, cadd2(1, tmp));
			addPole(f, gamma);
			gamma = cmlt(beta, csub2(1, tmp));
			addPole(f, gamma);

			f->amp /= cabs2(pzk->poles[i]);
			f->no_wz += 2;
		}
	}
	
	for( i = 0; i < pzk->nextZero; i++ ) {
		if( cisreal(pzk->zeros[i]) ) {
			beta.re = cdwp2.re / pzk->zeros[i].re;
			tmp.re = 1 - ( w02/(beta.re*beta.re) );

			if( tmp.re >= 0 ) {
				tmp.re = sqrt( tmp.re );
				gamma.im = 0;
				gamma.re = beta.re * (1 + tmp.re);
				addZero(f, gamma);
				gamma.re = beta.re * (1 - tmp.re);
				addZero(f, gamma);
			} else {
				tmp.im = sqrt( -tmp.re );
				tmp.re = 1;
				gamma = cmul2( beta.re, tmp );
				addZero(f, gamma);
			}

			f->amp *= -pzk->zeros[i].re;
			f->no_wz--;
		}
		else {
			beta = cdiv(cdwp2, pzk->zeros[i]);	
			tmp = cdiv(cw0, beta);
			tmp = csqrt( csub2(1, cmlt(tmp, tmp)) );

			gamma = cmlt(beta, cadd2(1, tmp));
			addZero(f, gamma);
			gamma = cmlt(beta, csub2(1, tmp));
			addZero(f, gamma);

			f->amp *= cabs2(pzk->zeros[i]);
			f->no_wz -= 2;
		}
	}
	
	return f;	
}
예제 #18
0
void do_minphdec(float *tr,int nt, float *filter,int fnl,int fnr,float prw)
{

	float *rtr;
	float *rtx;     
	complex *f;
	complex *w;
	complex a;
	int iamp;
	float amp;
	float ampm=-1.0e+20;
	float amps;
	float *am;
	float *ph;	
	float mean=0.0;
	float sum=0.0;

	int nfftc; 
        int nf;    
	int i,j;			/* counter */
	float snfftc;
	

	/* Set up pfa fft */
	nfftc = npfao(nt,LOOKFAC*nt); 
        if (nfftc >= SU_NFLTS || nfftc >= PFA_MAX)
                 err("Padded nt=%d--too big", nfftc);
        nf = nfftc/2 + 1;
	snfftc=1.0/nfftc;

        rtr = ealloc1float(nfftc);
        rtx = ealloc1float(nf);
	f = ealloc1complex(nfftc);
	w = ealloc1complex(nfftc);
	am = ealloc1float(nf);
	ph = ealloc1float(nf);
        
	/* clean the arrays */
	memset( (void *) w, (int) '\0', nfftc*sizeof(complex));
        memset( (void *) rtr, (int) '\0', nfftc*FSIZE);
	
	/* Cross correlation */
	xcor(nt,0,tr,nt,0,tr,nf,0,rtr);

        /* FFT */
	pfarc(1, nfftc,rtr,w);

	/* stabilize */
	for(i=0;i<nf;i++) {
		am[i] += am[i]*prw;
	}
	
	/* Normalize */
	for(i=0;i<nf;i++) {
		a=w[i];
		am[i]= sqrt(a.r*a.r+a.i*a.i);
		sum += am[i];
		if(am[i]!=0) ph[i] = atan2(a.i,a.r);
		else ph[i]=0;
	}
	sum *=	1.0/nf;
	sum = 1.0/sum;
	sscal(nf,sum,am,1);
	
	/* Smooth the apmlitude spectra  */
	if(fnl!=0) conv (fnl+fnr+1,-fnl,filter,nf,0,am,nf,0,am);

	fprintf(stderr," %f\n",sum);	
	
	for(i=0;i<nf;i++) {
		w[i].r = am[i]*cos(ph[i]);
		w[i].i = am[i]*sin(ph[i]);
	}
	for(i=nf,j=nf-1;i<nfftc;i++,j--) {
		w[i].r = am[j]*cos(ph[j]);
		w[i].i = am[j]*sin(ph[j]);
	}
		
	/* log spectra */
	for (i = 0; i < nfftc; ++i)  w[i] =
		crmul(clog(cmul(w[i],conjg(w[i]))),0.5);

	/* Hilbert transform */
	pfacc(-1,nfftc,w);
        for (i=0; i<nfftc; ++i) {
		w[i].r *=snfftc;
		w[i].i *=snfftc;
	}
	for(i=1;i<nfftc/2;i++) w[i] = cadd(w[i],w[i]);
	for(i=nfftc/2;i<nfftc;i++) w[i] = cmplx(0,0);
	pfacc(1,nfftc,w);
	/* end of Hilbert transform */
	
	/* exponentiate */
	for(i=0;i<nfftc;i++) w[i] = cexp(w[i]);
	
	/* inverse filter */
	for(i=0;i<nfftc;i++) f[i] = cdiv(cmplx(1.0,0),w[i]);
	
	/* Load trace into tr (zero-padded) */
        memset( (void *) w, (int) '\0',nfftc*sizeof(complex));
	for(i=0;i<nt;i++) w[i].r = tr[i];

	/* Trace to frequency domain */
	pfacc(1,nfftc,w);
      
      	/* apply filter */
        for(i=0;i<nfftc;i++) w[i] = cmul(w[i],f[i]);
             
        /* Time domain */
        pfacr(-1, nfftc,w,rtr);
	for(i=0;i<nt;i++) rtr[i] *=snfftc;
	
	memcpy( (void *) tr, (const void *) rtr, nt*FSIZE);				
	
	free1float(rtr);
	free1float(am);
	free1float(ph);
	free1complex(f);
	free1complex(w);
}	
예제 #19
0
/************************PSPI migration************************/
void pspimig(float **data,complex **image,float **v,int nt,int nx,int nz,float dt,float dx, float dz)
{
int ntfft;                              /*number of samples of the zero padded trace*/
int nxfft;
int nw;                                 /*number of temporal freqs.*/
int it;                                 /*loop index over time sample*/
int ix;                                 /*loop index over midpoint sample*/     
int iw;                                 /*loop index over frequency*/                 
int ik;                                 /*loop index over wavenumber*/
int iz;                                /*loop index over migrated depth samples*/
int iv;                                /*loop index over reference velocities*/
int nvref_max=8;                      /*number of reference velocities in each layer*/
int nvref;
int i1;                               /*nearest reference velocity*/
int i2;
int iw1;
int iw2;


float **vref;                           /*2D reference velocity array*/
float w0;                               /*first frequency sample*/
float w;                                /*frequency*/
float dw;                               /*frequency sampling interval*/                 
float k0;                               /*first wavenumber*/
float k;
float dk;                             /*wave number sampling interval in x*/
float dv;                              /*velocity interval*/
float *in;                             /*input 1D data in FFTW*/
float **cpdata;
float phase;
float wv;
float vmin;
float vmax;
float f1 = 1.0;
float f2 = 35.0;

complex *out;                           /*output of 1D FFT using FFTW*/
complex **datawx;                       /*data in frequency-wavenumber domain*/
complex *in2;
complex *out2;
complex *in3;
complex *out3;
complex **Pkv;                           /*wavefield in k-v*/
complex **Pxv;                           /*wavefield in x-v*/
complex **Pwx;                           /*wavefield in w-x*/

complex cshift;
complex tmp_a;
complex tmp_b;

fftwf_plan p1; 
fftwf_plan p2;
fftwf_plan p3;

/*allocate memory of reference velocities*/
vref = alloc2float(nz,nvref_max);     /*allocate 2D array for reference velocity to avoid changing memory of vector*/
                                      /*nz by nvref_max*/
for (ix=0;ix<nx;ix++){
for (iz=0;iz<nz;iz++){
image[ix][iz] = cmplx(0.0,0.0);       /*nz by nz*/
}
}


/*devide velocity by 2 for downward continuation*/
for (iz=0;iz<nz;iz++){
for (ix=0;ix<nx;ix++){
v[ix][iz]=v[ix][iz]/2.0;
}
}
 /*fprintf(stderr,"nx=%d nz=%d",nx,nz);
 FILE *Fvp = fopen("vel.bin", "wb");
 fwrite(v[0],1,4*nx*nz,Fvp);
 fclose(Fvp);*/


/*zero padding in termporal direction*/
ntfft = 1.0*exp2(ceil(log2(nt)));        /*number of zero padded trace in FFT*/
nw = ntfft/2+1;                          /*number of points of frequency axis after FFTW*/
cpdata = alloc2float(ntfft,nx);          /*data after zero padding*/  

for (ix=0;ix<nx;ix++){
 for (it=0;it<ntfft;it++){
   if(it<=nt) cpdata[ix][it] = data[ix][it];
   else {cpdata[ix][it] = 0.0;
         }
 		          }
	             }


/*allocate memory for w-x domain data*/
datawx = alloc2complex(nw,nx);           /*w-x data nx by nw*/
iw1 = floor(f1*dt*ntfft)+1;
iw2 = floor(f2*dt*ntfft)+1;

/*define plans for FFT using FFTW*/
/*plan 1 from t-x to w-x*/
in = alloc1float(ntfft);
out = alloc1complex(nw);
p1 = fftwf_plan_dft_r2c_1d(ntfft,in,(fftwf_complex*)out,FFTW_ESTIMATE);      /*real to complex*/

/*plan 2 from w-x to w-k*/
nxfft = 1.0*exp2(ceil(log2(nx)));
in2 =  alloc1complex(nxfft);
out2 = alloc1complex(nxfft);
p2 = fftwf_plan_dft_1d(nxfft,(fftwf_complex*)in2,(fftwf_complex*)out2,FFTW_FORWARD,FFTW_ESTIMATE);


/*plan 3 from w-k to w-x*/
in3 =  alloc1complex(nxfft);
out3 = alloc1complex(nxfft);
p3 = fftwf_plan_dft_1d(nxfft,(fftwf_complex*)in3,(fftwf_complex*)out3,FFTW_BACKWARD,FFTW_ESTIMATE);

Pxv = alloc2complex(nvref_max,nxfft);

Pkv = alloc2complex(nvref_max,nxfft);

Pwx = alloc2complex(nw,nxfft); 

/*apply first 1-D Fourier transform on data from t-x to w-x using FFTW package*/
for (ix=0;ix<nx;ix++){
for(it=0;it<ntfft;it++){
in[it] = cpdata[ix][it];                    /*assign one trace to a vector*/
}
fftwf_execute(p1);

for(iw=0;iw<nw;iw++){
datawx[ix][iw] = cdiv(out[iw], cmplx(sqrt(ntfft), 0.0));
}            /*w*/

}            /*x*/

fftwf_destroy_plan(p1);


/*determine frequency and wavenumber axis*/
dw = 2.0*PI/(ntfft*dt);                    /*frequency sampling interval*/
w0 = 0.0;                                  /*first frequency sample*/

dk = 2.0*PI/(nxfft*dx);                   /*wavenumber sampling interval*/
k0 = 0.0;                                 /*first wavenumber sample*/



/*initialization of downward wavefield*/
for (iw=0;iw<nw;iw++){
for (ix=0;ix<nxfft;ix++){
if (ix<nx){Pwx[ix][iw] =  datawx[ix][iw];}     
else{Pwx[ix][iw] = cmplx(0.0,0.0);}
}
}

/*loop over depth z*/
for (iz=0;iz<nz;iz++){                
fprintf(stderr,"depth sample %d\n",iz);

/*calculate reference velocities of each layer*/
vmin = v[0][iz];
vmax = v[0][iz]; 
for (ix=0;ix<nx;ix++){
if(v[ix][iz]>=vmax) vmax=v[ix][iz];       /*get the maximum velocity*/
if(v[ix][iz]<=vmin) vmin=v[ix][iz];       /*get the minimum velocity*/
}                  

dv = (vmax-vmin)/(nvref_max-1);

if(dv/vmax<=0.001){
nvref = 1;
vref[0][iz]=(vmin+vmax)/2;
}
else
{
nvref = nvref_max;
for (iv=0;iv<nvref_max;iv++)
{
vref[iv][iz] = vmin+dv*iv;
}
}


/*loop over frequencies*/
w = w0;
for (iw=iw1;iw<=iw2;iw++){
w = w0 + iw*dw;                               /*frequency axis (important)*/

/*apply phase-shift in w-x (optional)*/

/*datawx*/

/*Apply second FFT to tranform w-x data to w-k domain using FFTW*/
for (ix=0;ix<nxfft;ix++){
in2[ix] = Pwx[ix][iw];
}

fftwf_execute(p2);
for (ik=0;ik<nxfft;ik++){
out2[ik] = cdiv(out2[ik], cmplx(sqrt(nxfft), 0.0));
}

/*loop over wavenumbers*/
k = k0;
for (ik=0;ik<nxfft;ik++){

if (ik<=nxfft/2){
k = ik*dk;                           /*wavenumber axis (important)*/
}
else{
k = (ik-nxfft)*dk;
}
 
/*loop over reference velocities*/
for (iv=0;iv<nvref;iv++){
wv = w/vref[iv][iz];
if(wv>fabs(k)){                     /*note that k can be negative*/
phase = sqrt(wv*wv-k*k)*dz;
cshift = cmplx(cos(phase),sin(phase));
}
else{
cshift = cmplx(0.0,0.0);
}
Pkv[ik][iv] = cmul(out2[ik],cshift); 
}                               /*end for v*/

}                               /*end for k*/

   
/*from w-k go back to w-x domain*/
for (iv=0;iv<nvref;iv++){  /*inverse FFT for each velocity*/

for (ik=0;ik<nxfft;ik++){
in3[ik] = Pkv[ik][iv];
}    /*end for k*/

fftwf_execute(p3);


for (ix=0;ix<nxfft;ix++){
Pxv[ix][iv] = cdiv(out3[ix], cmplx(sqrt(nxfft), 0.0));
}    /*end for x*/

}    /*end for v*/     /*Pxv ix by iv*/


/*interpolation of wavefield in w-x*/
if (nvref==1){
for (ix=0;ix<nx;ix++){
Pwx[ix][iw] = Pxv[ix][0];
}
}
else
{
for (ix=0;ix<nx;ix++){ 
if (v[ix][iz]==vmax){i1=(v[ix][iz]-vmin)/dv-1;}
else
{i1 = (v[ix][iz]-vmin)/dv;}    /*find nearest reference velocity and wavefield*/
i2 = i1+1;
tmp_a = cadd(crmul(Pxv[ix][i1], vref[i2][iz]-v[ix][iz]) , crmul(Pxv[ix][i2], v[ix][iz]-vref[i1][iz]));
tmp_b = cmplx(vref[i2][iz]-vref[i1][iz], 0.0);
Pwx[ix][iw] = cdiv(tmp_a,tmp_b);
}          /*interpolate wavefield*/
}          /*end else*/

/*imaging condition*/
for (ix=0;ix<nx;ix++){
image[ix][iz] = cadd(image[ix][iz],Pwx[ix][iw]);
}

/*zero padding*/
for (ix=nx;ix<nxfft;ix++){
Pwx[ix][iw] = cmplx(0.0,0.0);
}

}       /*w*/
}       /*z*/

fftwf_destroy_plan(p2);
fftwf_destroy_plan(p3);

}   /*end pspimig migration function*/
예제 #20
0
void fdmig( complex **cp, int nx, int nw, float *v,float fw,float
	dw,float dz,float dx,float dt,int dip)
{
	int iw,ix,step=1;
	float *s1,*s2,w,coefa[5],coefb[5],v1,vn,trick=0.1;
	complex cp2,cp3,cpnm1,cpnm2;
	complex a1,a2,b1,b2;
	complex endl,endr;
	complex *data,*d,*a,*b,*c;

	s1=alloc1float(nx);
	s2=alloc1float(nx);

	data=alloc1complex(nx);
	d=alloc1complex(nx);
	a=alloc1complex(nx);
	b=alloc1complex(nx);
	c=alloc1complex(nx);

	if(dip==45){
	coefa[0]=0.5;coefb[0]=0.25; 
	step=1;
	}
	
	if(dip==65){
	coefa[0]=0.478242060;coefb[0]=0.376369527;
	step=1;
	}
	
	if(dip==79){
	coefa[0]=coefb[0]=0.4575;
	step=1;
	}

	if(dip==80){
	coefa[1]=0.040315157;coefb[1]=0.873981642;
	coefa[0]=0.457289566;coefb[0]=0.222691983;
	step=2;
	}
	
	if(dip==87){
	coefa[2]=0.00421042;coefb[2]=0.972926132;
	coefa[1]=0.081312882;coefb[1]=0.744418059;
	coefa[0]=0.414236605;coefb[0]=0.150843924;
	step=3;
	}
	 
	if(dip==89){
	coefa[3]=0.000523275;coefb[3]=0.994065088;
	coefa[2]=0.014853510;coefb[2]=0.919432661;
	coefa[1]=0.117592008;coefb[1]=0.614520676;
	coefa[0]=0.367013245;coefb[0]=0.105756624;
	step=4;
	}

	if(dip==90){
	coefa[4]=0.000153427;coefb[4]=0.997370236;
	coefa[3]=0.004172967;coefb[3]=0.964827992;
	coefa[2]=0.033860918;coefb[2]=0.824918565;
	coefa[1]=0.143798076;coefb[1]=0.483340757;
	coefa[0]=0.318013812;coefb[0]=0.073588213;
	step=5;
	}

	v1=v[0];vn=v[nx-1];

	 
	do {
step--;

	for(iw=0,w=fw;iw<nw;iw++,w+=dw){

		if(fabs(w)<=1.0e-10)w=1.0e-10/dt; 

		for(ix=0;ix<nx;ix++){
			s1[ix]=(v[ix]*v[ix])*coefb[step]/(dx*dx*w*w)+trick;
			s2[ix]=-v[ix]*dz*coefa[step]/(w*dx*dx)*0.5;
		}

		for(ix=0;ix<nx;ix++){
			data[ix]=cp[iw][ix];
		}

		cp2=data[1];
		cp3=data[2];
		cpnm1=data[nx-2];
		cpnm2=data[nx-3];
		a1=crmul(cmul(cp2,conjg(cp3)),2.0);
		b1=cadd(cmul(cp2,conjg(cp2)),cmul(cp3,conjg(cp3)));

		if(b1.r==0.0 && b1.i==0.0)
			a1=cwp_cexp(cmplx(0.0,-w*dx*0.5/v1));
		else
			a1=cdiv(a1,b1);

		if(a1.i>0.0)a1=cwp_cexp(cmplx(0.0,-w*dx*0.5/v1));

		a2=crmul(cmul(cpnm1,conjg(cpnm2)),2.0);
		b2=cadd(cmul(cpnm1,conjg(cpnm1)),cmul(cpnm2,conjg(cpnm2)));

		if(b2.r==0.0 && b2.i==0.0)
			a2=cwp_cexp(cmplx(0.0,-w*dx*0.5/vn));
		else
			a2=cdiv(a2,b2);

		if(a2.i>0.0)a2=cwp_cexp(cmplx(0.0,-w*dx*0.5/vn));


		for(ix=0;ix<nx;ix++){
			a[ix]=cmplx(s1[ix],s2[ix]);
			b[ix]=cmplx(1.0-2.0*s1[ix],-2.0*s2[ix]);
		}

		for(ix=1;ix<nx-1;ix++){

		d[ix]=cadd(cadd(cmul(data[ix+1],a[ix+1]),cmul(data[ix-1],a[ix-1])),
		cmul(data[ix],b[ix]));
		}

		d[0]=cadd(cmul(cadd(b[0],cmul(a[0],a1)),data[0]),cmul(data[1],a[1]));

		d[nx-1]=cadd(cmul(cadd(b[nx-1],cmul(a[nx-1],a2)),data[nx-1]),
		cmul(data[nx-2],a[nx-2]));

		for(ix=0;ix<nx;ix++){
			data[ix]=cmplx(s1[ix],-s2[ix]);
			b[ix]=cmplx(1.0-2.0*s1[ix],2.0*s2[ix]);
		}
		endl=cadd(b[0],cmul(data[0],a1));
		endr=cadd(b[nx-1],cmul(data[nx-1],a2));

		
		for(ix=1;ix<nx-1;ix++){
			a[ix]=data[ix+1];
			c[ix]=data[ix-1];
		}
		a[0]=data[1];
		c[nx-1]=data[nx-2];
			
		retris(data,a,c,b,endl,endr,nx,d);

		for(ix=0;ix<nx;ix++){
			cp[iw][ix]=data[ix];
		}

	}

	}while(step);

	free1complex(data);
	free1complex(d);
	free1complex(b);
	free1complex(c);
	free1complex(a);
	free1float(s1);
	free1float(s2);
		
	return;
}
예제 #21
0
파일: linear.c 프로젝트: Ntools/fft-lib-0.1
void cgauj(Complex a[], int l, int m, int n, double eps)
{
	int c, i, iw, j, k, mm1, *p, r, *work;
	double api, w, wmax;
	Complex pivot, *q, *q1, wk, wk1;

	if(l < n || m < 2 || m >= n || eps <= 0.)
	{
		fprintf(stderr, "Error : Illegal parameter in cgauj()\n");
		return;
	}
	work = (int *)malloc(m * sizeof(int));
	if(work == NULL)
	{
		fprintf(stderr, "Error : Out of memory  in cgauj()\n");
		return;
	}

	for(i = 0, p = work; i < m; i++)	*p++ = i;
	for(k = 0; k < m; k++)
	{
		wmax = 0.;
		for(i = k; i < m; i++)
		{
			for(j = k, q = a + i * l + k; j < m; j++)
			{
				w = cabslt(*q++);
				if(w > wmax)
				{
					wmax = w;
					r = i;
					c = j;
				}
			}
		}
		pivot = *(a + r * l + c);
		api = cabslt(pivot);
		if(api < eps)
		{
			fprintf(stderr, "Error : api < eps  in cgauj()\n");
			free((char *)work);
			return;
		}
		if(c != k)
		{
			iw = *(work + k);
			*(work + k) = *(work + c);
			*(work + c) = iw;
			for(i = 0, q = a + i * l; i < m; i++, q += l)
			{
				wk = *(q + k);
				*(q + k) = *(q + c);
				*(q + c) = wk;
			}
		}
		if(r != k)
		{
			for(j = k; j < n; j++)
			{
				wk = *(a + r * l + j);
				*(a + r * l + j) = *(a + k * l + j);
				*(a + k * l + j) = wk;
			}
		}

		*(a + k * l + k) = tocomplex(1., 0.);
		for(i = k + 1, q = a + k * l + k + 1; i < n; i++, q++)
			*q = cdiv(*q, pivot);
		for(i = 0; i < m; i++)
		{
			if(i != k)
			{
				wk = *(a + i * l + k);
				for(j = k; j < n; j++)
				{
					wk1 = cmul(wk, *(a + k * l + j));
					*(a + i * l + j) = csub(*(a + i * l + j), wk1);
				}
			}
		}
	}
	mm1 = m - 1;
	for(i = 0; i < mm1; i++)
	{
		for(;;)
		{
			k = *(work + i);
			if(k == i)	break;
			iw = *(work + k);
			*(work + k) = *(work + i);
			*(work + i) = iw;
			for(j = m, q = a + k * l + m, q1 = a + i * l + m; j < n; j++)
			{
				wk = *q;
				*q++ = *q1;
				*q1++ = wk;
			}
		}
	}
	free((char *)work);
	return;
}
예제 #22
0
void do_four(const char *fn, const char *cn, int nx, real x[], real dy[],
             real eps0, real epsRF, const output_env_t oenv)
{
    FILE      *fp, *cp;
    t_complex *tmp, gw, hw, kw;
    int        i, nnx, nxsav;
    real       fac, nu, dt, *ptr, maxeps, numax;

    nxsav = nx;
    /*while ((dy[nx-1] == 0.0) && (nx > 0))
       nx--;*/
    if (nx == 0)
    {
        gmx_fatal(FARGS, "Empty dataset in %s, line %d!", __FILE__, __LINE__);
    }

    nnx = 1;
    while (nnx < 2*nx)
    {
        nnx *= 2;
    }
    snew(tmp, 2*nnx);
    printf("Doing FFT of %d points\n", nnx);
    for (i = 0; (i < nx); i++)
    {
        tmp[i].re = dy[i];
    }
    ptr = &tmp[0].re;
    four1(ptr-1, nnx, -1);

    dt = x[1]-x[0];
    if (epsRF == 0)
    {
        fac = (eps0-1)/tmp[0].re;
    }
    else
    {
        fac = ((eps0-1)/(2*epsRF+eps0))/tmp[0].re;
    }
    fp     = xvgropen(fn, "Epsilon(\\8w\\4)", "Freq. (GHz)", "eps", oenv);
    cp     = xvgropen(cn, "Cole-Cole plot", "Eps'", "Eps''", oenv);
    maxeps = 0;
    numax  = 0;
    for (i = 0; (i < nxsav); i++)
    {
        if (epsRF == 0)
        {
            kw.re = 1+fac*tmp[i].re;
            kw.im = 1+fac*tmp[i].im;
        }
        else
        {
            gw     = rcmul(fac, tmp[i]);
            hw     = rcmul(2*epsRF, gw);
            hw.re += 1.0;
            gw.re  = 1.0 - gw.re;
            gw.im  = -gw.im;
            kw     = cdiv(hw, gw);
        }
        kw.im *= -1;

        nu     = (i+1)*1000.0/(nnx*dt);
        if (kw.im > maxeps)
        {
            maxeps = kw.im;
            numax  = nu;
        }

        fprintf(fp, "%10.5e  %10.5e  %10.5e\n", nu, kw.re, kw.im);
        fprintf(cp, "%10.5e  %10.5e\n", kw.re, kw.im);
    }
    printf("MAXEPS = %10.5e at frequency %10.5e GHz (tauD = %8.1f ps)\n",
           maxeps, numax, 1000/(2*M_PI*numax));
    ffclose(fp);
    ffclose(cp);
    sfree(tmp);
}
예제 #23
0
int main(int argc, char *argv[]){

    int x, y;
    char operator;
    int result;
    int is_valid;

    // keep looping until exit
    while(TRUE){

        is_valid = TRUE;

        int n = scanf("%d %c %d", &x, &operator, &y);
        
        // stdin should provide 3 arguments
        if(n!=3){
            printf("Valid input: number operator number, e.g. 3 + 4 \n");
            return 0;
        }else{

           /* consume the rest of characters in stdin buffer
            in case of the input like 12 + 3a
            causes unexpected behavior for the next round*/

            while(getchar() != '\n');
        }

        switch (operator){
            case '+':
                result = add(x,y);
                break;
            case '-':
                result = sub(x,y);
                break;
            case '*':
                result = mul(x,y);
                break;
            case '/':
                if(y == 0){
                    is_valid = FALSE;
                    printf("The divisor cannot be 0.\n");
                }
                else
                    result = cdiv(x,y);
                break;
            case '%':
                if(y == 0){
                    is_valid = FALSE;
                    printf("The divisor cannot be 0.\n");
                }
                else
                    result = mod(x,y);
                break;
            default:
                is_valid = FALSE;
                printf("Valid operators: +, -, *, /, %% \n");
                break;
        }

        if(is_valid)
            printf("%d\n", result);
        else
            return 0;
    }

    return 0;
}