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
00029
00030
00031
00032
00033 #ifndef __RVL_PDC
00034 #define __RVL_PDC
00035
00036 #include "data.hh"
00037 #include "product.hh"
00038
00039 namespace RVL {
00040
00046 class BlockFunctionObject:
00047 public FunctionObject,
00048 public std::vector<FunctionObject *> {
00049
00050 public:
00051
00052 string getName() const {
00053 string tmp;
00054 tmp+="*****************************\n";
00055 tmp+="*** Block Function Object ***\n";
00056 tmp+="*****************************\n";
00057
00058
00059
00060
00061
00062
00063
00064 return tmp;
00065 }
00066 };
00067
00071 class DiagonalFunctionObject: public BlockFunctionObject {
00072 private:
00073 DiagonalFunctionObject();
00074 DiagonalFunctionObject(DiagonalFunctionObject const &);
00075
00076 public:
00077 DiagonalFunctionObject(size_t n, FunctionObject & f)
00078 : BlockFunctionObject() {
00079 for (size_t i=0;i<n;i++) this->push_back(&f);
00080 }
00081 };
00082
00107 class ProductDataContainer: public DataContainer,
00108 public Product<DataContainer> {
00109
00110 public:
00111
00112 ProductDataContainer() {}
00113 ProductDataContainer(const ProductDataContainer &) {}
00114 virtual ~ProductDataContainer() {}
00115
00116
00117 virtual void eval( FunctionObject & f,
00118 std::vector<DataContainer const *> & x) {
00119
00120 BlockFunctionObject * bf = NULL;
00121 if (!(bf=dynamic_cast<BlockFunctionObject *>(&f))) {
00122 bf=new DiagonalFunctionObject(this->getSize(),f);
00123 }
00124 if (!bf) {
00125 RVLException e;
00126 e<<"Error: ProductDataContainer::eval\n";
00127 e<<"failed to create BlockFO from FO = "<<f.getName()<<" by either cast or DiagFO\n";
00128 throw e;
00129 }
00130 if (bf->size()!=this->getSize()) {
00131 RVLException e;
00132 e<<"Error: ProductDataContainer::eval\n";
00133 e<<"Input FO = "<<f.getName()<<" cast to BlockFO but wrong size\n";
00134 e<<"FO size = "<<bf->size()<<" ProductDC size = "<<this->getSize()<<"\n";
00135 throw e;
00136 }
00137
00138 try {
00139 size_t nx = x.size();
00140 vector<ProductDataContainer const *> xp(nx);
00141 for (size_t i=0;i<nx;i++) {
00142 if (!(xp[i]=dynamic_cast<ProductDataContainer const *> (x[i]))) {
00143 RVLException e;
00144 e<<"Error: ProductDataContainer::eval\n";
00145 e<<"argument "<<i<<" is not PDC\n";
00146 throw e;
00147 }
00148 if (xp[i]->getSize() != getSize()) {
00149 RVLException e;
00150 e<<"Error: ProductDataContainer::eval \n";
00151 e<<"input ProductDataContainer arg "<<i
00152 <<" does not have same number\n";
00153 e<<"of factors\n";
00154 throw e;
00155 }
00156 }
00157 vector<DataContainer const *> tmp(nx);
00158 size_t nc = this->getSize();
00159 for (size_t i=0;i<nc;i++) {
00160 for (size_t j=0;j<nx;j++) {
00161 tmp[j] = &((*xp[j])[i]);
00162 }
00163
00164 (*this)[i].eval(*(bf->at(i)),tmp);
00165 }
00166 }
00167 catch (RVLException & e) {
00168 e<<"\ncalled from ProductDataContainer::eval\n";
00169 throw e;
00170 }
00171 catch (...) {
00172 throw;
00173 }
00174 }
00175
00176 virtual void eval( FunctionObjectConstEval & f,
00177 std::vector<DataContainer const *> & x) const {
00178 try {
00179 size_t nx = x.size();
00180 vector<ProductDataContainer const *> xp(nx);
00181 for (size_t i=0;i<nx;i++) {
00182 if (!(xp[i]=dynamic_cast<ProductDataContainer const *> (x[i]))) {
00183 RVLException e;
00184 e<<"Error: ProductDataContainer::eval\n";
00185 e<<"argument "<<i<<" is not PDC\n";
00186 throw e;
00187 }
00188 if (xp[i]->getSize() != getSize()) {
00189 RVLException e;
00190 e<<"Error: ProductDataContainer::eval \n";
00191 e<<"input ProductDataContainer arg "<<i
00192 <<" does not have same number\n";
00193 e<<"of factors\n";
00194 throw e;
00195 }
00196 }
00197 vector<DataContainer const *> tmp(nx);
00198 size_t nc = this->getSize();
00199 for (size_t i=0;i<nc;i++) {
00200 for (size_t j=0;j<nx;j++) {
00201 tmp[j] = &((*xp[j])[i]);
00202 }
00203 DataContainer const & thisref = (*this)[i];
00204 thisref.eval(f,tmp);
00205 }
00206 }
00207 catch (RVLException & e) {
00208 e<<"\ncalled from ProductDataContainer::eval (const)\n";
00209 throw e;
00210 }
00211 catch (...) {
00212 throw;
00213 }
00214 }
00215
00218 virtual ostream & write(ostream & str) const {
00219 str<<"Product Data Container"<<endl;
00220 for (size_t i=0; i<getSize(); i++) {
00221 str<<"***factor "<<i<<":"<<endl;
00222 (*this)[i].write(str);
00223 }
00224 return str;
00225 }
00226
00227 };
00228
00242 class StdProductDataContainer:
00243 public ProductDataContainer,
00244 public std::vector< DataContainer * > {
00245
00246 private:
00247
00253 StdProductDataContainer(const StdProductDataContainer & p);
00254
00255 public:
00256
00258
00259 StdProductDataContainer() {}
00260
00261 ~StdProductDataContainer() {
00262
00263 for (size_t i=0;i<getSize();i++)
00264 if (this->at(i)) delete this->at(i);
00265 }
00266
00267 size_t getSize() const { return this->size(); }
00268
00269 DataContainer & operator[](size_t i) {
00270 try {
00271 return *(this->at(i));
00272 }
00273 catch (out_of_range) {
00274 RVLException e;
00275 e<<"attempt to access component "<<i<<" of StdProductDC of size "<<this->size()<<"\n";
00276 throw e;
00277 }
00278 }
00279
00280 DataContainer const & operator[](size_t i) const {
00281 try {
00282 return *(this->at(i));
00283 }
00284 catch (out_of_range) {
00285 RVLException e;
00286 e<<"attempt to access component "<<i<<" of StdProductDC of size "<<this->size()<<"\n";
00287 throw e;
00288 }
00289 }
00290
00291 void push(DataContainerFactory const & f) {
00292 DataContainer * x = f.build();
00293 this->push_back(x);
00294 }
00295
00296 };
00297
00298 }
00299
00300 #endif
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310