cgv
Loading...
Searching...
No Matches
bi_polynomial.h
1#pragma once
2#include <cgv/math/polynomial.h>
3
4namespace cgv {
5 namespace math {
6
7
19template <typename T>
20T bipoly_val(const mat<T>& bp, const T& x1, const T& x2)
21{
22 unsigned n = bp.ncols();
23 unsigned m = bp.nrows();
24 assert(n > 0);
25 assert(m > 0);
26
27 vec<T> r(m);
28 for(unsigned i = 0; i < m;i++)
29 r(i) = poly_val(bp.row(i),x1);
30
31 return poly_val(r,x2);
32}
33
37template <typename T>
38T bipoly_val(const mat<T>& bp, const vec<T>& x)
39{
40 unsigned n = bp.ncols();
41 unsigned m = bp.nrows();
42 assert(n > 0);
43 assert(m > 0);
44 assert(v.size() == 2)
45
46 vec<T> r(n);
47 for(unsigned i = 0; i < m;i++)
48 r(i) = poly_val(bp.row(i),x(0));
49
50 return poly_val(r,x(1));
51}
52
53
54//returns vandermonde matrix for bivariate polynomial fitting
55template <typename T>
56cgv::math::mat<T> vander2(unsigned degree1, unsigned degree2,
57 const vec<T>& X1,const vec<T> X2)
58{
59 assert(X1.size()>0);
60 assert(X1.size() == X2.size());
61 unsigned n = X1.size();
62 unsigned m = (degree1+1)*(degree2+1);
63 cgv::math::mat<T> Vxy(n,m);
64
65 cgv::math::mat<T> Vx = vander(degree1,X1);
66 cgv::math::mat<T> Vy = vander(degree2,X2);
67
68 for(unsigned r = 0; r < n; r++)
69 {
70 for(unsigned i = 0; i < degree2+1; i++)
71 for(unsigned j =0; j < degree1+1; j++)
72 Vxy(r,j*(degree2+1)+i) = Vy(r,i)*Vx(r,j);
73
74 }
75
76
77 return Vxy;
78
79}
80
81
82
83//fit a bivariate polynomial
84template <typename T>
85mat<T> bipoly_fit(unsigned degree1, unsigned degree2,
86 const vec<T>& X1,const vec<T> X2,const vec<T> Y)
87{
88
89 assert(X1.size() == X2.size());
90 assert(X1.size() == Y.size());
91
92
93 mat<T> V = cgv::math::vander2(degree1,degree2,X1,X2);
94 mat<T> A;
95 vec<T> b,bp;
96 AtA(V,A);
97 Atx(V,Y,b);
98 svd_solve(A,b,bp);
99
100 return reshape(bp,degree2+1,degree1+1);
101
102}
103
104
105/*
106template <typename T>
107mat<T> bipoly_fit2(unsigned degree1, unsigned degree2,
108 const vec<T>& X1,const vec<T> X2,const vec<T> Y)
109{
110
111 assert(X1.size() == X2.size());
112 assert(X1.size() == Y.size());
113
114 vec<T> C = poly_fit<T>(degree2,X2,Y);
115 //std::cout << C << "\n";
116 mat<T> B = dyad(cgv::math::ones<T>(X1.size()),C);
117 mat<T> V = cgv::math::vander(degree1,X1);
118 mat<T> A;
119
120 AtA(V,A);
121
122 mat<T> D,bp;
123 AtB(V,B,D);
124
125 svd_solve(A,D,bp);
126 //std::cout <<":\n"<< A*bp-D;
127
128 return bp;
129}*/
130
132template <typename T>
133mat<T> bipoly_der_x1(const mat<T>& bp)
134{
135
136 assert(bp.ncols() > 0 && bp.nrows() > 0);
137 if(bp.ncols() == 1)
138 return zeros<T>(1,1);
139
140 mat<T> m(bp.nrows(),bp.ncols()-1);
141 for(unsigned i = 0; i < bp.nrows(); i++)
142 m.set_row(i,poly_der(bp.row(i)));
143 return m;
144}
145
147template <typename T>
148mat<T> bipoly_der_x2(const mat<T>& bp)
149{
150
151 assert(bp.ncols() > 0 && bp.nrows() > 0);
152 if(bp.nrows() == 1)
153 return zeros<T>(1,1);
154 T n = (T)(bp.nrows()-1);
155
156 mat<T> m(bp.nrows()-1,bp.ncols());
157 for(unsigned i = 0; i < bp.nrows()-1; i++)
158 m.set_row(i,(n-(T)i)* bp.row(i));
159 return m;
160}
161
163template <typename T>
164mat<T> bipoly_int_x1(const mat<T>& bp,const T& k=0)
165{
166 mat<T> m(bp.nrows(),bp.ncols()+1);
167 for(unsigned i = 0; i < bp.nrows();i++)
168 m.set_row(i,poly_int(bp.row(i),k));
169 return m;
170}
171
173template <typename T>
174mat<T> bipoly_int_x2(const mat<T>& bp,const T& k=0)
175{
176
177 mat<T> v(1,bp.ncols());
178 v.zeros();
179 v(0,bp.ncols()-1)=k;
180 mat<T> m = vertcat(bp,v);
181
182 for(unsigned i = 0; i < m.nrows()-2;i++)
183 for(unsigned j = 0; j < m.ncols();j++)
184 m(i,j)=m(i,j)/(m.nrows()-1-i);
185
186
187
188 return m;
189}
190
191
192
193
194
195
196
197
198 }
199}
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
Definition mat.h:208
the cgv namespace
Definition print.h:11