test/maps_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 608 6ac5d9ae1d3d
parent 440 88ed40ad0d4f
child 684 7b1a6e963018
child 693 7bda7860e0a8
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #include <deque>
    20 #include <set>
    21 
    22 #include <lemon/concept_check.h>
    23 #include <lemon/concepts/maps.h>
    24 #include <lemon/maps.h>
    25 
    26 #include "test_tools.h"
    27 
    28 using namespace lemon;
    29 using namespace lemon::concepts;
    30 
    31 struct A {};
    32 inline bool operator<(A, A) { return true; }
    33 struct B {};
    34 
    35 class C {
    36   int x;
    37 public:
    38   C(int _x) : x(_x) {}
    39 };
    40 
    41 class F {
    42 public:
    43   typedef A argument_type;
    44   typedef B result_type;
    45 
    46   B operator()(const A&) const { return B(); }
    47 private:
    48   F& operator=(const F&);
    49 };
    50 
    51 int func(A) { return 3; }
    52 
    53 int binc(int a, B) { return a+1; }
    54 
    55 typedef ReadMap<A, double> DoubleMap;
    56 typedef ReadWriteMap<A, double> DoubleWriteMap;
    57 typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
    58 
    59 typedef ReadMap<A, bool> BoolMap;
    60 typedef ReadWriteMap<A, bool> BoolWriteMap;
    61 typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
    62 
    63 int main()
    64 {
    65   // Map concepts
    66   checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
    67   checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
    68   checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
    69   checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
    70   checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
    71   checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
    72   checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
    73   checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
    74 
    75   // NullMap
    76   {
    77     checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
    78     NullMap<A,B> map1;
    79     NullMap<A,B> map2 = map1;
    80     map1 = nullMap<A,B>();
    81   }
    82 
    83   // ConstMap
    84   {
    85     checkConcept<ReadWriteMap<A,B>, ConstMap<A,B> >();
    86     checkConcept<ReadWriteMap<A,C>, ConstMap<A,C> >();
    87     ConstMap<A,B> map1;
    88     ConstMap<A,B> map2 = B();
    89     ConstMap<A,B> map3 = map1;
    90     map1 = constMap<A>(B());
    91     map1 = constMap<A,B>();
    92     map1.setAll(B());
    93     ConstMap<A,C> map4(C(1));
    94     ConstMap<A,C> map5 = map4;
    95     map4 = constMap<A>(C(2));
    96     map4.setAll(C(3));
    97 
    98     checkConcept<ReadWriteMap<A,int>, ConstMap<A,int> >();
    99     check(constMap<A>(10)[A()] == 10, "Something is wrong with ConstMap");
   100 
   101     checkConcept<ReadWriteMap<A,int>, ConstMap<A,Const<int,10> > >();
   102     ConstMap<A,Const<int,10> > map6;
   103     ConstMap<A,Const<int,10> > map7 = map6;
   104     map6 = constMap<A,int,10>();
   105     map7 = constMap<A,Const<int,10> >();
   106     check(map6[A()] == 10 && map7[A()] == 10,
   107           "Something is wrong with ConstMap");
   108   }
   109 
   110   // IdentityMap
   111   {
   112     checkConcept<ReadMap<A,A>, IdentityMap<A> >();
   113     IdentityMap<A> map1;
   114     IdentityMap<A> map2 = map1;
   115     map1 = identityMap<A>();
   116 
   117     checkConcept<ReadMap<double,double>, IdentityMap<double> >();
   118     check(identityMap<double>()[1.0] == 1.0 &&
   119           identityMap<double>()[3.14] == 3.14,
   120           "Something is wrong with IdentityMap");
   121   }
   122 
   123   // RangeMap
   124   {
   125     checkConcept<ReferenceMap<int,B,B&,const B&>, RangeMap<B> >();
   126     RangeMap<B> map1;
   127     RangeMap<B> map2(10);
   128     RangeMap<B> map3(10,B());
   129     RangeMap<B> map4 = map1;
   130     RangeMap<B> map5 = rangeMap<B>();
   131     RangeMap<B> map6 = rangeMap<B>(10);
   132     RangeMap<B> map7 = rangeMap(10,B());
   133 
   134     checkConcept< ReferenceMap<int, double, double&, const double&>,
   135                   RangeMap<double> >();
   136     std::vector<double> v(10, 0);
   137     v[5] = 100;
   138     RangeMap<double> map8(v);
   139     RangeMap<double> map9 = rangeMap(v);
   140     check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100,
   141           "Something is wrong with RangeMap");
   142   }
   143 
   144   // SparseMap
   145   {
   146     checkConcept<ReferenceMap<A,B,B&,const B&>, SparseMap<A,B> >();
   147     SparseMap<A,B> map1;
   148     SparseMap<A,B> map2 = B();
   149     SparseMap<A,B> map3 = sparseMap<A,B>();
   150     SparseMap<A,B> map4 = sparseMap<A>(B());
   151 
   152     checkConcept< ReferenceMap<double, int, int&, const int&>,
   153                   SparseMap<double, int> >();
   154     std::map<double, int> m;
   155     SparseMap<double, int> map5(m);
   156     SparseMap<double, int> map6(m,10);
   157     SparseMap<double, int> map7 = sparseMap(m);
   158     SparseMap<double, int> map8 = sparseMap(m,10);
   159 
   160     check(map5[1.0] == 0 && map5[3.14] == 0 &&
   161           map6[1.0] == 10 && map6[3.14] == 10,
   162           "Something is wrong with SparseMap");
   163     map5[1.0] = map6[3.14] = 100;
   164     check(map5[1.0] == 100 && map5[3.14] == 0 &&
   165           map6[1.0] == 10 && map6[3.14] == 100,
   166           "Something is wrong with SparseMap");
   167   }
   168 
   169   // ComposeMap
   170   {
   171     typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
   172     checkConcept<ReadMap<B,double>, CompMap>();
   173     CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
   174     CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
   175 
   176     SparseMap<double, bool> m1(false); m1[3.14] = true;
   177     RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
   178     check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1],
   179           "Something is wrong with ComposeMap")
   180   }
   181 
   182   // CombineMap
   183   {
   184     typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
   185     checkConcept<ReadMap<A,double>, CombMap>();
   186     CombMap map1 = CombMap(DoubleMap(), DoubleMap());
   187     CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
   188 
   189     check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
   190           "Something is wrong with CombineMap");
   191   }
   192 
   193   // FunctorToMap, MapToFunctor
   194   {
   195     checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
   196     checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
   197     FunctorToMap<F> map1;
   198     FunctorToMap<F> map2 = FunctorToMap<F>(F());
   199     B b = functorToMap(F())[A()];
   200 
   201     checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
   202     MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
   203 
   204     check(functorToMap(&func)[A()] == 3,
   205           "Something is wrong with FunctorToMap");
   206     check(mapToFunctor(constMap<A,int>(2))(A()) == 2,
   207           "Something is wrong with MapToFunctor");
   208     check(mapToFunctor(functorToMap(&func))(A()) == 3 &&
   209           mapToFunctor(functorToMap(&func))[A()] == 3,
   210           "Something is wrong with FunctorToMap or MapToFunctor");
   211     check(functorToMap(mapToFunctor(constMap<A,int>(2)))[A()] == 2,
   212           "Something is wrong with FunctorToMap or MapToFunctor");
   213   }
   214 
   215   // ConvertMap
   216   {
   217     checkConcept<ReadMap<double,double>,
   218       ConvertMap<ReadMap<double, int>, double> >();
   219     ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
   220     ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
   221   }
   222 
   223   // ForkMap
   224   {
   225     checkConcept<DoubleWriteMap, ForkMap<DoubleWriteMap, DoubleWriteMap> >();
   226 
   227     typedef RangeMap<double> RM;
   228     typedef SparseMap<int, double> SM;
   229     RM m1(10, -1);
   230     SM m2(-1);
   231     checkConcept<ReadWriteMap<int, double>, ForkMap<RM, SM> >();
   232     checkConcept<ReadWriteMap<int, double>, ForkMap<SM, RM> >();
   233     ForkMap<RM, SM> map1(m1,m2);
   234     ForkMap<SM, RM> map2 = forkMap(m2,m1);
   235     map2.set(5, 10);
   236     check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 &&
   237           m2[5] == 10 && map2[1] == -1 && map2[5] == 10,
   238           "Something is wrong with ForkMap");
   239   }
   240 
   241   // Arithmetic maps:
   242   // - AddMap, SubMap, MulMap, DivMap
   243   // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap
   244   // - NegMap, NegWriteMap, AbsMap
   245   {
   246     checkConcept<DoubleMap, AddMap<DoubleMap,DoubleMap> >();
   247     checkConcept<DoubleMap, SubMap<DoubleMap,DoubleMap> >();
   248     checkConcept<DoubleMap, MulMap<DoubleMap,DoubleMap> >();
   249     checkConcept<DoubleMap, DivMap<DoubleMap,DoubleMap> >();
   250 
   251     ConstMap<int, double> c1(1.0), c2(3.14);
   252     IdentityMap<int> im;
   253     ConvertMap<IdentityMap<int>, double> id(im);
   254     check(addMap(c1,id)[0] == 1.0  && addMap(c1,id)[10] == 11.0,
   255           "Something is wrong with AddMap");
   256     check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0,
   257           "Something is wrong with SubMap");
   258     check(mulMap(id,c2)[0] == 0    && mulMap(id,c2)[2]  == 6.28,
   259           "Something is wrong with MulMap");
   260     check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2]  == 1.57,
   261           "Something is wrong with DivMap");
   262 
   263     checkConcept<DoubleMap, ShiftMap<DoubleMap> >();
   264     checkConcept<DoubleWriteMap, ShiftWriteMap<DoubleWriteMap> >();
   265     checkConcept<DoubleMap, ScaleMap<DoubleMap> >();
   266     checkConcept<DoubleWriteMap, ScaleWriteMap<DoubleWriteMap> >();
   267     checkConcept<DoubleMap, NegMap<DoubleMap> >();
   268     checkConcept<DoubleWriteMap, NegWriteMap<DoubleWriteMap> >();
   269     checkConcept<DoubleMap, AbsMap<DoubleMap> >();
   270 
   271     check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0,
   272           "Something is wrong with ShiftMap");
   273     check(shiftWriteMap(id, 2.0)[1] == 3.0 &&
   274           shiftWriteMap(id, 2.0)[10] == 12.0,
   275           "Something is wrong with ShiftWriteMap");
   276     check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0,
   277           "Something is wrong with ScaleMap");
   278     check(scaleWriteMap(id, 2.0)[1] == 2.0 &&
   279           scaleWriteMap(id, 2.0)[10] == 20.0,
   280           "Something is wrong with ScaleWriteMap");
   281     check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0,
   282           "Something is wrong with NegMap");
   283     check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0,
   284           "Something is wrong with NegWriteMap");
   285     check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0,
   286           "Something is wrong with AbsMap");
   287   }
   288 
   289   // Logical maps:
   290   // - TrueMap, FalseMap
   291   // - AndMap, OrMap
   292   // - NotMap, NotWriteMap
   293   // - EqualMap, LessMap
   294   {
   295     checkConcept<BoolMap, TrueMap<A> >();
   296     checkConcept<BoolMap, FalseMap<A> >();
   297     checkConcept<BoolMap, AndMap<BoolMap,BoolMap> >();
   298     checkConcept<BoolMap, OrMap<BoolMap,BoolMap> >();
   299     checkConcept<BoolMap, NotMap<BoolMap> >();
   300     checkConcept<BoolWriteMap, NotWriteMap<BoolWriteMap> >();
   301     checkConcept<BoolMap, EqualMap<DoubleMap,DoubleMap> >();
   302     checkConcept<BoolMap, LessMap<DoubleMap,DoubleMap> >();
   303 
   304     TrueMap<int> tm;
   305     FalseMap<int> fm;
   306     RangeMap<bool> rm(2);
   307     rm[0] = true; rm[1] = false;
   308     check(andMap(tm,rm)[0] && !andMap(tm,rm)[1] &&
   309           !andMap(fm,rm)[0] && !andMap(fm,rm)[1],
   310           "Something is wrong with AndMap");
   311     check(orMap(tm,rm)[0] && orMap(tm,rm)[1] &&
   312           orMap(fm,rm)[0] && !orMap(fm,rm)[1],
   313           "Something is wrong with OrMap");
   314     check(!notMap(rm)[0] && notMap(rm)[1],
   315           "Something is wrong with NotMap");
   316     check(!notWriteMap(rm)[0] && notWriteMap(rm)[1],
   317           "Something is wrong with NotWriteMap");
   318 
   319     ConstMap<int, double> cm(2.0);
   320     IdentityMap<int> im;
   321     ConvertMap<IdentityMap<int>, double> id(im);
   322     check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3],
   323           "Something is wrong with LessMap");
   324     check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3],
   325           "Something is wrong with EqualMap");
   326   }
   327 
   328   // LoggerBoolMap
   329   {
   330     typedef std::vector<int> vec;
   331     vec v1;
   332     vec v2(10);
   333     LoggerBoolMap<std::back_insert_iterator<vec> >
   334       map1(std::back_inserter(v1));
   335     LoggerBoolMap<vec::iterator> map2(v2.begin());
   336     map1.set(10, false);
   337     map1.set(20, true);   map2.set(20, true);
   338     map1.set(30, false);  map2.set(40, false);
   339     map1.set(50, true);   map2.set(50, true);
   340     map1.set(60, true);   map2.set(60, true);
   341     check(v1.size() == 3 && v2.size() == 10 &&
   342           v1[0]==20 && v1[1]==50 && v1[2]==60 &&
   343           v2[0]==20 && v2[1]==50 && v2[2]==60,
   344           "Something is wrong with LoggerBoolMap");
   345 
   346     int i = 0;
   347     for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
   348           it != map2.end(); ++it )
   349       check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
   350   }
   351 
   352   return 0;
   353 }