cgv
Loading...
Searching...
No Matches
qr.h
1#pragma once
2
3#include "mat.h"
4#include "det.h"
5#include "functions.h"
6#include "up_tri_mat.h"
7
8#include <limits>
9#include <algorithm>
10
11namespace cgv {
12namespace math {
13
14//qr decomposition returns false if matrix is singular
15template<typename T>
16bool qr(const mat<T> &a, mat<T> &q, up_tri_mat<T> &r)
17{
18 mat<T> rr = a;
19
20 bool sing =false;
21 unsigned n = a.nrows();
22 unsigned m = a.ncols();
23 assert(n == m);
24 q.resize(n,n);
25 r.resize(n);
26 unsigned i,j,k;
27 vec<T> c(n), d(n);
28 T scale,sigma,sum,tau;
29 for (k=0;k<n-1;k++)
30 {
31 scale=0.0;
32 for (i=k;i<n;i++)
33 scale=std::max((T)scale,(T)std::abs(rr(i,k)));
34 if (scale == 0.0)
35 {
36 sing=true;
37 c[k]=d[k]=0.0;
38 } else {
39 for (i=k;i<n;i++) rr(i,k) /= scale;
40 for (sum=0.0,i=k;i<n;i++) sum += rr(i,k)*rr(i,k);
41 sigma=sign((T)sqrt(sum),(T)rr(k,k));
42 rr(k,k) += sigma;
43 c[k]=sigma*rr(k,k);
44 d[k] = -scale*sigma;
45 for (j=k+1;j<n;j++) {
46 for (sum=0.0,i=k;i<n;i++)
47 sum += rr(i,k)*rr(i,j);
48 tau=sum/c[k];
49 for (i=k;i<n;i++)
50 rr(i,j) -= tau*rr(i,k);
51 }
52 }
53 }
54 d[n-1]=rr(n-1,n-1);
55 if (d[n-1] == 0.0)
56 sing=true;
57 for (i=0;i<n;i++) {
58 for (j=0;j<n;j++) q(i,j)=0.0;
59 q(i,i)=1.0;
60 }
61 for (k=0;k<n-1;k++)
62 {
63 if (c[k] != 0.0)
64 {
65 for (j=0;j<n;j++)
66 {
67 sum=0.0;
68 for (i=k;i<n;i++)
69 sum += rr(i,k)*q(j,i);
70 sum /= c[k];
71 for (i=k;i<n;i++)
72 q(j,i) -= sum*rr(i,k);
73 }
74 }
75 }
76 for (i=0;i<n;i++)
77 {
78 rr(i,i)=d[i];
79 for (j=0;j<i;j++) rr(i,j)=0.0;
80 }
81 for(unsigned i = 0; i < n;i++)
82 for(unsigned j = i; j < n; j++)
83 r(i,j)=rr(i,j);
84 return !sing;
85}
86
87
88//qr decomposition by modified gram schmidt
89template<typename T>
90bool qr_mgs(const mat<T> &a, mat<T> &q, up_tri_mat<T> &r)
91{
92 unsigned n = a.nrows();
93 unsigned m = a.ncols();
94 assert(n == m);
95 q.resize(n,n);
96 r.resize(n);
97
98 for(unsigned j = 0; j < m; j++)
99 {
100 vec<T> v = a.col(j);
101 for(unsigned i = 0; i < j; i++)
102 {
103 r(i,j) = dot(q.col(i),v);
104 v= v- r(i,j)*q.col(i);
105 }
106 r(j,j) = length(v);
107 if(std::abs(r(j,j)) == 0)
108 return false;
109 q.set_col(j, v/r(j,j));
110
111 }
112 return true;
113}
114
115
116
117
118
119
120
121// rq decomposition using tricky column and row permutations
122template <typename T>
123bool rq(const mat<T> &a, up_tri_mat<T> &r, mat<T> &q)
124{
125 unsigned N = a.nrows();
126 r.resize(N);
127 q.resize(N,N);
128 mat<T> p=transpose(a);
129 p.fliplr();
130 p.flipud();
131 if(!qr(p,q,r)) return false;
132 mat<T> rr =r;
133 rr.transpose();
134 rr.fliplr();
135 rr.flipud();
136
137 q.transpose();
138 q.fliplr();
139 q.flipud();
140
141 if (det(q)<0)
142 {
143
144 rr.set_col(0,-rr.col(0));
145 q.set_row(0,-q.row(0));
146
147 }
148
149 for(unsigned i = 0; i< r.nrows();i++)
150 for(unsigned j = i; j< r.ncols();j++)
151 r(i,j)=rr(i,j);
152
153 return true;
154}
155
156
157
158
159
160
161
162}
163
164}
the cgv namespace
Definition print.h:11