DenseLinAlgPack_TestVectorClass.cpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include <iomanip>
00030 #include <ostream>
00031 #include <vector>
00032 #include <typeinfo>
00033 
00034 #include "DenseLinAlgPack_TestDenseLinAlgPack.hpp"
00035 #include "DenseLinAlgPack_DVectorClass.hpp"
00036 #include "DenseLinAlgPack_DVectorOut.hpp"
00037 #include "DenseLinAlgPack_MatVecCompare.hpp"
00038 #include "TestingHelperPack_update_success.hpp"
00039 
00040 namespace {
00041 
00042 // This template function checks that iterator and subscriping access all
00043 // give the same results.
00044 template<class V, class I>
00045 void test_access( V* _v, I begin, I end, std::ostream*out, bool* success ) {
00046   using std::setw;
00047   using TestingHelperPack::update_success;
00048 
00049   V &v = *_v;
00050   bool result;
00051 
00052   if(out)
00053     *out  << "\nbegin + i == v[i] == v(i+1), for i = 0,1,...,v.dim()\n";
00054 
00055   I itr;
00056   int i;
00057   if(out)
00058     *out  << "\n i,  *(begin + i)  ==  v[i]  ==  v(i+1)  ==    ?  "
00059         << "\n--,  ------------     ------     ------     ------\n";
00060   for( itr = begin, i = 0; itr != end; ++itr, ++i ) {
00061     result = update_success( *itr == v[i] && v[i] == v(i+1), success );
00062     if(out)
00063       *out  << setw(2)  << i << ','
00064           << setw(14) << *itr
00065           << setw(11) << v[i]
00066           << setw(11) << v(i+1)
00067           << setw(11) << std::right << result << std::endl << std::left;
00068   }
00069   if(out) *out << std::endl;
00070 }
00071 
00072 // This template function checks that a subregion creates the expected view.
00073 // Here rng must be rng.full_range() == true.
00074 template<class V, class VS>
00075 void test_subregion_access( V* _v, VS* _vs, const DenseLinAlgPack::Range1D& rng
00076   , std::ostream* out, bool* success )
00077 {
00078   using std::setw;
00079   using TestingHelperPack::update_success;
00080 
00081   bool result;
00082   V &v = *_v;
00083   VS &vs = *_vs;
00084 
00085   if(out)
00086     *out  << "\nv.begin() + i1 == vs.begin() + i2 == vs[i2] == vs(i2+1)"
00087         << ", for i1 = lb-1,..,ub-1, for i2 = 0,..,rng.size()-1\n";
00088 
00089   typename V::const_iterator itr1;
00090   typename VS::const_iterator itr2;
00091   int i1, i2;
00092   if(out)
00093     *out  << "\ni1, i2, *(v.begin() + i1)  ==  *(vs.begin() + i2)  ==  vs[i2]  ==  vs(i2+1)  ==    ?  "
00094         << "\n--, --, -----------------      ------------------      ------      --------      ------\n";
00095   for(  i1 = rng.lbound()-1, itr1 = v.begin() + i1, i2 = 0, itr2 = vs.begin();
00096       i2 < rng.size();
00097       ++i1, ++itr1, ++i2, ++itr2                        )
00098   {
00099     result = update_success( *itr1 == *itr2 && *itr2 == vs[i2] && *itr2 == vs(i2+1), success );
00100     if(out)
00101       *out  << setw(2)  << i1 << ','
00102           << setw(3)  << i2 << ','
00103           << setw(18) << *itr1
00104           << setw(24) << *itr2
00105           << setw(12) << vs[i2]
00106           << setw(14) << vs(i2+1)
00107           << setw(12) << std::right << result << std::endl << std::left;
00108   }
00109   if(out) *out << std::endl;
00110 }
00111 
00112 // Print out a string for overlap
00113 const char* overlap_str( DenseLinAlgPack::EOverLap overlap ) {
00114   switch(overlap) {
00115     case DenseLinAlgPack::NO_OVERLAP:
00116       return "NO_OVERLAP";
00117     case DenseLinAlgPack::SOME_OVERLAP:
00118       return "SOME_OVERLAP";
00119     case DenseLinAlgPack::SAME_MEM:
00120       return "SAME_MEM";
00121   }
00122   return "Invalid value for EOverLap";
00123 }
00124 
00125 } // end namespace
00126 
00127 bool DenseLinAlgPack::TestingPack::TestVectorClass(std::ostream* out)
00128 {
00129   using DenseLinAlgPack::comp;
00130   using DenseLinAlgPack::sqrt_eps;
00131   using TestingHelperPack::update_success;
00132 
00133   bool success = true;
00134   bool result, result1, result2;
00135 
00136   if(out)
00137     *out  << "\n**********************************************"
00138         << "\n*** Testing DVector and DVectorSlice classes ***"
00139         << "\n**********************************************\n"
00140         << std::boolalpha;
00141 
00142   try {
00143 
00144   if(out)
00145     *out  << "\nLet vvz[i-1] = i + 0.1*i, for i = 1...,n\n";
00146 
00147   // std::vector<> which is starndard for comparisons
00148   const DVector::size_type n = 6;
00149   std::vector<DVector::value_type> vvz(6);
00150   {for(int i = 1; i <= n; ++i)
00151     vvz[i-1] = i + 0.1 * i;
00152   }
00153 
00154   if(out) *out << "\nLet alpha1 = 22.5\n";
00155   const value_type alpha1 = 22.5; 
00156 
00157   // ///////////////////////
00158   // Test Constructors
00159 
00160   if(out)
00161     *out  << "\n***\n*** Testing constructors\n***\n";
00162 
00163   // DVectorSlice Constructors
00164 
00165   if(out) *out << "\nVectorSlice vs1\n";
00166   DVectorSlice  vs1;
00167   if(out) *out << "vs1 =\n" << vs1;
00168 
00169   if(out) *out << "\nVectorSlice vs2(vvz.begin(),n)\n";
00170   DVectorSlice  vs2(&vvz[0],n);
00171   if(out) *out << "vs2 =\n" << vs2;
00172 
00173   if(out) *out << "\nVectorSlice vs3(vvz.begin(),n,Range1D())\n";
00174   DVectorSlice  vs3(&vvz[0],n,Range1D());
00175   if(out) *out << "vs3 =\n" << vs3;
00176 
00177   if(out) *out << "\nVectorSlice vs4(vs3,Range1D())\n";
00178   DVectorSlice  vs4(vs3,Range1D());
00179   if(out) *out << "vs4 =\n" << vs4;
00180 
00181   // DVector Constructors
00182 
00183   if(out) *out << "\nVector v1\n";
00184   DVector v1;
00185   if(out) *out << "v1 =\n" << v1;
00186 
00187   if(out) *out << "\nVector v2(alpha1,n)\n";
00188   DVector v2(alpha1,n);
00189   if(out) *out << "v2 =\n" << v2;
00190 
00191   if(out) *out << "\nVector v3(vvz.begin(),n)\n";
00192   DVector v3(&vvz[0],n);
00193   if(out) *out << "v3 =\n" << v3;
00194 
00195   if(out) *out << "\nVector v4(vs4)\n";
00196   DVector v4(vs4);
00197   if(out) *out << "v4 =\n" << v4;
00198 
00199   // //////////////////////////////////////
00200   // Test Binding Views (DVectorSlice)
00201 
00202   if(out)
00203     *out  << "\n***\n*** Testing DVectorSlice binding and "
00204           "conversion from DVector -> DVectorSlice\n***\n"
00205         << "\nvs1.bind(v2());\n";
00206   vs1.bind(v2());
00207   if(out) *out << "vs1 =\n" << vs1;
00208 
00209   // ///////////////////////
00210   // Test DVector Resizing
00211 
00212   if(out)
00213     *out  << "\n***\n*** Testing DVector resizing\n***\n"
00214         << "\nv2.free();\n";
00215   v2.free();
00216   if(out) *out << "v2.dim() == 0 : " << update_success( v2.dim() == 0, &success ) << std::endl;
00217 
00218   if(out)
00219     *out  << "\nv2.resize(n,2*alpha1);\n";
00220   v2.resize(n,2*alpha1);
00221   result1 = update_success( v2.dim() == n, &success );
00222   result2 = update_success( comp(v2,2*alpha1), &success );
00223   if(out)
00224     *out  << "( (v2.dim() -> " << v2.dim() << ") == n && "
00225         << "(comp(v2,2*alpha1) -> " << result2 << ") ) : " << (result1 && result2) << std::endl
00226         << "v2 =\n" << v2;
00227 
00228   // //////////////////////////////////////////////////////////
00229   // Test Iterator Access, Subscriping and Reverse VectorSlices
00230 
00231   if(out) *out << "\n***\n*** Testing Iterator Access, Subscriping and Reverse VectorSlices\n***\n";
00232 
00233   if(out)
00234     *out  << "\nLet v == v3, begin = v.begin()";
00235   test_access(&v3,v3.begin(),v3.end(),out,&success);
00236 
00237   if(out)
00238     *out  << "\nLet v == const_cast<const DVector&>(v3), begin = v.begin()";
00239   test_access(&const_cast<const DVector&>(v3),const_cast<const DVector&>(v3).begin()
00240     ,const_cast<const DVector&>(v3).end(),out,&success);
00241 
00242   if(out)
00243     *out  << "\nLet v == vs3, begin = v.begin()";
00244   test_access(&vs3,vs3.begin(),vs3.end(),out,&success);
00245 
00246   if(out)
00247     *out  << "\nLet v == const_cast<const DVectorSlice&>(vs3), begin = v.begin()";
00248   test_access(&const_cast<const DVectorSlice&>(vs3),const_cast<const DVectorSlice&>(vs3).begin()
00249     ,const_cast<const DVectorSlice&>(vs3).end(),out,&success);
00250 
00251   if(out)
00252     *out  << "\nLet v == v3.rev(), begin = v3.rbegin()";
00253   test_access(&v3.rev(),v3.rbegin(),v3.rend(),out,&success);
00254 
00255   if(out)
00256     *out  << "\nLet v == const_cast<const DVector&>(v3).rev(), begin = const_cast<const DVector&>(v3).rbegin()";
00257   test_access(&const_cast<const DVector&>(v3).rev(),const_cast<const DVector&>(v3).rbegin()
00258     ,const_cast<const DVector&>(v3).rend(),out,&success);
00259 
00260   if(out)
00261     *out  << "\nLet v == vs3.rev(), begin = vs3.rbegin()";
00262   test_access(&vs3.rev(),vs3.rbegin(),vs3.rend(),out,&success);
00263 
00264   if(out)
00265     *out  << "\nLet v == const_cast<const DVectorSlice&>(vs3).rev()"
00266           ", begin = const_cast<const DVectorSlice&>(vs3).rbegin()";
00267   test_access(&const_cast<const DVectorSlice&>(vs3).rev(),const_cast<const DVectorSlice&>(vs3).rbegin()
00268     ,const_cast<const DVectorSlice&>(vs3).rend(),out,&success);
00269 
00270 #ifdef LINALGPACK_CHECK_RANGE
00271 
00272   if(out) *out << "\n*** Test subscriping out of bounds\n";
00273 
00274   if(out) *out << "\nv3(0); (should throw std::out_of_range)\n";
00275   try{
00276     v3(0);
00277     result = false; 
00278   }
00279   catch(const std::out_of_range&) {
00280     result = true;
00281   }
00282   if(out) *out << "v3(0) threw std::out_of_range : " << result << std::endl;
00283   update_success( result, &success );
00284   
00285   if(out) *out << "\nv3(n+1); (should throw std::out_of_range)\n";
00286   try{
00287     v3(n+1);
00288     result = false; 
00289   }
00290   catch(const std::out_of_range&) {
00291     result = true;
00292   }
00293   if(out) *out << "v3(n+1) threw std::out_of_range : " << result << std::endl;
00294   update_success( result, &success );
00295 
00296   if(out) *out << "\nvs3(0); (should throw std::out_of_range)\n";
00297   try{
00298     vs3(0);
00299     result = false; 
00300   }
00301   catch(const std::out_of_range &) {
00302     result = true;
00303   }
00304   if(out) *out << "vs3(0) threw std::out_of_range : " << result << std::endl;
00305   update_success( result, &success );
00306   
00307   if(out) *out << "\nvs3(n+1); (should throw std::out_of_range)\n";
00308   try{
00309     vs3(n+1);
00310     result = false; 
00311   }
00312   catch(const std::out_of_range&) {
00313     result = true;
00314   }
00315   if(out) *out << "vs3(n+1) threw std::out_of_range : " << result << std::endl;
00316   update_success( result, &success );
00317 
00318 #endif
00319 
00320   // ////////////////////////////////
00321   // Test Subregion Access
00322 
00323   if(out) *out << "\n***\n*** Testing Subregion Access\n***\n";
00324 
00325   // DVector Subregions
00326   Range1D rng;
00327 
00328   if(out) *out << "\nv = v3, rng = [1,n/2], vs = v(rng)";
00329   rng = Range1D(1,n/2);
00330   test_subregion_access( &v3, &v3(rng), rng, out, &success );
00331 
00332   if(out) *out << "\nv = v3, rng = [n/3,2*n/3], vs = v(rng)";
00333   rng = Range1D(n/3,2*n/3);
00334   test_subregion_access( &v3, &v3(rng), rng, out, &success );
00335   
00336   if(out) *out << "\nv = v3, rng = [n/2,n], vs = v(rng)";
00337   rng = Range1D(n/2,n);
00338   test_subregion_access( &v3, &v3(rng), rng, out, &success );
00339 
00340   if(out) *out << "\nv = const_cast<const DVector&>(v3), rng = [n/2,n], vs = v(rng)";
00341   rng = Range1D(n/2,n);
00342   test_subregion_access( &v3, &const_cast<const DVector&>(v3)(rng), rng, out, &success );
00343 
00344   if(out) *out << "\nv = v3, rng = [1,n/2], vs = v(1,n/2)";
00345   rng = Range1D(1,n/2);
00346   test_subregion_access( &v3, &v3(1,n/2), rng, out, &success );
00347 
00348   if(out) *out << "\nv = const_cast<const DVector&>(v3), rng = [n/2,n], vs = v(n/2,n)";
00349   rng = Range1D(n/2,n);
00350   test_subregion_access( &v3, &const_cast<const DVector&>(v3)(n/2,n), rng, out, &success );
00351 
00352   // DVectorSlice Subregions
00353 
00354   if(out) *out << "\nv = vs3, rng = [1,n/2], vs = v(rng)";
00355   rng = Range1D(1,n/2);
00356   test_subregion_access( &vs3, &vs3(rng), rng, out, &success );
00357 
00358   if(out) *out << "\nv = vs3, rng = [n/3,2*n/3], vs = v(rng)";
00359   rng = Range1D(n/3,2*n/3);
00360   test_subregion_access( &vs3, &vs3(rng), rng, out, &success );
00361   
00362   if(out) *out << "\nv = vs3, rng = [n/2,n], vs = v(rng)";
00363   rng = Range1D(n/2,n);
00364   test_subregion_access( &vs3, &vs3(rng), rng, out, &success );
00365 
00366   if(out) *out << "\nv = const_cast<const DVectorSlice&>(vs3), rng = [n/2,n], vs = v(rng)";
00367   rng = Range1D(n/2,n);
00368   test_subregion_access( &vs3, &const_cast<const DVectorSlice&>(vs3)(rng), rng, out, &success );
00369 
00370   if(out) *out << "\nv = vs3, rng = [1,n/2], vs = v(1,n/2)";
00371   rng = Range1D(1,n/2);
00372   test_subregion_access( &vs3, &vs3(1,n/2), rng, out, &success );
00373 
00374   if(out) *out << "\nv = const_cast<const DVectorSlice&>(vs3), rng = [n/2,n], vs = v(n/2,n)";
00375   rng = Range1D(n/2,n);
00376   test_subregion_access( &vs3, &const_cast<const DVectorSlice&>(vs3)(n/2,n), rng, out, &success );
00377 
00378   // ///////////////////////
00379   // Test Assignment
00380 
00381   if(out) *out << "\n***\n*** Testing assignment operators\n***\n";
00382 
00383   // DVector Assignment
00384 
00385   if(out) *out << "\nv1.resize(n); v1 = 0.0;\n";
00386   v1.resize(n);
00387   v1 = 0.0;
00388   result = update_success( comp( v1, 0.0 ), &success );
00389   if(out)
00390     *out  << "v1 =\n" << v1
00391         << "v1 == 0.0 : " << result << std::endl;
00392   
00393   if(out) *out << "\nv1 = 0.0; v1 = vs3;\n";
00394   v1 = 0.0;
00395   v1 = vs3;
00396   result = update_success( comp( v1, vs3 ), &success );
00397   if(out)
00398     *out  << "v1 =\n" << v1
00399         << "v1 == vs3 : " << result << std::endl;
00400 
00401   if(out) *out << "\nv1 = 0.0; v1 = v3;\n";
00402   v1 = 0.0;
00403   v1 = v3;
00404   result = update_success( comp( v1, v3 ), &success );
00405   if(out)
00406     *out  << "v1 =\n" << v1
00407         << "v1 == v3 : " << result << std::endl;
00408 
00409   // DVectorSlice Assignment
00410 
00411   if(out) *out << "\nv1.resize(n); v1 = 0.0; vs1.bind(v1());\n";
00412   v1.resize(n);
00413   v1 = 0.0;
00414   vs1.bind(v1());
00415 
00416   if(out) *out << "\nvs1 = alpha1;\n";
00417   vs1 = alpha1;
00418   result = update_success( comp( vs1, alpha1 ), &success );
00419   if(out)
00420     *out  << "vs1 =\n" << v1
00421         << "vs1 == alpha1 : " << result << std::endl;
00422   
00423   if(out) *out << "\nvs1 = 0.0; vs1 = vs3;\n";
00424   vs1 = 0.0;
00425   vs1 = vs3;
00426   result = update_success( comp( vs1, vs3 ), &success );
00427   if(out)
00428     *out  << "vs1 =\n" << vs1
00429         << "vs1 == vs3 : " << result << std::endl;
00430 
00431   // ////////////////////////
00432   // Test overlap()
00433 
00434   if(out) *out << "\n***\n*** Testing overlap\n***\n";
00435 
00436   EOverLap ovlap;
00437 
00438   // DVector overlap
00439 
00440   if(out) *out << "\n*** DVector overlap\n";
00441 
00442   if(out) *out << "(v1.overlap(v3) -> ";
00443   ovlap = v1.overlap(v3);
00444   result = update_success( ovlap == NO_OVERLAP, &success );
00445   if(out) *out  << overlap_str(ovlap) << ") == NO_OVERLAP : " << result << std::endl;
00446   
00447   if(out) *out << "(v3.overlap(v3) -> ";
00448   ovlap = v3.overlap(v3);
00449   result = update_success( ovlap == SAME_MEM, &success );
00450   if(out) *out  << overlap_str(ovlap) << ") == SAME_MEM : " << result << std::endl;
00451 
00452   if(out) *out << "(v3.overlap(v3(1,n-1)) -> ";
00453   ovlap = v3.overlap(v3(1,n-1));
00454   result = update_success( ovlap == SOME_OVERLAP, &success );
00455   if(out) *out  << overlap_str(ovlap) << ") == SOME_OVERLAP : " << result << std::endl;
00456 
00457   if(out) *out << "(v3.overlap(v3(2,n-1)) -> ";
00458   ovlap = v3.overlap(v3(2,n-1));
00459   result = update_success( ovlap == SOME_OVERLAP, &success );
00460   if(out) *out  << overlap_str(ovlap) << ") == SOME_OVERLAP : " << result << std::endl;
00461 
00462   // DVectorSlice overlap
00463 
00464   if(out) *out << "\n*** DVectorSlice overlap\n"
00465           << "vs1.bind(v3());\n";
00466 
00467   vs1.bind(v3());
00468 
00469   if(out) *out << "(vs1.overlap(v2) -> ";
00470   ovlap = vs1.overlap(v2);
00471   result = update_success( ovlap == NO_OVERLAP, &success );
00472   if(out) *out  << overlap_str(ovlap) << ") == NO_OVERLAP : " << result << std::endl;
00473 
00474   if(out) *out << "(vs1.overlap(vs1) -> ";
00475   ovlap = vs1.overlap(vs1);
00476   result = update_success( ovlap == SAME_MEM, &success );
00477   if(out) *out  << overlap_str(ovlap) << ") == SAME_MEM : " << result << std::endl;
00478 
00479   if(out) *out << "(vs1(1,n/2).overlap(vs1(n/2+1,n)) -> ";
00480   ovlap = vs1(1,n/2).overlap(vs1(n/2+1,n));
00481   result = update_success( ovlap == NO_OVERLAP, &success );
00482   if(out) *out  << overlap_str(ovlap) << ") == NO_OVERLAP : " << result << std::endl;
00483 
00484   if(out) *out << "(vs1(1,n/2).overlap(vs1(n/3,2*n/3)) -> ";
00485   ovlap = vs1(1,n/2).overlap(vs1(n/3,2*n/3));
00486   result = update_success( ovlap == SOME_OVERLAP, &success );
00487   if(out) *out  << overlap_str(ovlap) << ") == SOME_OVERLAP : " << result << std::endl;
00488 
00489   if(out) *out << "(vs1(n/3,2*n/3).overlap(vs1(n/2+1,n)) -> ";
00490   ovlap = vs1(n/3,2*n/3).overlap(vs1(n/2+1,n));
00491   result = update_success( ovlap == SOME_OVERLAP, &success );
00492   if(out) *out  << overlap_str(ovlap) << ") == SOME_OVERLAP : " << result << std::endl;
00493 
00494   if(out) *out << "(vs1(n/3,2*n/3).overlap(vs1(n/3,2*n/3)) -> ";
00495   ovlap = vs1(n/3,2*n/3).overlap(vs1(n/3,2*n/3));
00496   result = update_success( ovlap == SAME_MEM, &success );
00497   if(out) *out  << overlap_str(ovlap) << ") == SAME_MEM : " << result << std::endl;
00498 
00499   } // end try
00500   catch( const std::exception& excpt ) {
00501     success = false;
00502     if(out)
00503       (*out)  << "\nError, a standard exception was thrown: "
00504           << typeName(excpt) << ": "
00505           << excpt.what() << std::endl; 
00506   }
00507   catch(...) {
00508     success = false;
00509     if(out)
00510       (*out)  << "\nError, an unknown exception was thrown\n";
00511   }
00512 
00513   if(out) {
00514     if(success)
00515       (*out)
00516         << "\n*** Congradulations, DVector and DVectorSlice seem to check out. ***\n";
00517     else
00518       (*out)
00519         << "\n*** Oops, all of the tests for DVector and DVectorSlice "
00520           "where not successful. ***\n";
00521   }
00522 
00523   return success;
00524 }
00525 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 10:10:59 2011 for MOOCHO (Single Doxygen Collection) by  doxygen 1.6.3