7#include "tpcclibConfig.h"
22 double **mat,
const unsigned int rows,
const unsigned int cols,
23 unsigned int row_pos,
unsigned int *p,
unsigned int *max_loc
26 unsigned int *p,
const unsigned int i,
const unsigned int j
29 double **mat,
const unsigned int rows,
const unsigned int cols,
30 const unsigned int row_pos,
const unsigned int col_pos,
double *result
32void qr_apply_householder(
33 double **mat,
double *rhs,
const unsigned int rows,
const unsigned int cols,
34 double *house,
const unsigned int row_pos,
unsigned int *p
37 double **mat,
double *rhs,
const unsigned int rows,
const unsigned int cols,
38 double *sol,
unsigned int *p
44 int M,
int N,
double **QR,
double *tau,
double *v,
double *help
47 int M,
int N,
double **QR,
double *tau,
double *v,
double *help
50 int N,
double **A,
double *X
82 const unsigned int rows,
84 const unsigned int cols,
89 if(rows<1 || cols<1)
return(1);
90 if(mat==NULL || rhs==NULL || sol==NULL)
return(2);
92 unsigned int i, j, max_loc;
94 double *buf=NULL, *ptr, *v=NULL, *orig_b=NULL, **A=NULL;
98 p=malloc(
sizeof(
unsigned int)*cols);
99 A=malloc(
sizeof(
double*)*rows);
100 buf=malloc(
sizeof(
double)*(rows*cols+rows+rows));
101 if(p==NULL || A==NULL || buf==NULL) {
102 free(p); free(A); free(buf);
106 for(i=0; i<rows; i++) {A[i]=ptr; ptr+=cols;}
107 v=ptr; ptr+=rows; orig_b=ptr;
109 for(i=0; i<rows; i++) {
111 for(j=0; j<cols; j++) A[i][j]=mat[i][j];
115 for(i=0; i<cols; i++) p[i]=i;
118 for(i=0; i<cols; i++) {
119 if(qr_get_next_col(A, rows, cols, i, p, &max_loc)==0)
120 qr_swap_cols(p, i, max_loc);
121 qr_householder(A, rows, cols, i, p[i], v);
122 qr_apply_householder(A, rhs, rows, cols, v, i, p);
126 qr_back_solve(A, rhs, rows, cols, sol, p);
129 for(i=0; i<rows; i++) {
131 for(j=0; j<cols; j++) rhs[i]+=mat[i][j]*sol[j];
137 for(i=0; i<rows; i++) {
145 free(p); free(A); free(buf);
158 const unsigned int rows,
160 const unsigned int cols,
162 const unsigned int row_pos,
166 unsigned int *max_loc
168 if(mat==NULL || rows<1 || cols<1 || p==NULL)
return(-1);
170 unsigned int i, j, maxloc;
171 double col_norm, max_norm;
174 max_norm=DBL_MIN; maxloc=0;
175 for(j=0; j<cols; j++) {
177 for(i=row_pos; i<rows; i++) col_norm+=mat[i][p[j]]*mat[i][p[j]];
178 if(col_norm>max_norm) {max_norm=col_norm; maxloc=j;}
180 if(max_norm!=DBL_MIN) {
181 if(max_loc!=NULL) *max_loc=maxloc;
193 const unsigned int rows,
195 const unsigned int cols,
197 const unsigned int row_pos,
201 unsigned int *max_loc
203 if(mat==NULL || rows<1 || cols<1 || p==NULL)
return(-1);
205 unsigned int i, j, maxloc;
209 col_norms=malloc(
sizeof(
double)*cols);
212 for(j=0; j<cols; j++) {
214 for(i=row_pos; i<rows; i++) col_norms[j]+=mat[i][p[j]]*mat[i][p[j]];
218 max=DBL_MIN; maxloc=0;
219 for(i=0; i<cols; i++)
220 if(col_norms[i]>max) {max=col_norms[i]; maxloc=i;}
225 if(max_loc!=NULL) *max_loc=maxloc;
233void qr_swap_cols(
unsigned int *p,
const unsigned int i,
const unsigned int j)
236 temp=p[i]; p[i]=p[j]; p[j]=temp;
244 const unsigned int rows,
246 const unsigned int cols,
248 const unsigned int row_pos,
250 const unsigned int col_pos,
254 if(rows<1 || cols<1 || mat==NULL || result==NULL)
return;
259 for(i=row_pos; i<rows; i++) norm+=mat[i][col_pos]*mat[i][col_pos];
260 if(norm==0.0)
return;
263 result[0]=(mat[row_pos][col_pos]-norm);
264 for(i=1; i<(rows-row_pos); i++) result[i]=mat[i+row_pos][col_pos];
267 for(i=0; i<(rows-row_pos); i++) norm+=result[i]*result[i];
271 for(i=0; i<(rows-row_pos); i++) result[i]*=(1.0/norm);
275void qr_apply_householder(
281 const unsigned int rows,
283 const unsigned int cols,
287 const unsigned int row_pos,
291 if(mat==NULL || rhs==NULL || rows<1 || cols<1 || house==NULL || p==NULL)
return;
293 unsigned int i, j, k, n;
303 hhmat=malloc(
sizeof(
double*)*n);
304 for(i=0; i<n; i++) hhmat[i]=malloc(
sizeof(
double)*n);
305 mat_cpy=malloc(
sizeof(
double*)*rows);
306 for(i=0; i<rows; i++) mat_cpy[i]=malloc(
sizeof(
double)*cols);
307 rhs_cpy=malloc(
sizeof(
double)*rows);
310 for(i=0; i<rows; i++)
311 for(j=0; j<cols; j++)
312 mat_cpy[i][j]=mat[i][j];
315 for(i=0; i<rows; i++) rhs_cpy[i]=rhs[i];
320 if(i!=j) hhmat[i][j]=-2.0*house[j]*house[i];
321 else hhmat[i][j]=1.0-2.0*house[j]*house[i];
324 for(k=0; k<cols; k++)
327 for(i=0; i<n; i++) sum+=hhmat[j][i]*mat_cpy[i+row_pos][p[k]];
328 mat[j+row_pos][p[k]]=sum;
334 for(i=0; i<n; i++) sum+=hhmat[i][j]*rhs_cpy[i+row_pos];
339 for(i=0; i<(rows-row_pos); i++) free(hhmat[i]);
340 for(i=0; i<rows; i++) free(mat_cpy[i]);
353 const unsigned int rows,
355 const unsigned int cols,
361 if(mat==NULL || rhs==NULL || rows<1 || cols<1 || sol==NULL || p==NULL)
364 unsigned int i, j, bottom;
368 for(i=0; i<cols; i++) sol[i]=0.0;
373 if(fabs(mat[i][p[cols-1]]) > 2.0*DBL_MIN) {bottom=i;
break;}
374 if(i==0)
break;
else i--;
383 if(j>i) sum+=sol[p[j]]*mat[i][p[j]];
384 if(j==0)
break;
else j--;
387 if(mat[i][p[i]] > 2.0*DBL_MIN) sol[p[i]]=(rhs[i]-sum)/mat[i][p[i]];
390 if(i==0)
break;
else i--;
438 double *qrRes, *qrTau, **qrWws, *qrWs, *chain;
441 if(m<=0 || n<=0 || A==NULL || B==NULL || X==NULL)
return(1);
445 if(tau!=NULL) qrTau=tau;
else qrTau=(
double*)calloc(n,
sizeof(
double));
446 if(res!=NULL) qrRes=res;
else qrRes=(
double*)calloc(m,
sizeof(
double));
448 qrWws=wws; chain=(
double*)NULL;
450 qrWws=(
double**)malloc(m *
sizeof(
double*));
451 chain=(
double*)malloc(m*n *
sizeof(
double));
452 for(i=0; i<m; i++) qrWws[i]=chain + i*n;
454 if(ws!=NULL) qrWs=ws;
else qrWs=(
double*)calloc(2*m,
sizeof(
double));
455 if(qrTau==NULL || qrRes==NULL || qrWws==NULL || qrWs==NULL)
return(1);
458 if(
qr_decomp(A, m, n, qrTau, qrWws, qrWs))
return(2);
459 if(
qr_solve(A, m, n, qrTau, B, X, qrRes, rnorm, qrWws, qrWs))
return(3);
463 if(tau==NULL) free(qrTau);
464 if(res==NULL) free(qrRes);
465 if(wws==NULL) {free(qrWws); free(chain);}
466 if(ws==NULL) free(qrWs);
467 for(i=0; i<n; i++)
if(isnan(X[i]))
return(4);
509 double *subvector, **submatrix;
512 if(M<N) MNmin=M;
else MNmin=N;
513 if(MNmin<1 || a==NULL || tau==NULL || cchain==NULL || chain==NULL)
return(1);
517 for(i=0; i<MNmin; i++) {
524 subvector[m-i]=a[m][i];
527 for(m=i; m<M; m++) a[m][i]=subvector[m-i];
531 printf(
" apply transformation\n");
532 for(m=i; m<M; m++)
for(n=i+1; n<N; n++) {
533 if((m-i)<0 || (m-i)>=M || (n-i-1)<0 || (n-i-1)>=N) printf(
"OVERFLOW!\n");
534 submatrix[m-i][n-i-1]=a[m][n];
536 if(
householder_hm(tau[i], subvector, submatrix, M-i, N-i))
return(2);
537 for(m=i; m<M; m++)
for(n=i+1; n<N; n++)
538 a[m][n]=submatrix[m-i][n-i-1];
586 if(QR==NULL || tau==NULL || b==NULL || x==NULL || residual==NULL)
return(1);
587 if(cchain==NULL || chain==NULL)
return(1);
588 if(M<1 || N<1)
return(2);
598 for(m=0; m<N; m++)
for(n=0; n<N; n++) Rmatrix[m][n]=QR[m][n];
599 for(m=0; m<M; m++) residual[m]=b[m];
602 if(qr_QTvec(M, N, QR, tau, residual, chain))
return(3);
605 for(n=0; n<N; n++) x[n]=residual[n];
606 if(qr_invRvec(N, Rmatrix, x))
return(4);
609 for(n=0; n<N; n++) residual[n]=0.0;
611 if(qr_Qvec(M, N, QR, tau, residual, chain))
return(4);
615 for(m=0, *resNorm=0.0; m<M; m++) *resNorm +=residual[m]*residual[m];
646 if(M<N) MNmin=M;
else MNmin=N;
647 if(MNmin<1 || QR==NULL || tau==NULL || v==NULL || help==NULL)
return(1);
651 for(i=0; i<MNmin; i++) {
653 if((m-i)<0 || (m-i)>=M || (i)<0 || (i)>=N) printf(
"OVERFLOW!\n");
658 for(m=i; m<M; m++) v[m]=w[m-i];
688 if(M<N) MNmin=M;
else MNmin=N;
689 if(MNmin<1 || QR==NULL || tau==NULL || v==NULL || help==NULL)
return(1);
693 for(i=MNmin-1; i>=0; i--) {
695 if((m-i)<0 || (m-i)>=M || (i)<0 || (i)>=N) printf(
"OVERFLOW!\n");
700 for(m=i; m<M; m++) v[m]=w[m-i];
722 if(N<1 || A==NULL || X==NULL)
return(1);
725 X[N-1] = X[N-1]/A[N-1][N-1];
726 for(i=N-2; i>=0; i--) {
727 for(j=i+1, tmp=X[i]; j<N; j++) {
764 if(N<1 || M<1 || A==NULL || b==NULL || weight==NULL)
return(1);
768 w=(
double*)malloc(M*
sizeof(
double));
if(w==NULL)
return(2);
775 if(weight[m]<=1.0e-100) w[m]=1.0e-50;
776 else w[m]=sqrt(weight[m]);
781 for(n=0; n<N; n++) A[m][n]*=w[m];
785 if(ws==NULL) free(w);
816 if(N<1 || M<1 || weight==NULL)
return(1);
817 if(A==NULL && b==NULL)
return(0);
821 w=(
double*)malloc(M*
sizeof(
double));
if(w==NULL)
return(2);
828 if(weight[m]<=1.0e-100) w[m]=1.0e-50;
829 else w[m]=sqrt(weight[m]);
834 if(A!=NULL)
for(n=0; n<N; n++) A[m][n]/=w[m];
835 if(b!=NULL) b[m]/=w[m];
838 if(ws==NULL) free(w);
870 if(A==NULL || B==NULL || X==NULL || N<1 || M<N)
return(1);
872 const double closeZero=1.0E-20;
874 double cc[M], orig_B[M];
875 double p[M][N], c[M][N];
878 for(
int n=0; n<N; n++) {
879 for(
int nn=0; nn<n; nn++) p[nn][n]=0.0;
881 for(
int m=n; m<M; m++) p[n][n]+=A[m][n]*A[m][n];
882 p[n][n]=copysign(sqrt(p[n][n]), A[n][n]);
884 if(fabs(p[n][n])<closeZero)
return(2);
885 for(
int m=n+1; m<M; m++) p[m][n]=A[m][n];
887 for(
int m=n; m<M; m++) norm+=p[m][n]*p[m][n];
889 for(
int m=n; m<M; m++) p[m][n]/=norm;
890 for(
int m=n; m<M; m++) {
891 for(
int nn=n; nn<N; nn++) {
893 for(
int mm=n; mm<M; mm++) c[m][nn]-=2.0*p[m][n]*p[mm][n]*A[mm][nn];
896 for(
int m=n; m<M; m++)
897 for(
int nn=n; nn<N; nn++) A[m][nn]=c[m][nn];
901 for(
int m=0; m<M; m++) orig_B[m]=B[m];
904 for(
int n=0; n<N; n++) {
905 for(
int m=n; m<M; m++) {
907 for(
int mm=n; mm<M; mm++) cc[m]-=2.0*p[m][n]*p[mm][n]*B[mm];
909 for(
int m=n; m<M; m++) B[m]=cc[m];
913 X[N-1]=B[N-1]/A[N-1][N-1];
914 for(
int n=N-2; n>=0; n--) {
916 for(
int nn=n+1; nn<N; nn++) X[n]-=A[n][nn]*X[nn];
923 for(
int m=0; m<M; m++) {
948 const unsigned int m,
951 const unsigned int n,
965 if(a==NULL || b==NULL || x==NULL || r2==NULL)
return(2);
966 if(n<1 || m<n) {*r2=nan(
"");
return(2);}
969 for(
unsigned int ni=0; ni<n; ni++) x[ni]=0.0;
973 for(
unsigned int ni=0; ni<n; ni++) {
976 for(
unsigned int mi=ni; mi<m; mi++) sq+=a[mi + ni*m]*a[mi + ni*m];
977 if(sq==0.0)
return(1);
978 double qv1=-copysign(sqrt(sq), a[ni + ni*m]);
979 double u1=a[ni + ni*m] - qv1;
981 unsigned int ni1=ni+1;
983 for(
unsigned int nj=ni1; nj<n; nj++) {
984 double dot=u1*a[ni + nj*m];
985 for(
unsigned int mi=ni1; mi<m; mi++)
986 dot+=a[mi + nj*m] * a[mi + ni*m];
987 double c=dot/fabs(qv1*u1);
988 for(
unsigned int mi=ni1; mi<m; mi++)
989 a[mi + nj*m]-=c*a[mi + ni*m];
994 for(
unsigned int mi=ni1; mi<m; mi++)
995 dot+=b[mi]*a[mi + ni*m];
996 double c=dot/fabs(qv1*u1);
998 for(
unsigned int mi=ni1; mi<m; mi++)
999 b[mi]-=c*a[mi + ni*m];
1003 for(
unsigned int ni=0; ni<n; ni++) {
1006 for(
unsigned int nj=k+1; nj<n; nj++)
1007 s-=a[k + nj*m] * x[nj];
1008 if(a[k + k*m]==0.0)
return(1);
1014 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)
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 qrWeightRm(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 qrSimpleLSQ(double **A, double *B, int M, int N, double *X, double *r2)
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 qrWeight(int N, int M, double **A, double *b, double *weight, double *ws)
int qr_decomp(double **a, int M, int N, double *tau, double **cchain, double *chain)
Header file for library libtpcextensions.
Header file for libtpclinopt.