log.hh

00001 // Copyright (C) 2006  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016 // Boston, MA 02110-1301, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef OLENA_LRDE_UFMT_LOG_HH
00029 # define OLENA_LRDE_UFMT_LOG_HH
00030 
00031 # include <map>
00032 # include <oln/level/fill.hh>
00033 
00034 
00035 namespace oln
00036 {
00037 
00038   namespace lrde
00039   {
00040 
00041     namespace ufmt
00042     {
00043 
00044       // couting
00045 
00046       template <class Algo>
00047       unsigned n_level_roots(const Algo& algo)
00048       {
00049         typedef typename Algo::image I;
00050         unsigned count = 0;
00051         oln_iter_type(I) p(algo.f_());
00052         for_all(p)
00053           if (algo.is_level_root_(p))
00054             ++count;
00055         return count;
00056       }
00057 
00058       template <class Algo>
00059       unsigned n_roots(const Algo& algo)
00060       {
00061         typedef typename Algo::image I;
00062         unsigned count = 0;
00063         oln_iter_type(I) p(algo.f_());
00064         for_all(p)
00065           if (algo.is_root_(p))
00066             ++count;
00067         return count;
00068       }
00069 
00070 
00071 
00072       // building images
00073 
00074       template <class Algo>
00075       typename Algo::bin_image_t // e.g., image2d<bool>
00076       level_root_image(const Algo& algo)
00077       {
00078         typedef typename Algo::bin_image_t B;
00079         B lroot(algo.f_().size());
00080         level::fill(lroot, false);
00081         oln_iter_type(B) p(algo.f_());
00082         for_all(p)
00083           if (algo.is_level_root_(p))
00084             lroot[p] = true;
00085         return lroot;
00086       }
00087 
00088 
00089       template <class Algo>
00090       typename Algo::int_u8_image_t
00091       tree_image(const Algo& algo, bool print_counts = false)
00092       {
00093         typedef typename Algo::point point;
00094         enum {
00095           unknown = 0, // temporary label
00096 
00097           // tree root (black)
00098           root = 1,
00099 
00100           // the following labels are for "not tree root" points
00101 
00102           // level roots are:
00103           // - intermediate (red) or
00104           intermediate_level_root = 2,
00105           // - leaf (green)
00106           leaf_level_root = 3,         // not root
00107 
00108           // some points belong to a path between a couple of level roots
00109           // (white)
00110           in_between_level_point = 6,
00111 
00112           // otherwise points are:
00113           // - leaf (blue)
00114           leaf_point = 4,
00115           // - intermediate (yellow)
00116           intermediate_point = 5
00117         };
00118 
00119         typedef typename Algo::int_u8_image_t T;
00120         T tree(algo.f_().size());
00121         level::fill(tree, unknown);
00122 
00123         oln_iter_type(T) p(algo.f_());
00124 
00125         for_all(p)
00126           if (algo.is_root_(p))
00127             tree[p] = root;
00128           else if (algo.is_level_root_(p))
00129             tree[p] = leaf_level_root; // but we do not know about 'leaf'
00130 
00131         for_all(p)
00132           if (algo.is_level_root_(p))
00133             {
00134               point q = p; // from p level root
00135               do
00136                 {
00137                   q = algo.parent_(q);
00138                   if (not algo.is_level_root_(q))
00139                     // we reach a non level root point
00140                     tree[q] = in_between_level_point;
00141                 }
00142               while (not algo.is_level_root_(q));
00143               // level root p --> level root q
00144               if (q != p and not algo.is_root_(q))
00145                 tree[q] = intermediate_level_root; // not leaf level root
00146             }
00147 
00148         for_all(p)
00149           {
00150             point par_p = algo.parent_(p);
00151             if (tree[par_p] == unknown)
00152               tree[par_p] = intermediate_point;
00153           }
00154         for_all(p)
00155           if (tree[p] == unknown)
00156             tree[p] = leaf_point;
00157 
00158         // printing
00159         if (print_counts)
00160           {
00161             unsigned
00162               n_roots = 0,
00163               n_intermediate_level_roots = 0,
00164               n_leaf_level_roots = 0,
00165               n_in_between_level_points = 0,
00166               n_leaf_points = 0,
00167               n_intermediate_points = 0;
00168 
00169             for_all(p)
00170               switch (tree[p]) {
00171               case root:
00172                 ++n_roots;
00173                 break;
00174               case intermediate_level_root:
00175                 ++n_intermediate_level_roots;
00176                 break;
00177               case leaf_level_root:
00178                 ++n_leaf_level_roots;
00179                 break;
00180               case in_between_level_point:
00181                 ++n_in_between_level_points;
00182                 break;
00183               case leaf_point:
00184                 ++n_leaf_points;
00185                 break;
00186               case intermediate_point:
00187                 ++n_intermediate_points;
00188                 break;
00189               }
00190 
00191             std::cout << "n roots               = " << n_roots << std::endl
00192                       << "n intermediate lroots = " << n_intermediate_level_roots << std::endl
00193                       << "n leaf lroots         = " << n_leaf_level_roots << std::endl
00194                       << "n in-between lpoint   = " << n_in_between_level_points << std::endl
00195                       << "n leaf points         = " << n_leaf_points << std::endl
00196                       << "n intermediate points = " << n_intermediate_points << std::endl;
00197 
00198           }
00199 
00200         return tree;
00201       }
00202 
00203 
00204 
00205       // comparing images
00206 
00207       template <class I1, class I2>
00208       bool
00209       check_equiv_label_images(const abstract::image<I1>& label1,
00210                                const abstract::image<I2>& label2)
00211       {
00212         assert(label1.size() == label2.size());
00213         std::map<unsigned, unsigned> m;
00214         oln_iter_type(I1) p(label1);
00215         for_all(p)
00216           {
00217             if (m.find(label1[p]) == m.end())
00218               m[label1[p]] = label2[p];
00219             else
00220               if (label2[p] != m[label1[p]])
00221                 return false;
00222           }
00223         return true;
00224       }
00225 
00226 
00227 
00228       // invariant checking
00229 
00230       template <class Algo>
00231       bool check_f_par_p_leq_f_p(const Algo& algo)
00232         // f(par(p)) <= f(p)
00233       {
00234         typedef typename Algo::image I;
00235         oln_iter_type(I) p(algo.f_());
00236         for_all(p)
00237           if (not (algo.f_(algo.parent_(p)) <= algo.f_(p)))
00238             {
00239               std::cerr << "invariant FAILED: f(par(p)) <= f(p)"
00240                         << std::endl;
00241               return false;
00242             }
00243         return true;
00244       }
00245 
00246 
00247 
00248       // some tests
00249 
00250       template <class Algo>
00251       bool is_level_compression_completed(const Algo& algo)
00252       {
00253         typedef typename Algo::image I;
00254         oln_iter_type(I) p(algo.f_());
00255         for_all(p)
00256           if (not is_level_root(algo.parent_(p)))
00257             {
00258               std::cerr << "test FAILED: level compression is NOT completed"
00259                         << std::endl;
00260               return false;
00261             }
00262         return true;
00263       }
00264 
00265 
00266     } // end of namespace oln::lrde::ufmt
00267 
00268   } // end of namespace oln::lrde
00269 
00270 } // end of namespace oln
00271 
00272 
00273 #endif // ! OLENA_LRDE_UFMT_LOG_HH

Generated on Tue Feb 20 20:20:07 2007 for Olena by  doxygen 1.5.1