locallinalg.hh

Go to the documentation of this file.
00001 /*************************************************************************
00002 
00003 Copyright Rice University, 2004.
00004 All rights reserved.
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a
00007 copy of this software and associated documentation files (the "Software"),
00008 to deal in the Software without restriction, including without limitation
00009 the rights to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, provided that the above copyright notice(s) and this
00012 permission notice appear in all copies of the Software and that both the
00013 above copyright notice(s) and this permission notice appear in supporting
00014 documentation.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
00019 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
00020 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
00021 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00022 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00023 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00024 THIS SOFTWARE.
00025 
00026 Except as contained in this notice, the name of a copyright holder shall
00027 not be used in advertising or otherwise to promote the sale, use or other
00028 dealings in this Software without prior written authorization of the
00029 copyright holder.
00030 
00031 **************************************************************************/
00032 
00033 #ifndef __RVL_LLA
00034 #define __RVL_LLA
00035 
00036 #include "local.hh"
00037 #include "linalg.hh"
00038 #include "functions.hh"
00039 
00040 namespace RVL {
00041 
00059   template<class DataType, class Scalar = DataType>
00060   class LocalLinearAlgebraPackage: public LinearAlgebraPackage<Scalar> {
00061 
00062   public:
00063     LocalLinearAlgebraPackage() {}
00064     LocalLinearAlgebraPackage(const LocalLinearAlgebraPackage<Scalar, DataType> &) {}
00065     virtual ~LocalLinearAlgebraPackage() {}
00066   
00068     virtual BinaryLocalFunctionObjectScalarRedn<DataType,Scalar> & localinner() const = 0;
00070     FunctionObjectScalarRedn<Scalar> & inner() const { return localinner(); }
00072     virtual UnaryLocalFunctionObject<DataType> & localzero() const = 0;
00074     FunctionObject & zero() const { return localzero(); }
00075     // lincombobject deferred - must be specialized FO type
00076 
00084     virtual bool compare( LinearAlgebraPackage<Scalar> const & lap) const = 0;
00085 
00087     virtual void write(RVLException & e) const = 0;
00088 
00090     virtual ostream & write(ostream & str) const = 0;
00091   };
00092 
00097   template<class Scalar>
00098   class RVLLinCombObject: public BinaryLocalEvaluation<Scalar>, public LinCombObject<Scalar> {
00099   private:
00100     mutable Scalar a;
00101     mutable Scalar b;
00102   public:
00103     RVLLinCombObject(Scalar ain = ScalarFieldTraits<Scalar>::One(), 
00104              Scalar bin = ScalarFieldTraits<Scalar>::One()): a(ain), b(bin) {}
00105     RVLLinCombObject(const RVLLinCombObject<Scalar> & lc ): a(lc.a), b(lc.b) {}
00106     ~RVLLinCombObject() {}
00107 
00109     void setScalar(Scalar ain, Scalar bin) { a=ain; b=bin; }
00110 
00112     using RVL::BinaryLocalEvaluation<Scalar>::operator();
00113     void operator() (LocalDataContainer<Scalar> & u, 
00114              LocalDataContainer<Scalar> const & v) {
00115       size_t n = u.getSize();
00116       if (n > v.getSize()) {
00117     RVLException e; e<<"Error: RVLLinComb::operator()\n";
00118     e<<"operand 1 longer than operand 2 - not enough data\n";
00119     throw e;
00120       }
00121 
00122       // compiler should generate more efficient code for 
00123       // several special cases by avoiding explicit multiply
00124 
00125       Scalar * pu = u.getData();
00126       Scalar const * pv = v.getData();
00127 
00128       // special case u = v + b*u
00129       if (a == ScalarFieldTraits<Scalar>::One()) {
00130     // special case u = v + u;
00131     if (b == ScalarFieldTraits<Scalar>::One()) {
00132       for (size_t i=0;i<n;i++) {
00133         pu[i] = pv[i]+pu[i];
00134       }
00135     }
00136     // special case u = v - u;
00137     else if (b == -ScalarFieldTraits<Scalar>::One()) {
00138       for (size_t i=0;i<n;i++) {
00139         pu[i] = pv[i]-pu[i];
00140       }
00141     }
00142     // special case u = v;
00143     else if (b == ScalarFieldTraits<Scalar>::Zero()) {
00144       RVLCopy<Scalar> cp;    
00145       // use RVLCopy which uses memcpy for efficiency
00146       cp(u,v);
00147     }
00148       
00149     else { 
00150       for (size_t i=0;i<n;i++) {
00151         pu[i] = pv[i]+b*pu[i];
00152       }
00153     }
00154       }
00155       // special case u = -v + b*w;
00156       else if (a == -ScalarFieldTraits<Scalar>::One()) {
00157     // special case u = -v;
00158     if (b == ScalarFieldTraits<Scalar>::Zero()) {
00159       for (size_t i=0;i<n;i++) {
00160         pu[i] = -pv[i];
00161       }
00162     }
00163     else {
00164       for (size_t i=0;i<n;i++) {
00165         pu[i] = -pv[i]+b*pu[i];
00166       }
00167     }
00168       }
00169       // special case u = a*v;
00170       else if (b == ScalarFieldTraits<Scalar>::Zero()) {
00171     for (size_t i=0;i<n;i++) {
00172       pu[i] = a*pv[i];
00173     }
00174       }
00175       // general case u = a*v + b*u
00176       else {
00177     for (size_t i=0;i<n;i++) {
00178       pu[i] = a*pv[i]+b*pu[i];
00179     }
00180       }
00181     }
00182 
00183     string getName() const { string s = "RVLLinCombObject"; return s; }
00184   };
00185 
00190   template<class Scalar>
00191   class RVLLinearAlgebraPackage: public LocalLinearAlgebraPackage<Scalar,Scalar> {
00192 
00193   private:
00194 
00195     mutable RVLAssignConst<Scalar> this_zero;
00196     mutable RVLL2innerProd<Scalar> this_inner;
00197     mutable RVLLinCombObject<Scalar> this_lco;
00198 
00199   public:
00200 
00201     RVLLinearAlgebraPackage(Scalar ipscale = ScalarFieldTraits<Scalar>::One())
00202       : this_zero(ScalarFieldTraits<Scalar>::Zero()), 
00203     this_inner(abs(ipscale)), this_lco() {}
00204     RVLLinearAlgebraPackage(const RVLLinearAlgebraPackage<Scalar> & p) 
00205       :this_zero(ScalarFieldTraits<Scalar>::Zero()),
00206        this_inner(p.this_inner.getScale()),this_lco() {}
00207     ~RVLLinearAlgebraPackage() {}
00208 
00209     BinaryLocalFunctionObjectScalarRedn<Scalar, Scalar> & localinner() const {
00210       return this_inner; 
00211     }
00212     UnaryLocalFunctionObject<Scalar> & localzero() const {
00213       return this_zero;
00214     }
00215     LinCombObject<Scalar> & linComb() const {
00216       return this_lco; 
00217     }
00218 
00219     virtual bool compare(LinearAlgebraPackage<Scalar> const & lap) const {
00220       RVLLinearAlgebraPackage<Scalar> const * laptr=NULL;
00221       laptr=dynamic_cast<RVLLinearAlgebraPackage<Scalar> const *>(&lap);
00222       if (laptr) return true;
00223       return false;
00224     }
00225 
00227     void setScale(Scalar newscale) { this_inner.setScale(newscale); }
00228 
00229     virtual void write(RVLException & e) const {
00230       e<<"RVLLinearAlgebraPackage\n";
00231     }
00232 
00233     virtual ostream & write(ostream & str) const {
00234       str<<"RVLLinearAlgebraPackage\n";
00235       return str;
00236     }
00237   };
00238 
00239 }
00240 
00241 #endif

Generated on 5 Jan 2017 for LocalRVL by  doxygen 1.4.7