00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CBINARYRELATION_H_
00029 #define CBINARYRELATION_H_
00030
00031 #include <mrpt/math/CMatrixTemplate.h>
00032 #include <mrpt/math/matrix_adaptors.h>
00033
00034 #include <set>
00035 #include <iterator>
00036 #include <algorithm>
00037 #include <utility>
00038
00039 namespace mrpt { namespace math {
00040 using std::vector;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template<typename T,typename U,bool UIsObject=false> class CBinaryRelation {
00051 private:
00052
00053
00054 typedef typename detail::MatrixWrapper<U,UIsObject>::MatrixType MatrixType;
00055 public:
00056 typedef U (*SimpleFunctionByReturnValue)(T,T);
00057 typedef U (*FunctionByReturnValue)(const T &,const T &);
00058 typedef void (*FunctionByReferencePass)(const T &,const T &,U &);
00059 typedef typename std::set<T>::const_iterator const_iterator;
00060 typedef typename std::set<T>::const_reverse_iterator const_reverse_iterator;
00061 typedef CMatrixRowAccessor<U> AccessorForFirstElement;
00062 typedef CMatrixColumnAccessor<U> AccessorForSecondElement;
00063 typedef CConstMatrixRowAccessor<U> ConstAccessorForFirstElement;
00064 typedef CConstMatrixColumnAccessor<U> ConstAccessorForSecondElement;
00065 private:
00066 std::set<T> elements;
00067 MatrixType relation;
00068
00069
00070
00071
00072
00073 template<typename FunctionType> inline void applyFunction(FunctionType fun,size_t e1,size_t e2,const T &T1,const T &T2) {
00074 detail::applyFunction<T,U,UIsObject,FunctionType>(*this,fun,e1,e2,T1,T2);
00075 }
00076
00077 public:
00078
00079
00080
00081 explicit inline CBinaryRelation(const std::set<T> &els):elements(els),relation(els.size(),els.size()) {}
00082
00083
00084
00085 template<typename FunctionType> inline CBinaryRelation(const std::set<T> &els,FunctionType fun):elements(els),relation(els.size(),els.size()) {
00086 initializeWith(fun);
00087 }
00088
00089
00090
00091 template<typename FunctionType> void initializeWith(FunctionType fun) {
00092 typename std::set<T>::const_iterator it=elements.begin();
00093 for (size_t i=0;i<elements.size();++i,++it) {
00094 typename std::set<T>::const_iterator jt=elements.begin();
00095 for (size_t j=0;j<elements.size();++j,++jt) applyFunction(fun,i,j,*it,*jt);
00096 }
00097 }
00098
00099
00100
00101 template<typename FunctionType> void initializeSymmetricallyWith(FunctionType fun) {
00102 typename std::set<T>::const_iterator it=elements.begin();
00103 for (size_t i=0;i<elements.size();++i,++it) {
00104 applyFunction(fun,i,i,*it,*it);
00105 typename std::set<T>::const_iterator jt=it;
00106 jt++;
00107 for (size_t j=i+1;j<elements.size();++j,++jt) {
00108 applyFunction(fun,i,j,*it,*jt);
00109 relation(j,i)=relation(i,j);
00110 }
00111 }
00112 }
00113
00114
00115
00116 inline void setRelationValue(size_t e1,size_t e2,const U &newVal) {
00117 relation.get_unsafe(e1,e2)=newVal;
00118 }
00119
00120
00121
00122 inline const U &getRelationValue(size_t e1,size_t e2) const {
00123 return relation.get_unsafe(e1,e2);
00124 }
00125 inline const U &operator()(size_t e1,size_t e2) const {
00126 return getRelationValue(e1,e2);
00127 }
00128
00129
00130
00131 inline U &getRelationValue(size_t e1,size_t e2) {
00132 return relation.get_unsafe(e1,e2);
00133 }
00134 inline U &operator()(size_t e1,size_t e2) {
00135 return getRelationValue(e1,e2);
00136 }
00137
00138
00139
00140 inline bool setRelationValue(const T &t1,const T &t2,const U &newVal) {
00141 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00142 typename std::set<T>::const_iterator it1=std::find(b,e,t1),it2=std::find(b,e,t2);
00143 if (it1==e||it2==e) return false;
00144 setRelationValue(static_cast<size_t>(std::distance(b,it1)),static_cast<size_t>(std::distance(b,it2)),newVal);
00145 return true;
00146 }
00147
00148
00149
00150 inline U getRelationValue(const T &t1,const T &t2) const {
00151 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00152 typename std::set<T>::const_iterator it1=std::find(b,e,t1),it2=std::find(b,e,t2);
00153 if (it1==e||it2==e) throw std::domain_error("Element not found");
00154 return getRelationValue(static_cast<size_t>(std::distance(b,it1)),static_cast<size_t>(std::distance(b,it2)));
00155 }
00156
00157
00158
00159
00160 inline U &getRelationValue(const T &t1,const T &t2) {
00161 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00162 typename std::set<T>::const_iterator it1=std::find(b,e,t1),it2=std::find(b,e,t2);
00163 if (it1==e||it2==e) throw std::domain_error("Element not found");
00164 return getRelationValue(static_cast<size_t>(std::distance(b,it1)),static_cast<size_t>(distance(b,it2)));
00165 }
00166
00167
00168
00169 inline const_iterator begin() const {
00170 return elements.begin();
00171 }
00172
00173
00174
00175 inline const_iterator end() const {
00176 return elements.end();
00177 }
00178
00179
00180
00181 inline const_reverse_iterator rbegin() const {
00182 return elements.rbegin();
00183 }
00184
00185
00186
00187 inline const_reverse_iterator rend() const {
00188 return elements.rend();
00189 }
00190
00191
00192
00193 T operator[](size_t i) const {
00194 ASSERT_BELOW_(i,elements.size())
00195 typename std::set<T>::const_iterator it=elements.begin();
00196 std::advance(it,i);
00197 return *it;
00198 }
00199
00200
00201
00202 inline AccessorForFirstElement getRelationFrom(size_t i) {
00203 return AccessorForFirstElement(relation,i);
00204 }
00205
00206
00207
00208 inline ConstAccessorForFirstElement getRelationFrom(size_t i) const {
00209 return ConstAccessorForFirstElement(relation,i);
00210 }
00211
00212
00213
00214 inline AccessorForSecondElement getRelationTo(size_t i) {
00215 return AccessorForSecondElement(relation,i);
00216 }
00217
00218
00219
00220 inline ConstAccessorForSecondElement getRelationTo(size_t i) const {
00221 return ConstAccessorForSecondElement(relation,i);
00222 }
00223
00224
00225
00226 inline AccessorForFirstElement getRelationFrom(const T &t) {
00227 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00228 typename std::set<T>::const_iterator it=std::find(b,e,t);
00229 if (it==e) throw std::domain_error("Element not found");
00230 return getRelationFrom(static_cast<size_t>(std::distance(b,it)));
00231 }
00232
00233
00234
00235
00236 inline ConstAccessorForFirstElement getRelationFrom(const T &t) const {
00237 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00238 typename std::set<T>::const_iterator it=std::find(b,e,t);
00239 if (it==e) throw std::domain_error("Element not found");
00240 return getRelationFrom(static_cast<size_t>(std::distance(b,it)));
00241 }
00242 inline void getRelationFrom(size_t i,vector<U> &vec) {
00243 size_t N=elements.size();
00244 ASSERT_(i<N);
00245 vec.resize(N);
00246 ConstAccessorForFirstElement access(relation,i);
00247 std::copy(access.begin(),access.end(),vec.begin());
00248 }
00249 inline void getRelationFrom(const T &t,vector<U> &vec) {
00250 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00251 typename std::set<T>::const_iterator it=std::find(b,e,t);
00252 if (it==e) throw std::domain_error("Element not found");
00253 getRelationFrom(static_cast<size_t>(std::distance(b,it)),vec);
00254 }
00255
00256
00257
00258 inline AccessorForSecondElement getRelationTo(const T &t) {
00259 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00260 typename std::set<T>::const_iterator it=std::find(b,e,t);
00261 if (it==e) throw std::domain_error("Element not found");
00262 return getRelationTo(static_cast<size_t>(std::distance(b,it)));
00263 }
00264
00265
00266
00267
00268 inline ConstAccessorForSecondElement getRelationTo(const T &t) const {
00269 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00270 typename std::set<T>::const_iterator it=std::find(b,e,t);
00271 if (it==e) throw std::domain_error("Element not found");
00272 return getRelationTo(static_cast<size_t>(std::distance(b,it)));
00273 }
00274 inline void getRelationTo(size_t i,vector<U> &vec) {
00275 size_t N=elements.size();
00276 ASSERT_(i<N);
00277 vec.resize(N);
00278 ConstAccessorForSecondElement access(relation,i);
00279 std::copy(access.begin(),access.end(),vec.begin());
00280 }
00281 inline void getRelationTo(const T &t,vector<U> &vec) {
00282 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00283 typename std::set<T>::const_iterator it=std::find(b,e,t);
00284 if (it==e) throw std::domain_error("Element not found");
00285 getRelationTo(static_cast<size_t>(std::distance(b,it)),vec);
00286 }
00287
00288
00289
00290 void removeElementAt(size_t i) {
00291 ASSERT_(i<elements.size());
00292 typename std::set<T>::const_iterator it=elements.begin();
00293 std::advance(it,i);
00294 elements.erase(i);
00295 set<size_t> ii;
00296 ii.insert(i);
00297 relation.removeRowsAndCols(ii,ii);
00298 }
00299
00300
00301
00302 bool removeElement(const T &el) {
00303 typename std::set<T>::const_iterator b=elements.begin(),e=elements.end();
00304 typename std::set<T>::const_iterator it=std::find(e,b,el);
00305 if (it==e) return false;
00306 removeElementAt(std::distance(b,it));
00307 return true;
00308 }
00309
00310
00311
00312 size_t removeElements(const set<T> &vals) {
00313 set<size_t> positions;
00314 for (typename set<T>::const_iterator it=vals.begin();it!=vals.end();++it) {
00315 typename set<T>::iterator elsIt=std::find(elements.begin(),elements.end(),*it);
00316 if (elsIt!=elements.end()) positions.insert(std::distance(elements.begin(),elsIt));
00317 }
00318
00319
00320
00321
00322
00323
00324 removeElementsAt(positions);
00325 return positions.size();
00326 }
00327 void removeElementsAt(const set<size_t> &poss) {
00328 relation.removeRowsAndCols(poss,poss);
00329 for (set<size_t>::const_reverse_iterator it=poss.rbegin();it!=poss.rend();++it) {
00330 typename std::set<T>::const_iterator it2=elements.begin();
00331 std::advance(it2,*it);
00332 elements.erase(it2);
00333 }
00334 }
00335
00336
00337
00338
00339 std::pair<bool,size_t> insertElement(const T &el) {
00340 std::pair<typename std::set<T>::iterator,bool> ins=elements.insert(el);
00341 size_t dist=std::distance(elements.begin(),ins.first);
00342 if (ins.second) {
00343 std::multiset<size_t> newEls;
00344 newEls.insert(dist);
00345 relation.insertRowsAndCols(newEls,newEls);
00346 return std::make_pair(true,dist);
00347 } else return std::make_pair(false,dist);
00348 }
00349
00350
00351
00352 template<typename FunctionType> std::pair<bool,size_t> insertElement(const T &el,FunctionType fun) {
00353 std::pair<bool,size_t> ins=insertElement(el);
00354 size_t pos=ins.second;
00355 for (size_t i=0;i<elements.size();++i) {
00356 const T &newEl=operator[](i);
00357 applyFunction(fun,pos,i,el,newEl);
00358 applyFunction(fun,i,pos,newEl,el);
00359 }
00360 return ins;
00361 }
00362
00363
00364
00365 size_t insertElements(const std::set<T> &els) {
00366 if (els.empty()) return 0;
00367
00368
00369
00370 std::vector<size_t> added;
00371
00372 added.reserve(els.size());
00373 for (typename std::set<T>::const_iterator it=els.begin();it!=els.end();++it) {
00374 std::pair<typename std::set<T>::iterator,bool> ins=elements.insert(*it);
00375 size_t dist=std::distance(elements.begin(),ins.first);
00376 if (ins.second) {
00377 added.push_back(dist);
00378 for (std::vector<size_t>::iterator it2=added.begin();it2!=added.end();++it2) if (*it2>=dist) ++(*it2);
00379
00380 }
00381 }
00382 std::sort(added.begin(),added.end());
00383 for (size_t j=1;j<added.size();++j) added[j]-=j;
00384 std::multiset<size_t> poss(added.begin(),added.end());
00385 relation.insertRowsAndCols(poss,poss);
00386 return added.size();
00387 }
00388
00389
00390
00391 template<typename FunctionType> size_t insertElements(const std::set<T> &els,FunctionType fun) {
00392 if (els.empty()) return 0;
00393 size_t howMany=insertElements(els);
00394 std::set<size_t> poss;
00395 {
00396
00397 typename std::set<T>::const_iterator begin=elements.begin(),end=elements.end();
00398 for (typename std::set<T>::const_iterator it=els.begin();it!=els.end();++it) poss.insert(std::distance(begin,find(begin,end,*it)));
00399 }
00400 std::set<size_t> nPoss;
00401 std::set<size_t>::const_iterator begin=poss.begin(),end=poss.end();
00402 for (size_t i=0;i<elements.size();++i) if (std::find(begin,end,i)==end) nPoss.insert(i);
00403 vector<const T *> proxy;
00404 proxy.reserve(poss.size());
00405 for (std::set<size_t>::const_iterator it=begin;it!=end;++it) {
00406 const T &e1=operator[](*it);
00407 proxy.push_back(&e1);
00408 size_t i=0;
00409 for (typename std::set<T>::const_iterator it2=elements.begin();it2!=elements.end();++it2,++i) applyFunction(fun,*it,i,e1,*it2);
00410 }
00411 for (std::set<size_t>::const_iterator it=nPoss.begin();it!=nPoss.end();++it) {
00412 const T &e1=operator[](*it);
00413 typename std::vector<const T *>::const_iterator itV=proxy.begin();
00414 for (std::set<size_t>::const_iterator it2=poss.begin();it2!=poss.end();++it2,++itV) applyFunction(fun,*it,*it2,e1,**itV);
00415 }
00416 return howMany;
00417 }
00418
00419
00420
00421 void setElements(const std::set<T> &newEls) {
00422 relation.setSize(0,0);
00423 elements=newEls;
00424 relation.setSize(newEls.size(),newEls.size());
00425 }
00426
00427
00428
00429 inline size_t size() const {
00430 return elements.size();
00431 }
00432 };
00433
00434 namespace detail {
00435
00436 template<typename T,typename U,bool UIsObject,typename FunctionType> inline void applyFunction(CBinaryRelation<T,U,UIsObject> &o, FunctionType fun,size_t e1,size_t e2,const T &T1,const T &T2) {
00437 o.getRelationValue(e1,e2)=fun(T1,T2);
00438 }
00439
00440
00441
00442 template<typename T,typename U,bool UIsObject> inline void applyFunction(CBinaryRelation<T,U,UIsObject> &o,typename CBinaryRelation<T,U,UIsObject>::FunctionByReferencePass fun,size_t e1,size_t e2,const T &T1,const T &T2) {
00443 fun(T1,T2,o.getRelationValue(e1,e2));
00444 }
00445 }
00446
00447
00448 }}
00449 #endif