Householder Qr Zerlegung
-
Hi!
Ich habe hier einen Code für eine QR Householder Zerlegung. Er funktioniert auch. Ich vestehe jedoch die scale Variable nicht.
Für was braucht man die hier oder besser, was macht sie hier? (Zeile 115)#include <stdio.h> #include <stdlib.h> #include <math.h> #define SIGN(a,b) ((b) > 0.0 ? fabs(a) : - fabs(a)) static double maxarg1,maxarg2; #define FMAX(a,b) (maxarg1 = (a),maxarg2 = (b),(maxarg1) > (maxarg2) ? (maxarg1) : (maxarg2)) static double sqrarg; #define SQR(a) ((sqrarg = (a)) == 0.0 ? 0.0 : sqrarg * sqrarg) //Global Variables double **a; //Matrix whose SVD needs to be found double *c; double *d; //Function int qrdcmp(double **a, int m, int n, double *c, double *d); int main (void) { int m, n; int i, j; printf("Enter the parameters for a square matrix(A)\n"); scanf("%d%d", &m, &n); //Assigning A matrix a = malloc(sizeof (double*)*m); //allocate M rows to dmatrix for (i =0; i < m; i++) {a[i] = malloc (sizeof (double)*n);} // Now for each row, allocate N actual floats // From this step we have a matrix of M rows and N columns worth of floats printf("Enter the elements of an array\n"); //2D array in effect for (i =0; i < m; i++) { for (j =0; j<n; j++) { scanf("%lf", &a[i][j]); } } //Assigning w matrix n printf("\n"); printf("A matrix\n"); for (i =0; i < m; i++) { for (j =0; j< n; j++) { printf("%9.4lf\t",a[i][j]); } printf("\n"); } c = malloc(sizeof(double)*n); d = malloc(sizeof(double)*n); for (i=0; i<n; i++) { c[i] = 0.0; d[i] = 0.0; } qrdcmp (a,m,n,c,d); double R[m][n]; for (i =0; i < m; i++) { for (j=0; j <n; j++) { if (i == j) {R[i][i] = d[i];} else if ( i < j) {R[i][j] = a[i][j];} else {R[i][j] = 0;} } } printf("\n"); printf("R decomposition of a matrix:\n"); for (i =0; i <m; i++) { for (j =0; j<n; j++) { printf("%9.4lf\t",R[i][j]); } printf("\n"); } getch(); } int qrdcmp(double **a, int m, int n, double *c, double *d) /*Constructs the QR decomposition of a[1..n][1..n]. The upper triangular matrix R is returned in the upper triangle of a, except for the diagonal elements of R which are returned in d[1..n]. The orthogonal matrix Q is represented as a product of n - 1 Householder matrices Q1 . . . Qn-1 , where Qj = 1 - uj ? uj /cj . The ith component of uj is zero for i = 1, . . . , j - 1 while the nonzero components are returned in a[i][j] for i = j, . . . , n. sing returns as true (1) if singularity is encountered during the decomposition, but the decomposition is still completed in this case; otherwise it returns false (0).*/ { int i,j,k; double scale,sigma,sum,tau; scale = sigma = sum = tau =0.0; i=j=k=0; int min; if (m >= n) {min = n;} else {min = m;} for (k =0;k < min;k++) { //printf("K =%d \n N = %d\n", k, n); //for (i=k;i<n;i++) scale=FMAX(scale,fabs(a[i][k])); for (i=k;i<m;i++) scale=FMAX(scale,fabs(a[i][k])); //printf ("scale %lf\n", scale); if (scale == 0.0) { //Singular case. c[k]=d[k]=0.0; } else { //Form Q_k and Q_k * A. //for (i=k;i<n;i++) for (i=k;i<m;i++) {a[i][k] /= scale;} //printf ("a[%d][%d] = %lf\n",i,k, a[i][k]);} //orgfor (sum=0.0,i=k;i<n;i++) for (sum=0.0,i=k;i<m;i++) {sum += SQR(a[i][k]);} //printf ("Sum = %lf\n",sum); sigma=SIGN(sqrt(sum),a[k][k]); //printf ("sigma = %lf\n", sigma); a[k][k] += sigma; //printf ("a[%d][%d]= %lf\n",k ,k, a[k][k]); c[k]=sigma*a[k][k]; //printf ("c[%d] = %lf\n", k,c[k]); d[k] = -scale*sigma; printf ("d[%d] = %lf\n", k,d[k]); for (j=k+1;j < n;j++) { //printf("j=%d\n",j); //orgfor (sum=0.0,i=k;i<n;i++) for (sum=0.0,i=k;i<m;i++) {sum += a[i][k]*a[i][j]; //printf("sum = %lf, a[%d][%d] = %lf, a[%d][%d]=%lf\n",sum, i, k, a[i][k], i, j, a[i][j]); } //printf("sum = %lf\n",sum); tau=sum/c[k]; //printf("tau= %lf\n",tau); //org for (i=k;i<n;i++) for (i=k;i<m;i++) { a[i][j] -= tau*a[i][k]; // printf("a[%d][%d] = %lf\n", i, j, a[i][j]); } } } } return 0; }