16 double **mat,
const unsigned int rows,
const unsigned int cols,
17 unsigned int row_pos,
unsigned int *p,
unsigned int *max_loc
20 unsigned int *p,
const unsigned int i,
const unsigned int j
23 double **mat,
const unsigned int rows,
const unsigned int cols,
24 const unsigned int row_pos,
const unsigned int col_pos,
double *result
26void qr_apply_householder(
27 double **mat,
double *rhs,
const unsigned int rows,
const unsigned int cols,
28 double *house,
const unsigned int row_pos,
unsigned int *p
31 double **mat,
double *rhs,
const unsigned int rows,
const unsigned int cols,
32 double *sol,
unsigned int *p
64 const unsigned int rows,
66 const unsigned int cols,
71 if(rows<1 || cols<1)
return(1);
72 if(mat==NULL || rhs==NULL || sol==NULL)
return(2);
74 unsigned int i, j, max_loc;
76 double *buf=NULL, *ptr, *v=NULL, *orig_b=NULL, **A=NULL;
80 p=malloc(
sizeof(
unsigned int)*cols);
81 A=malloc(
sizeof(
double*)*rows);
82 buf=malloc(
sizeof(
double)*(rows*cols+rows+rows));
83 if(p==NULL || A==NULL || buf==NULL) {
84 free(p); free(A); free(buf);
88 for(i=0; i<rows; i++) {A[i]=ptr; ptr+=cols;}
89 v=ptr; ptr+=rows; orig_b=ptr;
91 for(i=0; i<rows; i++) {
93 for(j=0; j<cols; j++) A[i][j]=mat[i][j];
97 for(i=0; i<cols; i++) p[i]=i;
100 for(i=0; i<cols; i++) {
101 if(qr_get_next_col(A, rows, cols, i, p, &max_loc)==0)
102 qr_swap_cols(p, i, max_loc);
103 qr_householder(A, rows, cols, i, p[i], v);
104 qr_apply_householder(A, rhs, rows, cols, v, i, p);
108 qr_back_solve(A, rhs, rows, cols, sol, p);
111 for(i=0; i<rows; i++) {
113 for(j=0; j<cols; j++) rhs[i]+=mat[i][j]*sol[j];
119 for(i=0; i<rows; i++) {
127 free(p); free(A); free(buf);
139 const unsigned int rows,
141 const unsigned int cols,
143 const unsigned int row_pos,
147 unsigned int *max_loc
149 if(mat==NULL || rows<1 || cols<1 || p==NULL)
return(-1);
151 unsigned int i, j, maxloc;
152 double col_norm, max_norm;
155 max_norm=DBL_MIN; maxloc=0;
156 for(j=0; j<cols; j++) {
158 for(i=row_pos; i<rows; i++) col_norm+=mat[i][p[j]]*mat[i][p[j]];
159 if(col_norm>max_norm) {max_norm=col_norm; maxloc=j;}
161 if(max_norm!=DBL_MIN) {
162 if(max_loc!=NULL) *max_loc=maxloc;
169void qr_swap_cols(
unsigned int *p,
const unsigned int i,
const unsigned int j)
172 temp=p[i]; p[i]=p[j]; p[j]=temp;
180 const unsigned int rows,
182 const unsigned int cols,
184 const unsigned int row_pos,
186 const unsigned int col_pos,
190 if(rows<1 || cols<1 || mat==NULL || result==NULL)
return;
195 for(i=row_pos; i<rows; i++) norm+=mat[i][col_pos]*mat[i][col_pos];
196 if(norm==0.0)
return;
199 result[0]=(mat[row_pos][col_pos]-norm);
200 for(i=1; i<(rows-row_pos); i++) result[i]=mat[i+row_pos][col_pos];
203 for(i=0; i<(rows-row_pos); i++) norm+=result[i]*result[i];
207 for(i=0; i<(rows-row_pos); i++) result[i]*=(1.0/norm);
211void qr_apply_householder(
217 const unsigned int rows,
219 const unsigned int cols,
223 const unsigned int row_pos,
227 if(mat==NULL || rhs==NULL || rows<1 || cols<1 || house==NULL || p==NULL)
return;
229 unsigned int i, j, k, n;
239 hhmat=malloc(
sizeof(
double*)*n);
240 for(i=0; i<n; i++) hhmat[i]=malloc(
sizeof(
double)*n);
241 mat_cpy=malloc(
sizeof(
double*)*rows);
242 for(i=0; i<rows; i++) mat_cpy[i]=malloc(
sizeof(
double)*cols);
243 rhs_cpy=malloc(
sizeof(
double)*rows);
246 for(i=0; i<rows; i++)
247 for(j=0; j<cols; j++)
248 mat_cpy[i][j]=mat[i][j];
251 for(i=0; i<rows; i++) rhs_cpy[i]=rhs[i];
256 if(i!=j) hhmat[i][j]=-2.0*house[j]*house[i];
257 else hhmat[i][j]=1.0-2.0*house[j]*house[i];
260 for(k=0; k<cols; k++)
263 for(i=0; i<n; i++) sum+=hhmat[j][i]*mat_cpy[i+row_pos][p[k]];
264 mat[j+row_pos][p[k]]=sum;
270 for(i=0; i<n; i++) sum+=hhmat[i][j]*rhs_cpy[i+row_pos];
275 for(i=0; i<(rows-row_pos); i++) free(hhmat[i]);
276 for(i=0; i<rows; i++) free(mat_cpy[i]);
289 const unsigned int rows,
291 const unsigned int cols,
297 if(mat==NULL || rhs==NULL || rows<1 || cols<1 || sol==NULL || p==NULL)
300 unsigned int i, j, bottom;
304 for(i=0; i<cols; i++) sol[i]=0.0;
309 if(fabs(mat[i][p[cols-1]]) > 2.0*DBL_MIN) {bottom=i;
break;}
310 if(i==0)
break;
else i--;
319 if(j>i) sum+=sol[p[j]]*mat[i][p[j]];
320 if(j==0)
break;
else j--;
323 if(mat[i][p[i]] > 2.0*DBL_MIN) sol[p[i]]=(rhs[i]-sum)/mat[i][p[i]];
326 if(i==0)
break;
else i--;
373 double *qrRes, *qrTau, **qrWws, *qrWs, *chain;
376 if(m<=0 || n<=0 || A==NULL || B==NULL || X==NULL)
return(1);
380 if(tau!=NULL) qrTau=tau;
else qrTau=(
double*)calloc(n,
sizeof(
double));
381 if(res!=NULL) qrRes=res;
else qrRes=(
double*)calloc(m,
sizeof(
double));
383 qrWws=wws; chain=(
double*)NULL;
385 qrWws=(
double**)malloc(m *
sizeof(
double*));
386 chain=(
double*)malloc(m*n *
sizeof(
double));
387 for(i=0; i<m; i++) qrWws[i]=chain + i*n;
389 if(ws!=NULL) qrWs=ws;
else qrWs=(
double*)calloc(2*m,
sizeof(
double));
390 if(qrTau==NULL || qrRes==NULL || qrWws==NULL || qrWs==NULL)
return(1);
393 if(
qr_decomp(A, m, n, qrTau, qrWws, qrWs))
return(2);
394 if(
qr_solve(A, m, n, qrTau, B, X, qrRes, rnorm, qrWws, qrWs))
return(3);
397 if(tau==NULL) free(qrTau);
398 if(res==NULL) free(qrRes);
399 if(wws==NULL) {free(qrWws); free(chain);}
400 if(ws==NULL) free(qrWs);
401 for(i=0; i<n; i++)
if(isnan(X[i]))
return(4);
443 double *subvector, **submatrix;
446 if(M<N) MNmin=M;
else MNmin=N;
447 if(MNmin<1 || a==NULL || tau==NULL || cchain==NULL || chain==NULL)
return(1);
452 for(i=0; i<MNmin; i++) {
457 for(m=i; m<M; m++) subvector[m-i]=a[m][i];
459 for(m=i; m<M; m++) a[m][i]=subvector[m-i];
465 submatrix[m-i][n-i-1]=a[m][n];
466 if(
householder_hm(tau[i], subvector, submatrix, M-i, N-i))
return(2);
469 a[m][n]=submatrix[m-i][n-i-1];
515 if(QR==NULL || tau==NULL || b==NULL || x==NULL || residual==NULL)
return(1);
516 if(cchain==NULL || chain==NULL)
return(1);
517 if(M<1 || N<1)
return(2);
519 int MNmin;
if(M<N) MNmin=M;
else MNmin=N;
522 double **Rmatrix=cchain;
528 for(m=0; m<N; m++)
for(n=0; n<N; n++) Rmatrix[m][n]=QR[m][n];
529 for(m=0; m<M; m++) residual[m]=b[m];
534 for(
int i=0; i<MNmin; i++) {
535 for(m=i; m<M; m++) h[m-i]=QR[m][i];
536 for(m=i; m<M; m++) w[m-i]=residual[m];
538 for(m=i; m<M; m++) residual[m]=w[m-i];
542 for(n=0; n<N; n++) x[n]=residual[n];
544 x[N-1]=x[N-1]/Rmatrix[N-1][N-1];
545 for(
int i=N-2; i>=0; i--) {
546 for(
int j=i+1; j<N; j++) x[i]-=Rmatrix[i][j]*x[j];
551 for(n=0; n<N; n++) residual[n]=0.0;
555 for(
int i=MNmin-1; i>=0; i--) {
556 for(
int m=i; m<M; m++) h[m-i]=QR[m][i];
557 for(
int m=i; m<M; m++) w[m-i]=residual[m];
559 for(
int m=i; m<M; m++) residual[m]=w[m-i];
564 for(m=0, *resNorm=0.0; m<M; m++) *resNorm +=residual[m]*residual[m];
595 if(N<1 || M<1 || A==NULL || b==NULL || weight==NULL)
return(1);
599 w=(
double*)malloc(M*
sizeof(
double));
if(w==NULL)
return(2);
606 if(weight[m]<=1.0e-100) w[m]=1.0e-50;
607 else w[m]=sqrt(weight[m]);
612 for(n=0; n<N; n++) A[m][n]*=w[m];
616 if(ws==NULL) free(w);
635 const unsigned int m,
638 const unsigned int n,
652 if(a==NULL || b==NULL || x==NULL || r2==NULL)
return(2);
653 if(n<1 || m<n) {*r2=nan(
"");
return(2);}
656 for(
unsigned int ni=0; ni<n; ni++) x[ni]=0.0;
660 for(
unsigned int ni=0; ni<n; ni++) {
663 for(
unsigned int mi=ni; mi<m; mi++) sq+=a[mi + ni*m]*a[mi + ni*m];
664 if(sq==0.0)
return(1);
665 double qv1=-copysign(sqrt(sq), a[ni + ni*m]);
666 double u1=a[ni + ni*m] - qv1;
668 unsigned int ni1=ni+1;
670 for(
unsigned int nj=ni1; nj<n; nj++) {
671 double dot=u1*a[ni + nj*m];
672 for(
unsigned int mi=ni1; mi<m; mi++)
673 dot+=a[mi + nj*m] * a[mi + ni*m];
674 double c=dot/fabs(qv1*u1);
675 for(
unsigned int mi=ni1; mi<m; mi++)
676 a[mi + nj*m]-=c*a[mi + ni*m];
681 for(
unsigned int mi=ni1; mi<m; mi++)
682 dot+=b[mi]*a[mi + ni*m];
683 double c=dot/fabs(qv1*u1);
685 for(
unsigned int mi=ni1; mi<m; mi++)
686 b[mi]-=c*a[mi + ni*m];
690 for(
unsigned int ni=0; ni<n; ni++) {
693 for(
unsigned int nj=k+1; nj<n; nj++)
694 s-=a[k + nj*m] * x[nj];
695 if(a[k + k*m]==0.0)
return(1);
701 for(
unsigned int mi=n; mi<m; mi++)
int householder_hv(double tau, int size, double *v, double *w)
int householder_hm(double tau, double *vector, double **matrix, int rowNr, int columnNr)
double householder_transform(double *v, int N)
Header file for libtpcmodel.
int qrLH(const unsigned int m, const unsigned int n, double *a, double *b, double *x, double *r2)
Solve over-determined least-squares problem A x ~ b using successive Householder rotations.
int qr_weight(int N, int M, double **A, double *b, double *weight, double *ws)
int qrLSQ(double **mat, double *rhs, double *sol, const unsigned int rows, const unsigned int cols, double *r2)
QR least-squares solving routine.
int qr_solve(double **QR, int M, int N, double *tau, double *b, double *x, double *residual, double *resNorm, double **cchain, double *chain)
int qr(double **A, int m, int n, double *B, double *X, double *rnorm, double *tau, double *res, double **wws, double *ws)
int qr_decomp(double **a, int M, int N, double *tau, double **cchain, double *chain)