cgv
Loading...
Searching...
No Matches
point_operations.h
1#pragma once
2
3#ifdef min
4#undef min
5#endif
6#ifdef max
7#undef max
8#endif
9
10
11#include "vec.h"
12#include "mat.h"
13#include "transformations.h"
14#include <limits>
15#include <vector>
16#include <algorithm>
17
18
19
20namespace cgv {
21namespace math {
22
23
24
26template<typename T>
27inline vec<T> mean(const mat<T>& points)
28{
29 unsigned N = points.ncols();
30 unsigned M = points.nrows();
31 vec<T> mu;
32 mu.zeros(M);
33
34
35 for(unsigned j = 0; j < N;j++)
36 {
37 for(unsigned i = 0; i < M; i++)
38 {
39 mu(i)+=points(i,j);
40 }
41 }
42 mu/=(T)N;
43 return mu;
44}
45
46
49template <typename T>
50cgv::math::vec<T> geometric_median(const cgv::math::mat<T>& points, const T& eps=0.0001, const unsigned max_iter=100)
51{
52 unsigned m = points.cols();
53 unsigned n = points.rows();
54
56 cgv::math::vec<T> ytemp(n);
57
58
59 for(unsigned iter = 0; iter < max_iter; iter++)
60 {
61 ytemp.zeros();
62 T W =0;
63 for(unsigned j = 0;j < m; j++)
64 {
65 T invdist = length(points.col(j) - y);
66 if(invdist != 0)
67 invdist=1.0/invdist;
68
69 W += invdist;
70 ytemp += invdist*points.col(j);
71 }
72 ytemp = ytemp/W;
73 if(length(y-ytemp) < eps)
74 return ytemp;
75 else
76 y=ytemp;
77 }
78 return y;
79}
80
82template<typename T>
83inline vec<T> weighted_mean(const vec<T>& weights,const mat<T>& points)
84{
85 assert(weights.dim() == points.ncols());
86 unsigned N = points.ncols();
87 unsigned M = points.nrows();
88 vec<T> mu;
89 mu.zeros(M);
90
91 T sm =0;
92 for(unsigned j = 0; j < N;j++)
93 {
94 for(unsigned i = 0; i < M; i++)
95 {
96 mu(i)+=weights(j)*points(i,j);
97 }
98 sm+=weights(j);
99 }
100 mu/=sm;
101 return mu;
102}
103
104
105
106
107
109template <typename T>
110inline mat<T> covmat(const mat<T>& points)
111{
112 unsigned N = points.ncols();
113 unsigned M = points.nrows();
114 mat<T> covmat;
115 covmat.zeroes(M,M);
116 vec<T> m;
117 m.zeros(M);
118
119
120 for(unsigned c = 0; c < N;c++)
121 {
122 for(unsigned i = 0; i < M; i++)
123 {
124 for(unsigned j = 0; j < M; j++)
125 {
126 covmat(i,j)+=points(i,c)*points(j,c);
127 }
128 m(i)+=points(i,c);
129 }
130 }
131 m/=(T)N;
132 covmat-=((T)N)*dyad(m,m);
133 covmat/=(T)N;
134
135
136 return covmat;
137}
138
140template <typename T>
141inline mat<T> weighted_covmat(const vec<T>& weights,const mat<T>& points)
142{
143 unsigned N = points.ncols();
144 unsigned M = points.nrows();
145 mat<T> wcovmat;
146 wcovmat.zeros(M,M);
147 vec<T> wmean(M);
148 wmean.zeros();
149 T sumsqrweights=0;
150 T sumweights=0;
151
152 for(unsigned i = 0; i < N;i++)
153 {
154 sumweights+=weights(i);
155 }
156 vec<T> wn=weights/sumweights;
157 for(unsigned c = 0; c < N;c++)
158 {
159 for(unsigned i = 0; i < M;i++)
160 wmean(i)+=wn(c)*points.col(i,c);
161 sumsqrweights += wn(c)*wn(c);
162 }
163
164
165
166 for(unsigned c = 0; c < N;c++)
167 {
168 for(unsigned i = 0; i < M; i++)
169 {
170 for(unsigned j = 0; j < M; j++)
171 {
172 wcovmat(i,j)+=wn(c)*(points(i,c)-wmean(i))*(points(j,c)-wmean(j));
173 }
174
175 }
176 }
177 wcovmat/=((T)1.0-sumsqrweights);
178
179
180
181 return wcovmat;
182}
183
184
186template <typename T>
187inline void weighted_covmat_and_mean(const vec<T>& weights,const mat<T>& points, mat<T>&wcovmat, vec<T>& wmean)
188{
189 unsigned N = points.ncols();
190 unsigned M = points.nrows();
191 wcovmat.zeros(M,M);
192 wmean.resize(M);
193 wmean.zeros();
194
195
196 T sumsqrweights=0;
197 T sumweights=0;
198
199 for(unsigned i = 0; i < N;i++)
200 {
201 sumweights+=weights(i);
202 }
203 vec<T> wn=weights/sumweights;
204 for(unsigned c = 0; c < N;c++)
205 {
206 for(unsigned i = 0; i < M;i++)
207 wmean(i)+=wn(c)*points(i,c);
208 sumsqrweights += wn(c)*wn(c);
209 }
210
211
212
213 for(unsigned c = 0; c < N;c++)
214 {
215 for(unsigned i = 0; i < M; i++)
216 {
217 for(unsigned j = 0; j < M; j++)
218 {
219 wcovmat(i,j)+=wn(c)*(points(i,c)-wmean(i))*(points(j,c)-wmean(j));
220 }
221
222 }
223 }
224 wcovmat/=((T)1.0-sumsqrweights);
225
226}
227
229template <typename T>
230inline void covmat_and_mean(const mat<T>& points, mat<T>&covmat, vec<T>& mean)
231{
232 unsigned N = points.ncols();
233 unsigned M = points.nrows();
234 covmat.zeros(M,M);
235 mean.resize(M);
236 mean.zeros();
237
238
239 for(unsigned c = 0; c < N;c++)
240 {
241 for(unsigned i = 0; i < M; i++)
242 {
243 for(unsigned j = 0; j < M; j++)
244 {
245 covmat(i,j)+=points(i,c)*points(j,c);
246 }
247 mean(i)+=points(i,c);
248 }
249 }
250 mean/=(T)N;
251 covmat-=((T)N)*dyad(mean,mean);
252 covmat/=(T)N;
253
254}
255
256// compute the joint mean of N1+N2 datapoints from mean1 of N1 datapoint and mean2 of N2 datapoints
257template <typename T>
258inline vec<T> joint_mean(const int N1, const vec<T>& mean1,
259 const int N2, const vec<T>& mean2)
260{
261 T a = (T)N1/(T)(N2+N1);
262 T b = (T)N2/(T)(N2+N1);
263 return a*mean1+b*mean2;
264}
265
266//compute the joint mean and joint covariance matrix of N1+N2 datapoints
267//from mean1 and covmat1 of N1 data points and mean2 and covmat2 of N2 data points
268template <typename T>
269inline void joint_mean_and_covmat(const int N1, const vec<T>& mean1,const mat<T> &covmat1,
270 const int N2, const vec<T>& mean2, const mat<T>&covmat2,
271 int& jointN, vec<T>& jointmean, mat<T>& jointcovmat)
272{
273
274 jointN = N2+N1;
275 T a = (T)N1/(T)(jointN);
276 T b = (T)N2/(T)(jointN);
277 jointmean = a*mean1+b*mean2;
278
279 jointcovmat = N1*covmat1+N1*dyad(mean1,mean1) + N2*covmat2+N2*dyad(mean2,mean2);
280 jointcovmat -= ((T)jointN)*dyad(jointmean,jointmean);
281 jointcovmat /= (T)jointN;
282
283}
284
285
286
287
288
289//finds componentwise minimum vector of all column vectors in the matrix points
290template<typename T>
291inline vec<T> minimum(const mat<T>& points)
292{
293 unsigned N = points.ncols();
294 unsigned M = points.nrows();
295 vec<T> _min(M);
296 _min.fill(std::numeric_limits<T>::max());
297
298 for(unsigned j = 0; j < N;j++)
299 {
300 for(unsigned i = 0; i < M; i++)
301 {
302 _min(i) = _min(i) < points(i,j) ? _min(i) : points(i,j);
303 }
304 }
305
306 return _min;
307}
308
309//finds componentwise maximum vector of all column vectors in the matrix points
310template<typename T>
311inline vec<T> maximum(const mat<T>& points)
312{
313 unsigned N = points.ncols();
314 unsigned M = points.nrows();
315 vec<T> _max(M);
316 _max.fill(1-std::numeric_limits<T>::max());
317
318 for(unsigned j = 0; j < N;j++)
319 {
320 for(unsigned i = 0; i < M; i++)
321 {
322 _max(i) = _max(i) > points(i,j) ? _max(i) : points(i,j);
323 }
324 }
325
326 return _max;
327}
328
329
331template <typename T>
332inline void swap_XYZ_2_XZY(mat<T>& points)
333{
334 for(unsigned i = 0; i < points.ncols();i++)
335 {
336 T v = points(1,i);
337 points(1,i) =points(2,i);
338 points(2,i) = v;
339 }
340}
341
342//convert a non-homogeneous vector into a homogeneous vector
343template<typename T>
344inline void homog(vec<T>& p)
345{
346 vec<T> t(p.size()+1);
347 for(unsigned i = 0; i < p.size();i++)
348 {
349 t(i)=p(i);
350 }
351 t(p.size())=(T)1;
352 p=t;
353}
354
355//convert a homogeneous vector into a non-homogeneous vector
356template<typename T>
357inline void unhomog(vec<T>& p)
358{
359 unsigned N=p.size()-1;
360 vec<T> temp(N);
361
362 for(unsigned i = 0; i < N;i++)
363 {
364 temp(i)=p(i)/p(N);
365 }
366
367 p=temp;
368}
369
371template<typename T>
372inline void homog(mat<T>& points)
373{
374 mat<T> temp(points.nrows()+1,points.ncols());
375 for(unsigned j = 0; j < points.ncols(); j++)
376 {
377 for(unsigned i = 0; i < points.nrows();i++)
378 {
379 temp(i,j)=points(i,j);
380 }
381 temp(points.nrows(),j)=(T)1;
382 }
383 points=temp;
384}
385
387template<typename T>
388inline void unhomog(mat<T>& points)
389{
390 unsigned N=points.nrows()-1;
391 mat<T> temp(N,points.ncols());
392 for(unsigned j = 0; j < points.ncols(); j++)
393 {
394 for(unsigned i = 0; i < N;i++)
395 {
396 temp(i,j)=points(i,j)/points(N,j);
397 }
398 }
399 points=temp;
400}
401
402
403template<typename T>
404inline void center_and_scale(mat<T>& points,const T& sf=10)
405{
406 if(points.ncols() > 0)
407 {
408 assert(points.nrows() == 3);
409 vec<T> minv =minimum(points);
410 vec<T> maxv =maximum(points);
411 vec<T> t = vec<T>((maxv(0)+minv(0))/2.0,minv(1),(maxv(2)+minv(2))/2.0);
412 points = points - dyad(t,ones<T>(points.ncols()));
413 T s = max_value(maxv-minv);
414 points=scale_33<T>(sf/s,
415 sf/s,
416 sf/s)*points;
417 }
418}
419
420template<typename T>
421inline cgv::math::mat<T> center_and_scale_44(mat<T>& points,const T& sf=1)
422{
423 if(points.ncols() > 0)
424 {
425 assert(points.nrows() == 3);
426 vec<T> minv =minimum(points);
427 vec<T> maxv =maximum(points);
428 vec<T> t = vec<T>((maxv(0)+minv(0))/2.0,minv(1),(maxv(2)+minv(2))/2.0);
429 T s = max_value(maxv-minv);
430 return scale_44<T>(sf/s,
431 sf/s,
432 sf/s)*translate_44(-t);
433 }
434 return cgv::math::identity<T>(4);
435}
436
437
438
439
440}
441
442}
443
void zeros()
fill the vector with zeros
Definition fvec.h:133
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
Definition mat.h:208
const vec< T > col(unsigned j) const
extract a column of the matrix as a vector
Definition mat.h:833
A column vector class.
Definition vec.h:28
the cgv namespace
Definition print.h:11