xue@11: /* xue@11: Harmonic sinusoidal modelling and tools xue@11: xue@11: C++ code package for harmonic sinusoidal modelling and relevant signal processing. xue@11: Centre for Digital Music, Queen Mary, University of London. xue@11: This file copyright 2011 Wen Xue. xue@11: xue@11: This program is free software; you can redistribute it and/or xue@11: modify it under the terms of the GNU General Public License as xue@11: published by the Free Software Foundation; either version 2 of the xue@11: License, or (at your option) any later version. xue@11: */ xue@1: //--------------------------------------------------------------------------- xue@1: #include xue@1: #include Chris@2: #include "matrix.h" Chris@5: Chris@5: /** \file matrix.h */ Chris@5: xue@1: //--------------------------------------------------------------------------- Chris@5: Chris@5: /** xue@1: function BalanceSim: applies a similarity transformation to matrix a so that a is "balanced". This is xue@1: used by various eigenvalue evaluation routines. xue@1: xue@1: In: matrix A[n][n] xue@1: Out: balanced matrix a xue@1: xue@1: No return value. xue@1: */ xue@1: void BalanceSim(int n, double** A) xue@1: { xue@1: if (n<2) return; xue@1: const int radix=2; xue@1: double sqrdx; xue@1: sqrdx=radix*radix; xue@1: bool finish=false; xue@1: while (!finish) xue@1: { xue@1: finish=true; xue@1: for (int i=0; iar) xue@1: { xue@1: ac/=radix; xue@1: sc/=sqrdx; xue@1: } xue@1: } xue@1: if ((sc+sr)/ac<0.95*s) xue@1: { xue@1: finish=false; xue@1: ar=1.0/ac; xue@1: for (int j=0; jAdd(Z, 2);} xue@1: int sizeN=sizeof(double)*N; xue@1: for (int m=0; mAdd(Z, 2);} xue@1: int sizeN=sizeof(cdouble)*N; xue@1: for (int m=0; mAdd(z, 1);} xue@1: memcpy(z, a, sizeof(double)*N); xue@1: return z; xue@1: }//Copy xue@1: cdouble* Copy(int N, cdouble* z, cdouble* a, MList* List) xue@1: { xue@1: if (!z){z=new cdouble[N]; if (List) List->Add(z, 1);} xue@1: memcpy(z, a, sizeof(cdouble)*N); xue@1: return z; xue@1: }//Copy xue@1: //version without specifying pre-allocated z xue@1: double* Copy(int N, double* a, MList* List){return Copy(N, 0, a, List);} xue@1: cdouble* Copy(int N, cdouble* a, MList* List){return Copy(N, 0, a, List);} xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function det: computes determinant by Gaussian elimination method with column pivoting xue@1: xue@1: In: matrix A[N][N] xue@1: xue@1: Returns det(A). On return content of matrix A is unchanged if mode=0. xue@1: */ xue@1: double det(int N, double** A, int mode) xue@1: { xue@1: int c, p, ip, *rp=new int[N]; for (int i=0; ifabs(A[rp[p]][i])) p=ip; ip++;} xue@1: if (A[rp[p]][i]==0) {result=0; goto ret;} xue@1: if (p!=i) {c=rp[i]; rp[i]=rp[p]; rp[p]=c; result=-result;} xue@1: for (int j=i+1; jmp) mp=mm, p=ip; ip++;} xue@1: if (mp==0) {result=0; goto ret;} xue@1: if (p!=i) {c=rp[i]; rp[i]=rp[p]; rp[p]=c;} xue@1: for (int j=i+1; j2) {l=m0-(m1-m0)*(m1-m0)/(m-2*m1+m0); delete[] y; return 0;} xue@1: k++; m0=m1; m1=m; xue@1: } xue@1: delete[] y; return 1; xue@1: }//EigPowerA xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function EigPowerI: Inverse power method for solving the eigenvalue given an approximate non-zero xue@1: eigenvector. xue@1: xue@1: In: matrix A[N][N], approximate eigenvector x[N]. xue@1: Out: eigenvalue l, eigenvector x[N]. xue@1: xue@1: Returns 0 is successful. Content of matrix A is unchangd on return. Initial x[N] must not be zero. xue@1: */ xue@1: int EigPowerI(int N, double& l, double* x, double** A, double ep, int maxiter) xue@1: { xue@1: int sizeN=sizeof(double)*N; xue@1: double* y=new double[N]; MultiplyXy(N, N, y, A, x); xue@1: double q=Inner(N, x, y)/Inner(N, x, x), dt; xue@1: double** aa=new double*[N]; aa[0]=new double[N*N]; xue@1: for (int i=0; i=N) {delete[] rp; return 1;} xue@1: if (p!=i){c=rp[i]; rp[i]=rp[p]; rp[p]=c;} xue@1: for (int j=i+1; j=0; i--) xue@1: { xue@1: x[i]=b[rp[i]]; for (int j=i+1; jfabs(A[rp[p]][i])/s[rp[p]]) p=ip; ip++;} xue@1: if (A[rp[p]][i]==0) {delete[] s; delete[] rp; return 1;} xue@1: if (p!=i) {c=rp[i]; rp[i]=rp[p]; rp[p]=c;} xue@1: for (int j=i+1; j=0; i--) xue@1: { xue@1: x[i]=b[rp[i]]; for (int j=i+1; j=0; n--) xue@1: { xue@1: double xn=a[n]; xue@1: for (int m=n+1; m=0; n--) xue@1: { xue@1: for (int m=n+1; mA. xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrix A[N][N] xue@1: xue@1: Returns the determinant of the inverse matrix, 0 on failure. xue@1: */ xue@1: double GICP(int N, double** A) xue@1: { xue@1: int c, p, ip, *rp=new int[N]; for (int i=0; ifabs(A[rp[p]][i])) p=ip; ip++;} xue@1: if (A[rp[p]][i]==0) {delete[] rp; return 0;} xue@1: if (p!=i) {c=rp[i]; rp[i]=rp[p]; rp[p]=c; result=-result;} xue@1: result/=A[rp[i]][i]; xue@1: for (int j=i+1; j~A[rp[p]][i]) p=ip; ip++;} xue@1: if (A[rp[p]][i]==0) {delete[] rp; return 0;} xue@1: if (p!=i) {c=rp[i]; rp[i]=rp[p]; rp[p]=c; result=-result;} xue@1: result=result/(A[rp[i]][i]); xue@1: for (int j=i+1; jlower trangular of A xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrix A[N][N] xue@1: xue@1: Returns the determinant of the lower trangular of A xue@1: */ xue@1: double GILT(int N, double** A) xue@1: { xue@1: double result=1; xue@1: A[0][0]=1/A[0][0]; xue@1: for (int i=1; iupper trangular of A xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrix A[N][N] xue@1: xue@1: Returns the determinant of the upper trangular of A xue@1: */ xue@1: double GIUT(int N, double** A) xue@1: { xue@1: double result=1; xue@1: A[0][0]=1/A[0][0]; xue@1: for (int i=1; iA. xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrix A[N][N] xue@1: xue@1: Returns the determinant of the inverse matrix, 0 on failure. xue@1: */ xue@1: double GISCP(int N, double** A) xue@1: { xue@1: int c, p, ip, *rp=new int[N]; for (int i=0; ifabs(A[rp[p]][i]/s[rp[p]])) p=ip; ip++;} xue@1: if (A[rp[p]][i]==0) {delete[] s; delete[] rp; return 0;} xue@1: if (p!=i) {c=rp[i]; rp[i]=rp[p]; rp[p]=c; result=-result;} xue@1: result/=A[rp[i]][i]; xue@1: for (int j=i+1; jX. xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrix X[N][N] xue@1: xue@1: Returns the determinant of the inverse matrix, 0 on failure. xue@1: */ xue@1: double GISCP(int N, double** X, double** A) xue@1: { xue@1: Copy(N, X, A); xue@1: return GISCP(N, X); xue@1: }//GISCP xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function GSI: Gaussian-Seidel iterative algorithm for solving linear system Ax=b. Breaks down if any xue@1: Aii=0, like the Jocobi method JI(...). xue@1: xue@1: Gaussian-Seidel iteration is x(k)=(D-L)^(-1)(Ux(k-1)+b), where D is diagonal, L is lower triangular, xue@1: U is upper triangular and A=L+D+U. xue@1: xue@1: In: matrix A[N][N], vector b[N], initial vector x0[N] xue@1: Out: vector x0[N] xue@1: xue@1: Returns 0 is successful. Contents of matrix A and vector b remain unchanged on return. xue@1: */ xue@1: int GSI(int N, double* x0, double** A, double* b, double ep, int maxiter) xue@1: { xue@1: double e, *x=new double[N]; xue@1: int k=0, sizeN=sizeof(double)*N; xue@1: while (k=maxiter) return 1; xue@1: return 0; xue@1: }//GSI xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function Hessenb: reducing a square matrix A to upper Hessenberg form xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrix A[N][N], in upper Hessenberg form xue@1: xue@1: No return value. xue@1: */ xue@1: void Hessenb(int N, double** A) xue@1: { xue@1: double x, y; xue@1: for (int m=1; m fabs(x)) xue@1: { xue@1: x=A[j][m-1]; xue@1: i=j; xue@1: } xue@1: } xue@1: if (i!=m) xue@1: { xue@1: for (int j=m-1; j=1; i--) xue@1: { xue@1: int l=i-1; xue@1: double h=0, scale=0; xue@1: if (l>0) xue@1: { xue@1: for (int k=0; k<=l; k++) scale+=fabs(A[i][k]); xue@1: if (scale==0.0) sd[i]=A[i][l]; xue@1: else xue@1: { xue@1: for (int k=0; k<=l; k++) xue@1: { xue@1: A[i][k]/=scale; xue@1: h+=A[i][k]*A[i][k]; xue@1: } xue@1: double f=A[i][l]; xue@1: double g=(f>=0?-sqrt(h): sqrt(h)); xue@1: sd[i]=scale*g; xue@1: h-=f*g; xue@1: A[i][l]=f-g; xue@1: f=0; xue@1: for (int j=0; j<=l; j++) xue@1: { xue@1: A[j][i]=A[i][j]/h; xue@1: g=0; xue@1: for (int k=0; k<=j; k++) g+=A[j][k]*A[i][k]; xue@1: for (int k=j+1; k<=l; k++) g+=A[k][j]*A[i][k]; xue@1: sd[j]=g/h; xue@1: f+=sd[j]*A[i][j]; xue@1: } xue@1: double hh=f/(h+h); xue@1: for (int j=0; j<=l; j++) xue@1: { xue@1: f=A[i][j]; xue@1: sd[j]=g=sd[j]-hh*f; xue@1: for (int k=0; k<=j; k++) A[j][k]-=(f*sd[k]+g*A[i][k]); xue@1: } xue@1: } xue@1: } xue@1: else xue@1: sd[i]=A[i][l]; xue@1: d[i]=h; xue@1: } xue@1: xue@1: d[0]=sd[0]=0; xue@1: xue@1: for (int i=0; i=maxiter) return 1; xue@1: else return 0; xue@1: }//JI xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function LDL: LDL' decomposition A=LDL', where L is lower triangular and D is diagonal identical l and xue@1: a allowed. xue@1: xue@1: The symmetric matrix A is positive definite iff A can be factorized as LDL', where L is lower xue@1: triangular with ones on its diagonal and D is diagonal with positive diagonal entries. xue@1: xue@1: If a symmetric matrix A can be reduced by Gaussian elimination without row interchanges, then it can xue@1: be factored into LDL', where L is lower triangular with ones on its diagonal and D is diagonal with xue@1: non-zero diagonal entries. xue@1: xue@1: In: matrix A[N][N] xue@1: Out: lower triangular matrix L[N][N], vector d[N] containing diagonal elements of D xue@1: xue@1: Returns 0 if successful. Content of matrix A is unchanged on return. xue@1: */ xue@1: int LDL(int N, double** L, double* d, double** A) xue@1: { xue@1: double* v=new double[N]; xue@1: xue@1: if (A[0][0]==0) {delete[] v; return 1;} xue@1: d[0]=A[0][0]; for (int j=1; j=N. Use of this function requires xue@1: the submatrix A[N][N] be invertible. xue@1: xue@1: In: matrix A[M][N], vector y[M], M>=N. xue@1: Out: vector x[N]. xue@1: xue@1: No return value. Contents of matrix A and vector y are unchanged on return. xue@1: */ xue@1: void LSLinear2(int M, int N, double* x, double** A, double* y) xue@1: { xue@1: double** A1=Copy(N, N, 0, A); xue@1: LU(N, x, A1, y); xue@1: if (M>N) xue@1: { xue@1: double** B=&A[N]; xue@1: double* Del=MultiplyXy(M-N, N, B, x); xue@1: MultiAdd(M-N, Del, Del, &y[N], -1); xue@1: double** A2=MultiplyXtX(N, N, A); xue@1: MultiplyXtX(N, M-N, A1, B); xue@1: MultiAdd(N, N, A2, A2, A1, 1); xue@1: double* b2=MultiplyXty(N, M-N, B, Del); xue@1: double* dx=new double[N]; xue@1: GESCP(N, dx, A2, b2); xue@1: MultiAdd(N, x, x, dx, -1); xue@1: delete[] dx; xue@1: delete[] Del; xue@1: delete[] b2; xue@1: DeAlloc2(A2); xue@1: } xue@1: DeAlloc2(A1); xue@1: }//LSLinear2 xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function LU: LU decomposition A=LU, where L is lower triangular with diagonal entries 1 and U is upper xue@1: triangular. xue@1: xue@1: LU is possible if A can be reduced by Gaussian elimination without row interchanges. xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrices L[N][N] and U[N][N], subject to input values of L and U: xue@1: if L euqals NULL, L is not returned xue@1: if U equals NULL or A, U is returned in A, s.t. A is modified xue@1: if L equals A, L is returned in A, s.t. A is modified xue@1: if L equals U, L and U are returned in the same matrix xue@1: when L and U are returned in the same matrix, diagonal of L (all 1) is not returned xue@1: xue@1: Returns 0 if successful. xue@1: */ xue@1: int LU(int N, double** L, double** U, double** A) xue@1: { xue@1: double* diagl=new double[N]; xue@1: for (int i=0; i=0; i--) xue@1: { xue@1: x[i]/=A[i][i]; xue@1: for (int j=0; jb[i-j, j] xue@1: the main diagonal is b[0][0]~b[0][N-1] xue@1: the 1st upper subdiagonal is b[-1][1]~b[-1][N-1] xue@1: the 2nd upper subdiagonal is b[-2][2]~b[-2][N-1] xue@1: the 1st lower subdiagonal is b[1][0]~b[1][N-2] xue@1: the 2nd lower subdiagonal is b[2][0]~b[2][N-3] xue@1: xue@1: Out: L[N][N] and U[N][N], main diagonal of L being all 1 (probably), stored in a compact format in xue@1: b[-2:2][N]. xue@1: xue@1: Returns 0 if successful. xue@1: */ xue@1: int LU_PD(int N, double** b) xue@1: { xue@1: if (b[0][0]==0) return 1; xue@1: b[1][0]/=b[0][0], b[2][0]/=b[0][0]; xue@1: xue@1: //i=1, not to double b[*][i-2], b[-2][i] xue@1: b[0][1]-=b[1][0]*b[-1][1]; xue@1: if (b[0][1]==0) return 2; xue@1: b[-1][2]-=b[1][0]*b[-2][2]; xue@1: b[1][1]-=b[2][0]*b[-1][1]; xue@1: b[1][1]/=b[0][1]; xue@1: b[2][1]/=b[0][1]; xue@1: xue@1: for (int i=2; i=0; i--) xue@1: c[i]=(c[i]-b[-1][i+1]*c[i+1]-b[-2][i+2]*c[i+2])/b[0][i]; xue@1: } xue@1: return result; xue@1: }//LU_PD xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function LUCP: LU decomposition A=LU with column pivoting xue@1: xue@1: In: matrix A[N][N] xue@1: Out: matrix A[N][N] now holding L and U by L_U[i][j]=A[ind[i]][j], where L_U xue@1: hosts L and U according to mode: xue@1: mode=0: L diag=abs(U diag), U diag as return xue@1: mode=1: L diag=1, U diag as return xue@1: mode=2: U diag=1, L diag as return xue@1: xue@1: Returns the determinant of A. xue@1: */ xue@1: double LUCP(double **A, int N, int *ind, int &parity, int mode) xue@1: { xue@1: double det=1; xue@1: parity=1; xue@1: xue@1: for (int i=0; ivmax) vmax=tmp; xue@1: if (vmax==0) { parity=0; goto deletenorm; } //det=0 at this point xue@1: norm[i]=1/vmax; xue@1: } xue@1: xue@1: int maxind; xue@1: for (int j=0; j=j xue@1: double tmp=A[i][j]; for (int k=0; k=vmax) maxind=i, vmax=tmp2; xue@1: } xue@1: if (vmax==0) { parity=0; goto deletenorm; } //pivot being zero xue@1: if (j!=maxind) xue@1: { xue@1: //do column pivoting: switching rows xue@1: for (int k=0; kAdd(z, 1);} \ xue@1: for (int m=0; mAdd(z, 1); \ xue@1: for (int m=0; m=maxiter) return 1; xue@1: double g=(d[l+1]-d[l])/(2*sd[l]); xue@1: double r=sqrt(g*g+1); xue@1: g=d[m]-d[l]+sd[l]/(g+(g>=0?r:-r)); xue@1: double s=1, c=1, p=0; xue@1: int i; xue@1: for (i=m-1; i>=l; i--) xue@1: { xue@1: double f=s*sd[i], b=c*sd[i]; xue@1: sd[i+1]=(r=sqrt(f*f+g*g)); xue@1: if (r==0) xue@1: { xue@1: d[i+1]-=p; xue@1: sd[m]=0; xue@1: break; xue@1: } xue@1: s=f/r, c=g/r; xue@1: g=d[i+1]-p; xue@1: r=(d[i]-g)*s+2.0*c*b; xue@1: p=s*r; xue@1: d[i+1]=g+p; xue@1: g=c*r-b; xue@1: for (int k=0; k=l) continue; xue@1: d[l]-=p; xue@1: sd[l]=g; xue@1: sd[m]=0.0; xue@1: } xue@1: } xue@1: while (m!=l); xue@1: } xue@1: return 0; xue@1: }//QL xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function QR: nr version of QR method for solving upper Hessenberg system A. This is compatible with xue@1: Hessenb method. xue@1: xue@1: In: matrix A[N][N] xue@1: Out: vector ev[N] of eigenvalues xue@1: xue@1: Returns 0 on success. Content of matrix A is destroyed on return. xue@1: */ xue@1: int QR(int N, double **A, cdouble* ev) xue@1: { xue@1: int n=N, m, l, k, j, iter, i, mmin, maxiter=30; xue@1: double **a=A, z, y, x, w, v, u, t=0, s, r, q, p, a1=0; xue@1: for (i=0; i0?i-1:0; j=0) xue@1: { xue@1: iter=0; xue@1: do xue@1: { xue@1: for (l=n; l>0; l--) xue@1: { xue@1: s=fabs(a[l-1][l-1])+fabs(a[l][l]); xue@1: if (s==0) s=a1; xue@1: if (fabs(a[l][l-1])+s==s) {a[l][l-1]=0; break;} xue@1: } xue@1: x=a[n][n]; xue@1: if (l==n) {ev[n].x=x+t; ev[n--].y=0;} xue@1: else xue@1: { xue@1: y=a[n-1][n-1], w=a[n][n-1]*a[n-1][n]; xue@1: if (l==(n-1)) xue@1: { xue@1: p=0.5*(y-x); xue@1: q=p*p+w; xue@1: z=sqrt(fabs(q)); xue@1: x+=t; xue@1: if (q>=0) xue@1: { xue@1: z=p+(p>=0?z:-z); xue@1: ev[n-1].x=ev[n].x=x+z; xue@1: if (z) ev[n].x=x-w/z; xue@1: ev[n-1].y=ev[n].y=0; xue@1: } xue@1: else xue@1: { xue@1: ev[n-1].x=ev[n].x=x+p; xue@1: ev[n].y=z; ev[n-1].y=-z; xue@1: } xue@1: n-=2; xue@1: } xue@1: else xue@1: { xue@1: if (iter>=maxiter) return 1; xue@1: if (iter%10==9) xue@1: { xue@1: t+=x; xue@1: for (i=0; i<=n; i++) a[i][i]-=x; xue@1: s=fabs(a[n][n-1])+fabs(a[n-1][n-2]); xue@1: y=x=0.75*s; xue@1: w=-0.4375*s*s; xue@1: } xue@1: iter++; xue@1: for (m=n-2; m>=l; m--) xue@1: { xue@1: z=a[m][m]; xue@1: r=x-z; s=y-z; xue@1: p=(r*s-w)/a[m+1][m]+a[m][m+1]; q=a[m+1][m+1]-z-r-s; r=a[m+2][m+1]; xue@1: s=fabs(p)+fabs(q)+fabs(r); xue@1: p/=s; q/=s; r/=s; xue@1: if (m==l) break; xue@1: u=fabs(a[m][m-1])*(fabs(q)+fabs(r)); xue@1: v=fabs(p)*(fabs(a[m-1][m-1])+fabs(z)+fabs(a[m+1][m+1])); xue@1: if (u+v==v) break; xue@1: } xue@1: for (i=m+2; i<=n; i++) xue@1: { xue@1: a[i][i-2]=0; xue@1: if (i!=m+2) a[i][i-3]=0; xue@1: } xue@1: for (k=m; k<=n-1; k++) xue@1: { xue@1: if (k!=m) xue@1: { xue@1: p=a[k][k-1]; xue@1: q=a[k+1][k-1]; xue@1: r=0; xue@1: if (k!=n-1) r=a[k+2][k-1]; xue@1: x=fabs(p)+fabs(q)+fabs(r); xue@1: if (x!=0) p/=x, q/=x, r/=x; xue@1: } xue@1: if (p>=0) s=sqrt(p*p+q*q+r*r); xue@1: else s=-sqrt(p*p+q*q+r*r); xue@1: if (s!=0) xue@1: { xue@1: if (k==m) xue@1: { xue@1: if (l!=m) a[k][k-1]=-a[k][k-1]; xue@1: } xue@1: else a[k][k-1]=-s*x; xue@1: p+=s; xue@1: x=p/s; y=q/s; z=r/s; q/=p; r/=p; xue@1: for (j=k; j<=n; j++) xue@1: { xue@1: p=a[k][j]+q*a[k+1][j]; xue@1: if (k!=n-1) xue@1: { xue@1: p+=r*a[k+2][j]; xue@1: a[k+2][j]-=p*z; xue@1: } xue@1: a[k+1][j]-=p*y; a[k][j]-=p*x; xue@1: } xue@1: mmin=nl+1); xue@1: } xue@1: return 0; xue@1: }//QR xue@1: Chris@5: /** xue@1: function QR_GS: QR decomposition A=QR using Gram-Schmidt method xue@1: xue@1: In: matrix A[M][N], M>=N xue@1: Out: Q[M][N], R[N][N] xue@1: xue@1: No return value. xue@1: */ xue@1: void QR_GS(int M, int N, double** A, double** Q, double** R) xue@1: { xue@1: double *u=new double[M]; xue@1: for (int n=0; n=N xue@1: Out: Q[M][M], R[M][N] xue@1: xue@1: No return value. xue@1: */ xue@1: void QR_householder(int M, int N, double** A, double** Q, double** R) xue@1: { xue@1: double *u=new double[M*3], *ur=&u[M], *qu=&u[M*2]; xue@1: for (int m=0; m0) alf=-alf; xue@1: for (int m=n; mAdd(z, 2);} xue@1: for (int m=0; m1) memset(A[1], 0, sizeof(double)*N*(N-1)); xue@1: for (int i=1; i=maxiter) return 1; xue@1: return 0; xue@1: }//SorI xue@1: xue@1: //--------------------------------------------------------------------------- xue@1: //Submatrix routines xue@1: Chris@5: /** xue@1: function SetSubMatrix: copy matrix x[Y][X] into matrix z at (Y1, X1). xue@1: xue@1: In: matrix x[Y][X], matrix z with dimensions no less than [Y+Y1][X+X1] xue@1: Out: matrix z, updated. xue@1: xue@1: No return value. xue@1: */ xue@1: void SetSubMatrix(double** z, double** x, int Y1, int Y, int X1, int X) xue@1: { xue@1: for (int y=0; yAdd(z, 2);} xue@1: for (int y=0; yAdd(z, 1);} xue@1: memcpy(z, &x[X1], sizeof(cdouble)*X); xue@1: return z; xue@1: }//SubVector xue@1: //wrapper function xue@1: cdouble* SubVector(cdouble* x, int X1, int X, MList* List) xue@1: { xue@1: return SubVector(0, x, X1, X, List); xue@1: }//SubVector xue@1: xue@1: //--------------------------------------------------------------------------- Chris@5: /** xue@1: function transpose: matrix transpose: A'->A xue@1: xue@1: In: matrix a[N][N] xue@1: Out: matrix a[N][N] after transpose xue@1: xue@1: No return value. xue@1: */ xue@1: void transpose(int N, double** a) xue@1: { xue@1: double tmp; xue@1: for (int i=1; iZ xue@1: xue@1: In: matrix a[M][N] xue@1: Out: matrix z[N][M] xue@1: xue@1: Returns pointer to z. z is created anew if z=0 is specifid on start. xue@1: */ xue@1: double** transpose(int N, int M, double** ta, double** a, MList* List) xue@1: { xue@1: if (!ta) {Allocate2(double, N, M, ta); if (List) List->Add(ta, 2);} xue@1: for (int n=0; nAdd(P, 2);} xue@1: int sizeN=sizeof(double)*N; xue@1: for (int i=0; iAdd(P, 2); xue@1: return P; xue@1: }//Unitary xue@1: //wrapper functions xue@1: double** Unitary(int N, double* x, double* y, MList* List){return Unitary(N, 0, x, y, List);} xue@1: cdouble** Unitary(int N, cdouble* x, cdouble* y, MList* List){return Unitary(N, 0, x, y, List);} xue@1: xue@1: xue@1: