TPCCLIB
Loading...
Searching...
No Matches
hholder.c File Reference

Implementation and use of Householder transform. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "tpcextensions.h"
#include "tpclinopt.h"

Go to the source code of this file.

Functions

double householder_transform (double *v, int N)
int householder_hm (double tau, double *vector, double **matrix, int rowNr, int columnNr)
int householder_hv (double tau, int size, double *v, double *w)
double householder_norm (double *v, int size)

Detailed Description

Implementation and use of Householder transform.

Author
Kaisa Liukko, Vesa Oikonen

These routines are based on the code provided in the GSL library (https://sources.redhat.com/gsl/).

Todo
Use const variables when possible.

Definition in file hholder.c.

Function Documentation

◆ householder_hm()

int householder_hm ( double tau,
double * vector,
double ** matrix,
int rowNr,
int columnNr )

Applies a householder transformation defined by vector "vector" and scalar tau to the left-hand side of the matrix. (I - tau vector vector^T)*matrix The result of the transform is stored in matrix.

Returns
Returns 0 if ok.
Parameters
tauCoefficient defining householder transform.
vectorVector defining householder transform (of size rowNr).
matrixthe matrix that is to be transformed.
rowNrNr of rows in matrix.
columnNrNr of columns in matrix.

Definition at line 87 of file hholder.c.

98 {
99 int i, j;
100 double wj;
101
102 if(tau==0.0) return(0); // success
103 if(rowNr<1 || columnNr<1) return(1);
104 for(j=0; j<columnNr; j++) {
105 /* Compute wj = vk Akj */
106 wj=matrix[0][j];
107 for(i=1; i<rowNr; i++) /* note, computed for v(0) = 1 above */
108 wj += vector[i]*matrix[i][j];
109 /* Aij = Aij - tau vi wj */
110 /* i = 0 */
111 matrix[0][j]-=tau*wj;
112 /* i = 1 .. M-1 */
113 for(i=1; i<rowNr; i++) matrix[i][j]-=tau*vector[i]*wj;
114 }
115 return(0);
116}

Referenced by qr_decomp().

◆ householder_hv()

int householder_hv ( double tau,
int size,
double * v,
double * w )

Applies a householder transformation defined by vector v and coefficient tau to vector w w = (I - tau v v^T) w.

Returns
Returns 0 if ok.
Parameters
tauCoefficient defining householder transform.
sizeSize of vectors v and w.
vVector v.
wVector w.

Definition at line 126 of file hholder.c.

135 {
136 int i;
137 double d;
138
139 if(tau==0) return(0); // success
140 if(size<1) return(1);
141 /* d = v'w */
142 d=w[0]; for(i=1; i<size; i++) d+=v[i]*w[i];
143 /* w = w - tau (v) (v'w) */
144 w[0]-=tau*d;
145 for(i=1; i<size; i++) w[i]-=tau*v[i]*d;
146 return(0);
147}

◆ householder_norm()

double householder_norm ( double * v,
int size )

Calculates the euclidean norm of vector v[].

Returns
Returns the euclidean norm of a vector.
Parameters
vVector v.
sizeSize of vector v[].

Definition at line 155 of file hholder.c.

160 {
161 double ss=0.0;
162 int i;
163
164 for(i=0; i<size; i++) ss+=v[i]*v[i];
165 return sqrt(ss);
166}

◆ householder_transform()

double householder_transform ( double * v,
int N )

This function prepares a Householder transformation P = I - tau h h^T which can be used to zero all the elements of the input vector except the first one that will get value beta. On output the elements 1 - size-1 of the vector h are stored in locations vector[1] - vector[size-1] of the input vector and value of beta is stored in location vector[0].

Returns
The scalar tau is returned.
Parameters
vThe N-vector to be transformed.
Nsize of the vector.

Definition at line 33 of file hholder.c.

38 {
39 double vnorm, alpha, beta, tau;
40 int n;
41
42 if(N<1) return 0.0; // tau = 0
43 /* Euclidean norm of the vector starting from the second value */
44 vnorm=0.0; for(n=1; n<N; n++) vnorm+=v[n]*v[n];
45 vnorm=sqrt(vnorm); if(isnan(vnorm) || vnorm==0.0) return 0.0; // tau = 0
46
47 /* Computing the coefficient tau */
48 alpha=v[0];
49 beta= - (alpha >= 0.0 ? +1.0 : -1.0) * hypot(alpha, vnorm);
50 tau=(beta-alpha)/beta ;
51
52 /* Scale the Householder vector so that the first element will be 1.
53 * (Scaling is also affecting the coefficient tau).
54 * Without scaling, the first element would have value (alpha - beta). */
55#if(0) // Kaisa's version
56 {
57 double os=1.0/(alpha-beta);
58 for(n=1; n<N; n++) v[n]*=os;
59 v[0]=beta;
60 }
61#else // Vesa's version
62 {
63 double s=alpha-beta;
64 if(fabs(s)>DBL_MIN) {
65 v[0]=beta;
66 for(n=1; n<N; n++) v[n]*=(1.0/s);
67 } else {
68 v[0]=beta;
69 for(n=1; n<N; n++) v[n]*=(doubleMachEps()/s);
70 for(n=1; n<N; n++) v[n]*=(1.0/doubleMachEps());
71 }
72 }
73#endif
74
75 return tau;
76}
double doubleMachEps()
Definition doubleutil.c:105

Referenced by qr_decomp().