annotate Matrix.h @ 1:6422640a802f

first upload
author Wen X <xue.wen@elec.qmul.ac.uk>
date Tue, 05 Oct 2010 10:45:57 +0100
parents
children
rev   line source
xue@1 1 #ifndef MatrixH
xue@1 2 #define MatrixH
xue@1 3
xue@1 4 /*
xue@1 5 Matrix.cpp - matrix operations.
xue@1 6
xue@1 7 Matrices are accessed by double pointers as MATRIX[Y][X], where Y is the row index.
xue@1 8 */
xue@1 9
xue@1 10 #include "xcomplex.h"
xue@1 11 #include "arrayalloc.h"
xue@1 12
xue@1 13 //--Similar balance----------------------------------------------------------
xue@1 14 void BalanceSim(int n, double** A);
xue@1 15
xue@1 16 //--Choleski factorization---------------------------------------------------
xue@1 17 int Choleski(int N, double** L, double** A);
xue@1 18
xue@1 19 //--matrix copy--------------------------------------------------------------
xue@1 20 double** Copy(int M, int N, double** Z, double** A, MList* List=0);
xue@1 21 double** Copy(int M, int N, double** A, MList* List=0);
xue@1 22 double** Copy(int N, double** Z, double ** A, MList* List=0);
xue@1 23 double** Copy(int N, double ** A, MList* List=0);
xue@1 24 cdouble** Copy(int M, int N, cdouble** Z, cdouble** A, MList* List=0);
xue@1 25 cdouble** Copy(int M, int N, cdouble** A, MList* List=0);
xue@1 26 cdouble** Copy(int N, cdouble** Z, cdouble** A, MList* List=0);
xue@1 27 cdouble** Copy(int N, cdouble** A, MList* List=0);
xue@1 28 double* Copy(int N, double* z, double* a, MList* List=0);
xue@1 29 double* Copy(int N, double* a, MList* List=0);
xue@1 30 cdouble* Copy(int N, cdouble* z, cdouble* a, MList* List=0);
xue@1 31 cdouble* Copy(int N, cdouble* a, MList* List=0);
xue@1 32
xue@1 33 //--matrix determinant calculation-------------------------------------------
xue@1 34 double det(int N, double** A, int mode=0);
xue@1 35 cdouble det(int N, cdouble** A, int mode=0);
xue@1 36
xue@1 37 //--power methods for solving eigenproblems----------------------------------
xue@1 38 int EigPower(int N, double& l, double* x, double** A, double ep=1e-6, int maxiter=50);
xue@1 39 int EigPowerA(int N, double& l, double* x, double** A, double ep=1e-6, int maxiter=50);
xue@1 40 int EigPowerI(int N, double& l, double* x, double** A, double ep=1e-6, int maxiter=50);
xue@1 41 int EigPowerS(int N, double& l, double* x, double** A, double ep=1e-6, int maxiter=50);
xue@1 42 int EigPowerWielandt(int N, double& m, double* u, double l, double* v, double** A, double ep=1e-06, int maxiter=50);
xue@1 43 int EigenValues(int N, double** A, cdouble* ev);
xue@1 44 int EigSym(int N, double** A, double* d, double** Q);
xue@1 45
xue@1 46 //--Gaussian elimination for solving linear systems--------------------------
xue@1 47 int GEB(int N, double* x, double** A, double* b);
xue@1 48 int GESCP(int N, double* x, double** A, double*b);
xue@1 49 void GExL(int N, double* x, double** L, double* a);
xue@1 50 void GExLAdd(int N, double* x, double** L, double* a);
xue@1 51 void GExL1(int N, double* x, double** L, double a);
xue@1 52 void GExL1Add(int N, double* x, double** L, double a);
xue@1 53
xue@1 54 /*
xue@1 55 template GECP: Gaussian elimination with maximal column pivoting for solving linear system Ax=b
xue@1 56
xue@1 57 In: matrix A[N][N], vector b[N]
xue@1 58 Out: vector x[N]
xue@1 59
xue@1 60 Returns 0 if successful. Contents of matrix A and vector b are destroyed on return.
xue@1 61 */
xue@1 62 template<class T, class Ta>int GECP(int N, T* x, Ta** A, T *b, Ta* logdet=0)
xue@1 63 {
xue@1 64 if (logdet) *logdet=1E-302; int c, p, ip, *rp=new int[N]; for (int i=0; i<N; i++) rp[i]=i;
xue@1 65 Ta m;
xue@1 66 //Gaussian eliminating
xue@1 67 for (int i=0; i<N-1; i++)
xue@1 68 {
xue@1 69 p=i, ip=i+1;
xue@1 70 while (ip<N){if (fabs(A[rp[ip]][i])>fabs(A[rp[p]][i])) p=ip; ip++;}
xue@1 71 if (A[rp[p]][i]==0) {delete[] rp; return 1;}
xue@1 72 if (p!=i) {c=rp[i]; rp[i]=rp[p]; rp[p]=c;}
xue@1 73 for (int j=i+1; j<N; j++)
xue@1 74 {
xue@1 75 m=A[rp[j]][i]/A[rp[i]][i];
xue@1 76 A[rp[j]][i]=0;
xue@1 77 for (int k=i+1; k<N; k++) A[rp[j]][k]-=m*A[rp[i]][k];
xue@1 78 b[rp[j]]-=m*b[rp[i]];
xue@1 79 }
xue@1 80 }
xue@1 81 if (A[rp[N-1]][N-1]==0) {delete[] rp; return 1;}
xue@1 82 //backward substitution
xue@1 83 x[N-1]=b[rp[N-1]]/A[rp[N-1]][N-1];
xue@1 84 for (int i=N-2; i>=0; i--)
xue@1 85 {
xue@1 86 x[i]=b[rp[i]]; for (int j=i+1; j<N; j++) x[i]-=A[rp[i]][j]*x[j]; x[i]/=A[rp[i]][i];
xue@1 87 }
xue@1 88 if (logdet){*logdet=log(fabs(A[rp[0]][0])); for (int n=1; n<N; n++) *logdet+=log(fabs(A[rp[n]][n]));}
xue@1 89 delete[] rp;
xue@1 90 return 0;
xue@1 91 }//GECP
xue@1 92
xue@1 93 //--inverse lower and upper triangular matrices------------------------------
xue@1 94 double GILT(int N, double** A);
xue@1 95 double GIUT(int N, double** A);
xue@1 96
xue@1 97 //--inverse matrix calculation with gaussian elimination---------------------
xue@1 98 double GICP(int N, double** X, double** A);
xue@1 99 double GICP(int N, double** A);
xue@1 100 cdouble GICP(int N, cdouble** A);
xue@1 101 double GISCP(int N, double** X, double** A);
xue@1 102 double GISCP(int N, double** A);
xue@1 103
xue@1 104 //--Gaussian-Seidel method for solving linear systems------------------------
xue@1 105 int GSI(int N, double* x0, double** A, double* b, double ep=1e-4, int maxiter=50);
xue@1 106
xue@1 107 //Reduction to upper Heissenberg matrix by elimination with pivoting
xue@1 108 void Hessenb(int n, double** A);
xue@1 109
xue@1 110 //--Householder algorithm converting a matrix tridiagonal--------------------
xue@1 111 void HouseHolder(int N, double** A);
xue@1 112 void HouseHolder(int N, double** T, double** Q, double** A);
xue@1 113 void HouseHolder(int n, double **A, double* d, double* sd);
xue@1 114
xue@1 115 //--inner product------------------------------------------------------------
xue@1 116 double Inner(int N, double* x, double* y);
xue@1 117 cdouble Inner(int N, double* x, cdouble* y);
xue@1 118 cdouble Inner(int N, cdouble* x, cdouble* y);
xue@1 119 cdouble Inner(int N, cfloat* x, cdouble* y);
xue@1 120 cfloat Inner(int N, cfloat* x, cfloat* y);
xue@1 121 double Inner(int M, int N, double** X, double** Y);
xue@1 122
xue@1 123 /*
xue@1 124 template Inner: Inner product <xw, y>
xue@1 125
xue@1 126 In: vectors x[N], w[N] and y[N]
xue@1 127
xue@1 128 Returns inner product of xw and y.
xue@1 129 */
xue@1 130 template<class Tx, class Tw>cdouble Inner(int N, Tx* x, Tw* w, cdouble* y)
xue@1 131 {
xue@1 132 cdouble result=0;
xue@1 133 for (int i=0; i<N; i++) result+=(x[i]*w[i])**y[i];
xue@1 134 return result;
xue@1 135 }//Inner
xue@1 136 template<class Tx, class Tw>cdouble Inner(int N, Tx* x, Tw* w, double* y)
xue@1 137 {
xue@1 138 cdouble result=0;
xue@1 139 for (int i=0; i<N; i++) result+=x[i]*w[i]*y[i];
xue@1 140 return result;
xue@1 141 }//Inner
xue@1 142
xue@1 143 //--Jacobi iterative method for solving linear systems-----------------------
xue@1 144 int JI(int N, double* x, double** A, double* b, double ep=1e-4, int maxiter=50);
xue@1 145
xue@1 146 //--LDL factorization of a symmetric matrix----------------------------------
xue@1 147 int LDL(int N, double** L, double* d, double** A);
xue@1 148
xue@1 149 //--LQ factorization by Gram-Schmidt-----------------------------------------
xue@1 150 void LQ_GS(int M, int N, double** A, double** L, double** Q);
xue@1 151
xue@1 152 //--1-stage Least-square solution of overdetermined linear system------------
xue@1 153 /*
xue@1 154 template LSLinera: direct LS solution of A[M][N]x[N]=y[M], M>=N.
xue@1 155
xue@1 156 In: matrix A[M][N], vector y[M]
xue@1 157 Out: vector x[N]
xue@1 158
xue@1 159 Returns the log determinant of AtA. Contents of matrix A and vector y are unchanged on return.
xue@1 160 */
xue@1 161 template <class T> T LSLinear(int M, int N, T* x, T** A, T* y)
xue@1 162 {
xue@1 163 MList* mlist=new MList;
xue@1 164 T** AtA=MultiplyXtX(N, M, A, mlist);
xue@1 165 T* Aty=MultiplyXty(N, M, A, y, mlist);
xue@1 166 T result; GECP(N, x, AtA, Aty, &result);
xue@1 167 delete mlist;
xue@1 168 return result;
xue@1 169 }//LSLinear
xue@1 170
xue@1 171 //--2-stage Least-square solution of overdetermined linear system------------
xue@1 172 void LSLinear2(int M, int N, double* x, double** A, double* y);
xue@1 173
xue@1 174 //--LU factorization of a non-singular matrix--------------------------------
xue@1 175 int LU_Direct(int mode, int N, double* diag, double** a);
xue@1 176 int LU(int N, double** l, double** u, double** a); void LU_DiagL(int N, double** l, double* diagl, double** u, double** a);
xue@1 177 int LU_PD(int N, double** b);
xue@1 178 int LU_PD(int N, double** b, double* c);
xue@1 179 double LUCP(double **a, int N, int *ind, int& parity, int mode=1);
xue@1 180
xue@1 181 //--LU factorization method for solving a linear system----------------------
xue@1 182 void LU(int N, double* x, double** A, double* y, int* ind=0);
xue@1 183
xue@1 184 //--find maximum of vector---------------------------------------------------
xue@1 185 int maxind(double* data, int from, int to);
xue@1 186
xue@1 187 //--matrix linear combination------------------------------------------------
xue@1 188 /*
xue@1 189 template MultiAdd: matrix linear combination Z=X+aY
xue@1 190
xue@1 191 In: matrices X[M][N], Y[M][N], scalar a
xue@1 192 Out: matrix Z[M][N]
xue@1 193
xue@1 194 Returns pointer to Z. Z is created anew if Z=0 is specified on start.
xue@1 195 */
xue@1 196 template<class Tz, class Tx, class Ty, class Ta> Tz** MultiAdd(int M, int N, Tz** Z, Tx** X, Ty** Y, Ta a, MList* List=0)
xue@1 197 {
xue@1 198 if (!Z){Allocate2(Tz, M, N, Z); if (List) List->Add(Z, 2);}
xue@1 199 for (int i=0; i<M; i++) for (int j=0; j<N; j++) Z[i][j]=X[i][j]+a*Y[i][j];
xue@1 200 return Z;
xue@1 201 }//MultiAdd
xue@1 202
xue@1 203 /*
xue@1 204 template MultiAdd: vector linear combination z=x+ay
xue@1 205
xue@1 206 In: vectors x[N], y[N], scalar a
xue@1 207 Out: vector z[N]
xue@1 208
xue@1 209 Returns pointer to z. z is created anew if z=0 is specified on start.
xue@1 210 */
xue@1 211 template<class Tz, class Tx, class Ty, class Ta> Tz* MultiAdd(int N, Tz* z, Tx* x, Ty* y, Ta a, MList* List=0)
xue@1 212 {
xue@1 213 if (!z){z=new Tz[N]; if (List) List->Add(z, 1);}
xue@1 214 for (int i=0; i<N; i++) z[i]=x[i]+Ty(a)*y[i];
xue@1 215 return z;
xue@1 216 }//MultiAdd
xue@1 217 template<class Tx, class Ty, class Ta> Tx* MultiAdd(int N, Tx* x, Ty* y, Ta a, MList* List=0)
xue@1 218 {
xue@1 219 return MultiAdd(N, (Tx*)0, x, y, a, List);
xue@1 220 }//MultiAdd
xue@1 221
xue@1 222 //--matrix multiplication by constant----------------------------------------
xue@1 223 /*
xue@1 224 template Multiply: matrix-constant multiplication Z=aX
xue@1 225
xue@1 226 In: matrix X[M][N], scalar a
xue@1 227 Out: matrix Z[M][N]
xue@1 228
xue@1 229 Returns pointer to Z. Z is created anew if Z=0 is specified on start.
xue@1 230 */
xue@1 231 template<class Tz, class Tx, class Ta> Tz** Multiply(int M, int N, Tz** Z, Tx** X, Ta a, MList* List=0)
xue@1 232 {
xue@1 233 if (!Z){Allocate2(Tz, M, N, Z); if (List) List->Add(Z, 2);}
xue@1 234 for (int i=0; i<M; i++) for (int j=0; j<N; j++) Z[i][j]=a*X[i][j];
xue@1 235 return Z;
xue@1 236 }//Multiply
xue@1 237
xue@1 238 /*
xue@1 239 template Multiply: vector-constant multiplication z=ax
xue@1 240
xue@1 241 In: matrix x[N], scalar a
xue@1 242 Out: matrix z[N]
xue@1 243
xue@1 244 Returns pointer to z. z is created anew if z=0 is specified on start.
xue@1 245 */
xue@1 246 template<class Tz, class Tx, class Ta> Tz* Multiply(int N, Tz* z, Tx* x, Ta a, MList* List=0)
xue@1 247 {
xue@1 248 if (!z){z=new Tz[N]; if (List) List->Add(z, 1);}
xue@1 249 for (int i=0; i<N; i++) z[i]=x[i]*a;
xue@1 250 return z;
xue@1 251 }//Multiply
xue@1 252 template<class Tx, class Ta>Tx* Multiply(int N, Tx* x, Ta a, MList* List=0)
xue@1 253 {
xue@1 254 return Multiply(N, (Tx*)0, x, a, List);
xue@1 255 }//Multiply
xue@1 256
xue@1 257 //--matrix multiplication operations-----------------------------------------
xue@1 258 /*
xue@1 259 macro Multiply_full: matrix-matrix multiplication z=xy and multiplication-accumulation z=z+xy.
xue@1 260
xue@1 261 Each expansion of the macro defines three function templates; two are named $MULTIPLY and do matrix
xue@1 262 multiplication only; one is named $MULTIADD and accumulates the multiplicated result on top of a
xue@1 263 specified matrix. One of the two $MULTIPLY functions allows using a pre-allocated matrix to accept
xue@1 264 the matrix product, while the other directly allocates a new matrix and returns the pointer.
xue@1 265
xue@1 266 Functions are named after their exact functions. For example, MultiplyXYc multiplies matrix X with
xue@1 267 the complex conjugate of matrix Y, where postfix "c" attched to Y stands for conjugate. Likewise,
xue@1 268 the postfix "t" stands for transpose, and "h" stnads for Hermitian (conjugate transpose).
xue@1 269
xue@1 270 Three dimension arguments are needed by each function template. The first and last of the three are
xue@1 271 the number of rows and columns, respectively, of the product (output) matrix. The middle one is the
xue@1 272 "other", common dimension of both multiplier matrices.
xue@1 273 */
xue@1 274 #define Multiply_full(MULTIPLY, MULTIADD, xx, yy) \
xue@1 275 template<class Tx, class Ty>Tx** MULTIPLY(int N, int M, int K, Tx** z, Tx** x, Ty** y, MList* List=0){ \
xue@1 276 if (!z) {Allocate2(Tx, N, K, z); if (List) List->Add(z, 2);} \
xue@1 277 for (int n=0; n<N; n++) for (int k=0; k<K; k++){ \
xue@1 278 Tx zz=0; for (int m=0; m<M; m++) zz+=xx*yy; z[n][k]=zz;} return z;} \
xue@1 279 template<class Tx, class Ty>Tx** MULTIPLY(int N, int M, int K, Tx** x, Ty** y, MList* List=0){ \
xue@1 280 Tx** Allocate2(Tx, N, K, z); if (List) List->Add(z, 2); \
xue@1 281 for (int n=0; n<N; n++) for (int k=0; k<K; k++){ \
xue@1 282 Tx zz=0; for (int m=0; m<M; m++) zz+=xx*yy; z[n][k]=zz;} return z;} \
xue@1 283 template<class Tx, class Ty>void MULTIADD(int N, int M, int K, Tx** z, Tx** x, Ty** y){ \
xue@1 284 for (int n=0; n<N; n++) for (int k=0; k<K; k++){ \
xue@1 285 Tx zz=0; for (int m=0; m<M; m++) zz+=xx*yy; z[n][k]+=zz;}}
xue@1 286 Multiply_full(MultiplyXY, MultiAddXY, x[n][m], y[m][k]) //z[N][K]=x[N][M]y[M][K], identical z and x or y not allowed
xue@1 287 Multiply_full(MultiplyXYc, MultiAddXYc, x[n][m], *y[m][k]) //z[N][K]=x[N][M](y*)[M][K], identical z and x or y not allowed
xue@1 288 Multiply_full(MultiplyXYt, MultiAddXYt, x[n][m], y[k][m]) //z[N][K]=x[N][M]Yt[M][K], identical z and x or y not allowed
xue@1 289 Multiply_full(MultiplyXYh, MultiAddXYh, x[n][m], *y[k][m]) //z[N][K]=x[N][M](Yt*)[M][K], identical z and x or y not allowed
xue@1 290
xue@1 291 /*
xue@1 292 macro Multiply_square: square matrix multiplication z=xy and multiplication-accumulation z=z+xy.
xue@1 293 Identical z and x allowed for multiplication but not for multiplication-accumulation.
xue@1 294
xue@1 295 Each expansion of the macro defines three function templates; two are named $MULTIPLY and do matrix
xue@1 296 multiplication only; one is named $MULTIADD and accumulates the multiplicated result on top of a
xue@1 297 specified matrix. One of the two $MULTIPLY functions allows using a pre-allocated matrix to accept
xue@1 298 the matrix product, while the other directly allocates a new matrix and returns the pointer.
xue@1 299 */
xue@1 300 #define Multiply_square(MULTIPLY, MULTIADD) \
xue@1 301 template<class T>T** MULTIPLY(int N, T** z, T** x, T** y, MList* List=0){ \
xue@1 302 if (!z){Allocate2(T, N, N, z); if (List) List->Add(z, 2);} \
xue@1 303 if (z!=x) MULTIPLY(N, N, N, z, x, y); else{ \
xue@1 304 T* tmp=new T[N]; int sizeN=sizeof(T)*N; for (int i=0; i<N; i++){ \
xue@1 305 MULTIPLY(1, N, N, &tmp, &x[i], y); memcpy(z[i], tmp, sizeN);} delete[] tmp;} \
xue@1 306 return z;} \
xue@1 307 template<class T>T** MULTIPLY(int N, T** x, T** y, MList* List=0){return MULTIPLY(N, N, N, x, y, List);}\
xue@1 308 template<class T>void MULTIADD(int N, T** z, T** x, T** y){MULTIADD(N, N, N, z, x, y);}
xue@1 309 Multiply_square(MultiplyXY, MultiAddXY)
xue@1 310
xue@1 311 /*
xue@1 312 macro Multiply_xx: matrix self multiplication z=xx and self-multiplication-accumulation z=z+xx.
xue@1 313
xue@1 314 Each expansion of the macro defines three function templates; two are named $MULTIPLY and do matrix
xue@1 315 multiplication only; one is named $MULTIADD and accumulates the multiplicated result on top of a
xue@1 316 specified matrix. One of the two $MULTIPLY functions allows using a pre-allocated matrix to accept
xue@1 317 the matrix product, while the other directly allocates a new matrix and returns the pointer.
xue@1 318 */
xue@1 319 #define Multiply_xx(MULTIPLY, MULTIADD, xx1, xx2, zzt) \
xue@1 320 template<class T>T** MULTIPLY(int M, int N, T** z, T** x, MList* List=0){ \
xue@1 321 if (!z){Allocate2(T, M, M, z); if (List) List->Add(z, 2);} \
xue@1 322 for (int m=0; m<M; m++) for (int k=0; k<=m; k++){ \
xue@1 323 T zz=0; for (int n=0; n<N; n++) zz+=xx1*xx2; z[m][k]=zz; if (m!=k) z[k][m]=zzt;} \
xue@1 324 return z;} \
xue@1 325 template<class T>T** MULTIPLY(int M, int N, T ** x, MList* List=0){ \
xue@1 326 T** Allocate2(T, M, M, z); if (List) List->Add(z, 2); \
xue@1 327 for (int m=0; m<M; m++) for (int k=0; k<=m; k++){ \
xue@1 328 T zz=0; for (int n=0; n<N; n++) zz+=xx1*xx2; z[m][k]=zz; if (m!=k) z[k][m]=zzt;} \
xue@1 329 return z;} \
xue@1 330 template<class T>void MULTIADD(int M, int N, T** z, T** x){ \
xue@1 331 for (int m=0; m<M; m++) for (int k=0; k<=m; k++){ \
xue@1 332 T zz=0; for (int n=0; n<N; n++) zz+=xx1*xx2; z[m][k]+=zz; if (m!=k) z[k][m]+=zzt;}}
xue@1 333 Multiply_xx(MultiplyXtX, MultiAddXtX, x[n][m], x[n][k], zz) //z[M][M]=xt[M][N]x[N][M], identical z and x NOT ALLOWED.
xue@1 334 Multiply_xx(MultiplyXXt, MultiAddXXt, x[m][n], x[k][n], zz) //z[M][M]=X[M][N]xt[N][M], identical z and x NOT ALLOWED.
xue@1 335 Multiply_xx(MultiplyXhX, MultiAddXhX, *x[n][m], x[n][k], *zz) //z[M][M]=(xt*)[M][N]x[N][M], identical z and x NOT ALLOWED.
xue@1 336 Multiply_xx(MultiplyXXh, MultiAddXXh, x[m][n], *x[k][n], *zz) //z[M][M]=x[M][N](xt*)[N][M], identical z and x NOT ALLOWED.
xue@1 337 Multiply_xx(MultiplyXcXt, MultiAddXcXt, *x[m][n], x[k][n], *zz) //z[M][M]=(x*)[M][N]xt[N][M], identical z and x NOT ALLOWED.
xue@1 338
xue@1 339 //matrix-vector multiplication routines
xue@1 340 double* MultiplyXy(int M, int N, double* z, double** x, double* y, MList* List=0);
xue@1 341 double* MultiplyXy(int M, int N, double** x, double* y, MList* List=0);
xue@1 342 cdouble* MultiplyXy(int M, int N, cdouble* z, cdouble** x, cdouble* y, MList* List=0);
xue@1 343 cdouble* MultiplyXy(int M, int N, cdouble** x, cdouble* y, MList* List=0);
xue@1 344 cdouble* MultiplyXy(int M, int N, cdouble* z, double** x, cdouble* y, MList* List=0);
xue@1 345 cdouble* MultiplyXy(int M, int N, double** x, cdouble* y, MList* List=0);
xue@1 346 double* MultiplyxY(int M, int N, double* zt, double* xt, double** y, MList* List=0);
xue@1 347 double* MultiplyxY(int M, int N, double* xt, double** y, MList* List=0);
xue@1 348 cdouble* MultiplyxY(int M, int N, cdouble* zt, cdouble* xt, cdouble** y, MList* List=0);
xue@1 349 cdouble* MultiplyxY(int M, int N, cdouble* xt, cdouble** y, MList* List=0);
xue@1 350 double* MultiplyXty(int M, int N, double* z, double** x, double* y, MList* List=0);
xue@1 351 double* MultiplyXty(int M, int N, double** x, double* y, MList* List=0);
xue@1 352 cdouble* MultiplyXty(int M, int N, cdouble* z, cdouble** x, cdouble* y, MList* List=0);
xue@1 353 cdouble* MultiplyXty(int M, int N, cdouble** x, cdouble* y, MList* List=0);
xue@1 354 cdouble* MultiplyXhy(int M, int N, cdouble* z, cdouble** x, cdouble* y, MList* List=0);
xue@1 355 cdouble* MultiplyXhy(int M, int N, cdouble** x, cdouble* y, MList* List=0);
xue@1 356 cdouble* MultiplyXcy(int M, int N, cdouble* z, cdouble** x, cfloat* y, MList* List=0);
xue@1 357 cdouble* MultiplyXcy(int M, int N, cdouble** x, cfloat* y, MList* List=0);
xue@1 358 cdouble* MultiplyXcy(int M, int N, cdouble* z, cdouble** x, cdouble* y, MList* List=0);
xue@1 359 cdouble* MultiplyXcy(int M, int N, cdouble** x, cdouble* y, MList* List=0);
xue@1 360 double* MultiplyxYt(int M, int N, double* zt, double* xt, double** y, MList* MList=0);
xue@1 361 double* MultiplyxYt(int M, int N, double* xt, double** y, MList* MList=0);
xue@1 362
xue@1 363 //--matrix norms-------------------------------------------------------------
xue@1 364 double Norm1(int N, double** A);
xue@1 365
xue@1 366 //--QR factorization---------------------------------------------------------
xue@1 367 void QR_GS(int M, int N, double** A, double** Q, double** R);
xue@1 368 void QR_householder(int M, int N, double** A, double** Q, double** R);
xue@1 369
xue@1 370 //--QR factorization of a tridiagonal matrix---------------------------------
xue@1 371 int QL(int N, double* d, double* sd, double** z);
xue@1 372 int QR(int N, double **A, cdouble* ev);
xue@1 373
xue@1 374 //--QU factorization of a matrix---------------------------------------------
xue@1 375 void QU(int N, double** Q, double** A);
xue@1 376
xue@1 377 //--Extract the real part----------------------------------------------------
xue@1 378 double** Real(int M, int N, double** z, cdouble** x, MList* List);
xue@1 379 double** Real(int M, int N, cdouble** x, MList* List);
xue@1 380
xue@1 381 //--Finding roots of real polynomials----------------------------------------
xue@1 382 int Roots(int N, double* p, double* rr, double* ri);
xue@1 383
xue@1 384 //--Sor iterative method for solving linear systems--------------------------
xue@1 385 int SorI(int N, double* x0, double** a, double* b, double w=1, double ep=1e-4, int maxiter=50);
xue@1 386
xue@1 387 //--Submatrix----------------------------------------------------------------
xue@1 388 void SetSubMatrix(double** z, double** x, int Y1, int Y, int X1, int X);
xue@1 389 void SetSubMatrix(cdouble** z, cdouble** x, int Y1, int Y, int X1, int X);
xue@1 390 cdouble** SubMatrix(cdouble** z, cdouble** x, int Y1, int Y, int X1, int X, MList* List=0);
xue@1 391 cdouble** SubMatrix(cdouble** x, int Y1, int Y, int X1, int X, MList* List=0);
xue@1 392 cdouble* SubVector(cdouble* z, cdouble* x, int X1, int X, MList* List=0);
xue@1 393 cdouble* SubVector(cdouble* x, int X1, int X, MList* List=0);
xue@1 394
xue@1 395 //--matrix transpose operation-----------------------------------------------
xue@1 396 void transpose(int N, double** a);
xue@1 397 void transpose(int N, cdouble** a);
xue@1 398 double** transpose(int N, int M, double** ta, double** a, MList* List=0); //z[NM]=a[MN]'
xue@1 399 double** transpose(int N, int M, double** a, MList* List=0);
xue@1 400
xue@1 401 //--rotation matrix converting between vectors-------------------------------
xue@1 402 double** Unitary(int N, double** P, double* x, double* y, MList* List=0);
xue@1 403 double** Unitary(int N, double* x, double* y, MList* List=0);
xue@1 404 cdouble** Unitary(int N, cdouble** P, cdouble* x, cdouble* y, MList* List=0);
xue@1 405 cdouble** Unitary(int N, cdouble* x, cdouble* y, MList* List=0);
xue@1 406
xue@1 407 #endif