# eoGenOp.h

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 //-----------------------------------------------------------------------------
    00004 // eoGenOp.h
    00005 // (c) Maarten Keijzer and Marc Schoenauer, 2001
    00006 /*
    00007     This library is free software; you can redistribute it and/or
    00008     modify it under the terms of the GNU Lesser General Public
    00009     License as published by the Free Software Foundation; either
    00010     version 2 of the License, or (at your option) any later version.
    00011
    00012     This library is distributed in the hope that it will be useful,
    00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015     Lesser General Public License for more details.
    00016
    00017     You should have received a copy of the GNU Lesser General Public
    00018     License along with this library; if not, write to the Free Software
    00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00020
    00021     Contact: mak@dhi.dk
    00022              Marc.Schoenauer@polytechnique.fr
    00023  */
    00024 //-----------------------------------------------------------------------------
    00025
    00026 #ifndef _eoGenOp_H
    00027 #define _eoGenOp_H
    00028
    00029 #include <eoOp.h>
    00030 #include <eoPopulator.h>
    00031 #include <eoFunctorStore.h>
    00032 #include <assert.h>
    00033
    00044
    00056 template <class EOT>
    00057 class eoGenOp : public eoOp<EOT>, public eoUF<eoPopulator<EOT> &, void>
    00058 {
    00059   public :
    00061   eoGenOp(): eoOp<EOT>( eoOp<EOT>::general ) {}
    00062
    00066   virtual unsigned max_production(void) = 0;
    00067
    00068   virtual std::string className() const = 0;
    00069     void operator()(eoPopulator<EOT>& _pop)
    00070     {
    00071     _pop.reserve(max_production());
    00072       apply(_pop);
    00073     }
    00074
    00075
    00076   protected :
    00079     virtual void apply(eoPopulator<EOT>& _pop) = 0;
    00080 };
    00081
    00082
    00084 template <class EOT>
    00085 class eoMonGenOp : public eoGenOp<EOT>
    00086 {
    00087    public:
    00088     eoMonGenOp(eoMonOp<EOT>& _op) : op(_op) {}
    00089
    00090     unsigned max_production(void) { return 1; }
    00091
    00092     void apply(eoPopulator<EOT>& _it)
    00093     {
    00094       if (op(*_it))
    00095         (*_it).invalidate();  // look how simple
    00096
    00097     }
    00098   virtual std::string className() const {return op.className();}
    00099    private :
    00100     eoMonOp<EOT>& op;
    00101 };
    00102
    00106 template <class EOT>
    00107 class eoBinGenOp : public eoGenOp<EOT>
    00108 {
    00109    public:
    00110     eoBinGenOp(eoBinOp<EOT>& _op) : op(_op) {}
    00111
    00112     unsigned max_production(void) { return 1; }
    00113
    00117     void apply(eoPopulator<EOT>& _pop)
    00118     {
    00119       EOT& a = *_pop;
    00120       const EOT& b = _pop.select();
    00121
    00122       if (op(a, b))
    00123         a.invalidate();
    00124     }
    00125   virtual std::string className() const {return op.className();}
    00126
    00127    private :
    00128     eoBinOp<EOT>& op;
    00129 };
    00130
    00132 template <class EOT>
    00133 class eoSelBinGenOp : public eoGenOp<EOT>
    00134 {
    00135    public:
    00136     eoSelBinGenOp(eoBinOp<EOT>& _op, eoSelectOne<EOT>& _sel) :
    00137       op(_op), sel(_sel) {}
    00138
    00139     unsigned max_production(void) { return 1; }
    00140
    00141     void apply(eoPopulator<EOT>& _pop)
    00142     { // _pop.source() gets the original population, an eoVecOp can make use of this as well
    00143       if (op(*_pop, sel(_pop.source())))
    00144         (*_pop).invalidate();
    00145     }
    00146   virtual std::string className() const {return op.className();}
    00147
    00148    private :
    00149     eoBinOp<EOT>& op;
    00150     eoSelectOne<EOT>& sel;
    00151 };
    00152
    00153
    00156 template <class EOT>
    00157 class eoQuadGenOp : public eoGenOp<EOT>
    00158 {
    00159    public:
    00160     eoQuadGenOp(eoQuadOp<EOT>& _op) : op(_op) {}
    00161
    00162     unsigned max_production(void) { return 2; }
    00163
    00164     void apply(eoPopulator<EOT>& _pop)
    00165     {
    00166       EOT& a = *_pop;
    00167       EOT& b = *++_pop;
    00168
    00169
    00170       if(op(a, b))
    00171       {
    00172         a.invalidate();
    00173         b.invalidate();
    00174       }
    00175
    00176    }
    00177   virtual std::string className() const {return op.className();}
    00178
    00179    private :
    00180     eoQuadOp<EOT>& op;
    00181 };
    00182
    00207     template <class EOT>
    00208     eoGenOp<EOT>& wrap_op(eoOp<EOT>& _op, eoFunctorStore& _store)
    00209     {
    00210       switch(_op.getType())
    00211       {
    00212         case eoOp<EOT>::unary     : return _store.storeFunctor(new eoMonGenOp<EOT>(static_cast<eoMonOp<EOT>&>(_op)));
    00213         case eoOp<EOT>::binary    : return _store.storeFunctor(new eoBinGenOp<EOT>(static_cast<eoBinOp<EOT>&>(_op)));
    00214         case eoOp<EOT>::quadratic : return _store.storeFunctor(new eoQuadGenOp<EOT>(static_cast<eoQuadOp<EOT>&>(_op)));
    00215         case eoOp<EOT>::general   : return static_cast<eoGenOp<EOT>&>(_op);
    00216       }
    00217
    00218       assert(false);
    00219       return static_cast<eoGenOp<EOT>&>(_op);
    00220     }
    00221
    00222 #endif
    00223