home *** CD-ROM | disk | FTP | other *** search
- # include <math.h>
- # include <stdio.h>
- # include "complex.h"
- # include <stdlib.h>
- # include "miscio.h"
-
- # define nearzero 1.0E-20
-
- float ComplexMag(struct complext *CNum1)
- {
- float _fret;
-
- _fret = sqrt( (*CNum1).x * (*CNum1).x +
- (*CNum1).y * (*CNum1).y );
- return(_fret);
- }
-
-
- void CMath(struct complext c1,char op,
- struct complext c2,struct complext *result)
- {
- struct complext temp1;
- struct complext temp2;
- float tempr;
-
- switch ( op ) {
- case '+':
- {
-
- (*result).x = c1.x + c2.x;
- (*result).y = c1.y + c2.y;
-
- }
- break;
- case '-':
- {
- (*result).x = c1.x - c2.x;
- (*result).y = c1.y - c2.y;
- }
- break;
- case '*':
- {
- (*result).x = c1.x * c2.x - c1.y * c2.y;
- (*result).y = c1.x * c2.y + c1.y * c2.x;
- }
- break;
- case '/':
- {
- (*result).x = (c1.x + c2.x + c1.y * c2.y) / ((c2.x * c2.x) + (c2.y * c2.y));
- (*result).y = (c1.y * c2.x - c1.x * c2.y) / ((c2.x * c2.x) + (c2.y * c2.y));
- }
- break;
- case 'i':
- {
- tempr = ComplexMag(&c1);
- (*result).y = -(c1.y / tempr);
- (*result).x = c1.x / tempr;
- }
- break;
- }
- }
-
- void MatPrint(float *m1,int m,int n,char *matname)
- {
- int i;
- int j;
-
- printf("%s\n", matname );
- printf("\n");
- for ( i = 0; i <= m-1; ++i ) {
- for ( j = 0; j <= n-1; ++j ) {
- printf("%10.3f ", m1[i*n+j] );
- }
- printf("\n");
- }
- printf("\n");
- }
-
-
- void MatProd(float *m1,float *m2,int l,int m,
- int n, float *m3)
- {
- int i;
- int j;
- int k;
-
- for ( i = 0; i <= l-1; ++i ) {
- for ( j = 0; j <= n-1; ++j ) {
- m3[i*n+j] = 0;
- for ( k = 0; k <= m-1; ++k ) {
- m3[i*n+j] = m3[i*n+j] + m1[i*m+k] * m2[k*n+j];
- }
- }
- }
- }
-
- void MatScalarProd(float *m1, float sval,int numrow,
- int numcol, float *m2)
- {
- int i;
- int j;
-
- for ( i = 0; i <= numrow-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- m2[i*numcol+j] = sval * m1[i*numcol+j];
- }
- }
- }
-
- void MatAdd(float *m1, float *m2,int numrow,
- int numcol,float *m3)
- {
- int i;
- int j;
-
- for ( i = 0; i <= numrow-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- m3[i*numcol+j] = m1[i*numcol+j] + m2[i*numcol+j];
- }
- }
- }
-
- void MatTranspose(float *m1,int numrow,int numcol,float *m2)
- {
- int i;
- int j;
- float temp;
-
- for ( i = 0; i <= numrow-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- m2[j*numrow+i] = m1[i*numcol+j];
- }
- }
- }
-
- float MatDeter(float *m1, int numrow)
- {
- float _fret;
- int i;
- int j;
- int k;
- int lx;
- int f;
- int nxt;
- float pivot;
- float rac;
- float bignum;
- float temp1;
- float temp2;
- float eval;
-
- f = 1;
- for ( i = 0; i <= numrow-1; ++i ) {
- bignum = 0.0;
- for ( k = i; k <= numrow-1; ++k ) {
- eval = fabs(m1[k*numrow+i]);
- if ( eval - bignum > 0 ) {
- bignum = eval;
- lx = k;
- }
- }
- if ( i - lx != 0 ) {
- f = -f;
- }
- for ( j = 0; j <= numrow-1; ++j ) {
- temp1 = m1[i*numrow+j];
- m1[i*numrow+j] = m1[lx*numrow+j];
- m1[lx*numrow+j] = temp1;
- }
- pivot = m1[i*numrow+i];
- nxt = i + 1;
- for ( j = nxt; j <= numrow-1; ++j ) {
- rac = m1[j*numrow+i] / pivot;
- for ( k = i; k <= numrow-1; ++k ) {
- m1[j*numrow+k] = m1[j*numrow+k] - rac * m1[i*numrow+k];
- }
- }
- }
- temp2 = 1;
- for ( i = 0; i <= numrow-1; ++i ) {
- temp2 = temp2 * m1[i*numrow+i];
- }
- _fret = temp2 * f;
- return(_fret);
- }
-
- void matswap(float *s1,float *s2)
- {
- float temp;
-
- temp = (*s1);
- (*s1) = (*s2);
- (*s2) = temp;
- }
-
- void MatInvert(float *matdata, int numcol,float *det,
- float *invary)
- {
- int *pivlst;
- char *pivchk;
- int i;
- int j;
- int k;
- int l;
- int lerow;
- int lecol;
- int l1;
- float piv;
- float t;
- float leval;
-
- pivlst = (int *) calloc(50*2,2);
- pivchk = (char *) calloc(50,1);
- (*det) = 1;
- for ( i = 0; i <= numcol-1; ++i ) {
- pivchk[i] = 0;
- for ( j = 0; j <= numcol-1; ++j ) {
- invary[i*numcol+j] = matdata[i*numcol+j];
- }
- }
- for ( i = 0; i <= numcol-1; ++i ) {
- leval = 0.0;
- for ( j = 0; j <= numcol-1; ++j ) {
- if ( ! (pivchk[j]) ) {
- for ( k = 0; k <= numcol-1; ++k ) {
- if ( ! (pivchk[k]) ) {
- if ( fabs(invary[j*numcol+k]) > leval ) {
- lerow = j;
- lecol = k;
- leval = fabs(invary[j*numcol+k]);
- }
- }
- }
- }
- }
- pivchk[lecol] = 1;
- pivlst[i*2] = lerow;
- pivlst[i*2+1] = lecol;
- if ( lerow != lecol ) {
- (*det) = -(*det);
- for ( l = 0; l <= numcol-1; ++l ) {
- matswap(&invary[lerow*numcol+l],&invary[lecol*numcol+l]);
- }
- }
- piv = invary[lecol*numcol+lecol];
- (*det) = (*det) * piv;
- if ( (*det) > 1.0e+30 ) {
- (*det) = 1;
- }
- invary[lecol*numcol+lecol] = 1.0;
- for ( l = 0; l <= numcol-1; ++l ) {
- invary[lecol*numcol+l] = invary[lecol*numcol+l] / piv;
- }
- for ( l1 = 0; l1 <= numcol-1; ++l1 ) {
- if ( l1 != lecol ) {
- t = invary[l1*numcol+lecol];
- invary[l1*numcol+lecol] = 0;
- for ( l = 0; l <= numcol-1; ++l ) {
- invary[l1*numcol+l] = invary[l1*numcol+l] -
- invary[lecol*numcol+l] * t;
- }
- }
- }
- }
- for ( i = 0; i <= numcol-1; ++i ) {
- l = numcol - i - 1;
- if ( pivlst[l*2] != pivlst[l*2+1] ) {
- lerow = pivlst[l*2];
- lecol = pivlst[l*2+1];
- for ( k = 0; k <= numcol-1; ++k ) {
- matswap(&invary[k*numcol+lerow],&invary[k*numcol+lecol]);
- }
- }
- }
- free(pivlst); free(pivchk);
- }
-
- void NormalizeEigenVectors(float *a,int n)
- {
- int i;
- int j;
- float max;
-
- for ( j = 0; j <= n-1; ++j ) {
- max = a[j];
- for ( i = 1; i <= n-1; ++i ) {
- if ( fabs(a[i*n+j]) > fabs(max) ) {
- max = a[i*n+j];
- }
- }
- for ( i = 0; i <= n-1; ++i ) {
- a[i*n+j] = a[i*n+j] / max;
- }
- }
- }
-
- void JacobiRotation(float *m, int p, int q,
- float *mp, float *mq, float *v,
- int n )
- {
- float g;
- float h;
- float mpp;
- float mqq;
- float mpq;
- float mpj;
- float mqj;
- float tempr;
- float angle;
- float c;
- float s;
- float cs;
- float cSquared;
- float sSquared;
- int j;
- /* float tau; */
-
- mpp = mp[p];
- mpq = mp[q];
- mqq = mq[q];
-
- if (fabs(mpp - mqq) > nearzero) {
- angle = atan(2.0 * mpq / (mpp - mqq)) / 2.0;
- if ( angle > M_PI_4 ) {
- angle = angle - M_PI_2;
- }
- }
- else {
- if ( mpq > 0 ) {
- angle = M_PI_4;
- }
- else {
- angle = -M_PI_4;
- }
- }
- c = cos(angle);
- s = sin(angle);
- cSquared = c * c;
- sSquared = s * s;
- cs = c * s;
- tempr = 2.0 * mpq * cs;
- mp[p] = mpp * cSquared + tempr + mqq * sSquared;
- mq[q] = mpp * sSquared - tempr + mqq * cSquared;
- mp[q] = 0.0;
- mq[p] = 0.0;
- /* tau = s / (1.0 + c); */
- for ( j = 0; j <= n-1; ++j ) {
- if (( j !=p ) && ( j != q)) {
- mpj = mp[j] * c + mq[j] * s;
- mqj = mq[j] * c - mp[j] * s;
- mp[j] = mpj;
- m[j*n+p] = mpj;
- mq[j] = mqj;
- m[j*n+q] = mqj;
- }
- }
- for ( j = 0; j <= n-1; ++j ) {
- g = v[j*n+p];
- h = v[j*n+q];
- v[j*n+p] = c * g + s * h;
- v[j*n+q] = -s * g + c * h;
- }
- }
-
-
- void CyclicJacobi(float *a,int n,float *eigenvalues,
- float *v,int *count,char *success)
- {
- # define tolerance 1.0e-8
- int maxCount;
- int i;
- int p;
- int q;
- float sumsq;
- float *avp;
- float *avq;
-
- avp = (float *) calloc(n*n,4);
- avq = (float *) calloc(n*n,4);
- maxCount = (*count);
- (*count) = 0;
- for ( p = 0; p <= n-1; ++p ) {
- for ( q = 0; q <= n-1; ++q ) {
- v[p*n+q] = 0.0;
- }
- v[p*n+p] = 1.0;
- }
- do {
- (*count) = (*count) + 1;
- sumsq = 0.0;
- for ( p = 0; p <= n-1; ++p ) {
- sumsq = sumsq + a[p*n+p] * a[p*n+p];
- }
- (*success) = 1;
- for ( p = 0; p <= n - 2; ++p ) {
- for ( q = p + 1; q <= n-1; ++q ) {
- if ( fabs(a[p*n+q] / sumsq) > tolerance ) {
- (*success) = 0;
- JacobiRotation(a,p,q,&a[p*n],&a[q*n], v, n);
- }
- }
- }
- } while ( ! ((*success) || ((*count) > maxCount)) );
- if ( (*success) ) {
- for ( p = 0; p <= n-1; ++p ) {
- eigenvalues[p] = a[p*n+p];
- }
- }
- free(avp); free(avq);
- }
-
-
-
- void CMatProd(struct complext *m1,struct complext *m2,int l,
- int m,int n,struct complext *m3)
- {
- int i;
- int j;
- int k;
- struct complext temp;
-
- for ( i = 0; i <= l-1; ++i ) {
- for ( j = 0; j <= n-1; ++j ) {
- m3[i*n+j].x = 0.0;
- m3[i*n+j].y = 0.0;
- for ( k = 0; k <= m-1; ++k ) {
- CMath(m1[i*m+k],'*',m2[k*n+j],&temp);
- CMath(m3[i*n+j],'+',temp,&m3[i*n+j]);
- }
- }
- }
- }
-
- void CMatScalarProd(struct complext *m1,struct complext sval,int numrow,
- int numcol,struct complext *m2)
- {
- int i;
- int j;
-
- for ( i = 0; i <= numrow-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- CMath(sval,'*',m1[i*numcol+j],&m2[i*numcol+j]);
- }
- }
- }
-
- void CMatAdd(struct complext *m1,struct complext *m2,
- int numrow,int numcol,struct complext *m3)
- {
- int i;
- int j;
-
- for ( i = 0; i <= numrow-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- CMath(m1[i*numcol+j],'+',m2[i*numcol+j],&m3[i*numcol+j]);
- }
- }
- }
-
- void CMatTranspose(struct complext *m1,int numrow,int numcol,
- struct complext *m2 )
- {
- int i;
- int j;
- float temp;
-
- for ( i = 0; i <= numrow-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- m2[j*numrow+i].x = m1[i*numcol+j].x;
- m2[j*numrow+i].y = m1[i*numcol+j].y;
- }
- }
- }
-
- void CMatInvert(struct complext *matdata,int numcol,float *det,
- struct complext *invary)
- {
- float *inv;
- float *coef;
- int nn;
- int i;
- int j;
- float de;
-
- inv = (float *) calloc(4*numcol*numcol,4);
- coef = (float *) calloc(4*numcol*numcol,4);
-
- for ( i = 0; i <= numcol-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- coef[(i * 2 )*2*numcol+(j * 2 )] = matdata[i*numcol +j].x;
- coef[(i * 2 )*2*numcol +(j * 2+1)] = -matdata[i*numcol+j].y;
- coef[(i * 2+1)*2*numcol +(j * 2 )] = matdata[i*numcol+j].y;
- coef[(i * 2+1)*2*numcol +(j * 2+1)] = matdata[i*numcol +j].x;
- }
- }
- nn = 2 * numcol;
- MatInvert(coef,nn,&de,inv);
- for ( i = 0; i <= numcol-1; ++i ) {
- for ( j = 0; j <= numcol-1; ++j ) {
- invary[i*numcol +j].x = inv[(i * 2)*2*numcol +(j * 2 )];
- invary[i*numcol +j].y = inv[(i * 2+1)*2*numcol +(j * 2 )];
- }
- }
- (*det) = de;
- free(coef); free(inv);
- }
-
- void CMatPrint(struct complext *m1,int m,int n,char *matname)
- {
- int i;
- int j;
-
- printf("%s\n", matname);
- printf("\n");
- for ( i = 0; i <= m-1; ++i ) {
- for ( j = 0; j <= n-1; ++j ) {
- printf("[%7.2f %7.2fj]", m1[i*n+j].x, m1[i*n+j].y );
- }
- printf("\n");
- }
- printf("\n");
- }
-