Dacus
08-29-2003, 07:07 AM
Hello,
Does somebody know where I can find the QR decomposition algorithm for rectangular matrices (using householder transformations)?
In "Numerical Recipes in C" only the particular case of a square matrix is given ... :confused:
Thx in advance,
Dacian
dacian.hantig@siemensvdo.com
boring7fordy7
09-11-2003, 09:12 AM
very funny
what do you think the R stands for?i
Dacus
09-12-2003, 01:37 AM
R stands for the upper-triangle matrix ...
But what this has to do with the A being a rectangular matrix instead of a square one?
Dacian
boring7fordy7
09-18-2003, 04:39 AM
hehehe i missread it :O)
but if you look at the SVD you find there a part of calculating QR for a non square Matrix.
Dacus
09-18-2003, 04:42 AM
Maybe, but I need householder as the method of obtaining the QR decomposition :(
TMcCloskey
09-18-2003, 11:12 AM
Check out LINPACK or/and LAPACK sources
boring7fordy7
09-20-2003, 03:11 AM
Originally posted by Dacus
Maybe, but I need householder as the method of obtaining the QR decomposition :(
they there use first housholder to QR and then use some Givens Rotations to get the triangular thing diagonalized.
DimpleB
12-10-2012, 10:08 AM
#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 Qk and Qk ? 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;
}
DimpleB
12-10-2012, 10:10 AM
this code works for all matrices
m==n
m<n
m>n