Home | History | Annotate | Download | only in ceres
      1 // Ceres Solver - A fast non-linear least squares minimizer
      2 // Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
      3 // http://code.google.com/p/ceres-solver/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are met:
      7 //
      8 // * Redistributions of source code must retain the above copyright notice,
      9 //   this list of conditions and the following disclaimer.
     10 // * Redistributions in binary form must reproduce the above copyright notice,
     11 //   this list of conditions and the following disclaimer in the documentation
     12 //   and/or other materials provided with the distribution.
     13 // * Neither the name of Google Inc. nor the names of its contributors may be
     14 //   used to endorse or promote products derived from this software without
     15 //   specific prior written permission.
     16 //
     17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27 // POSSIBILITY OF SUCH DAMAGE.
     28 //
     29 // Author: Sameer Agarwal (sameeragarwal (at) google.com)
     30 //         David Gallup (dgallup (at) google.com)
     31 
     32 // This include must come before any #ifndef check on Ceres compile options.
     33 #include "ceres/internal/port.h"
     34 
     35 #ifndef CERES_NO_SUITESPARSE
     36 
     37 #include "ceres/canonical_views_clustering.h"
     38 
     39 #include "ceres/collections_port.h"
     40 #include "ceres/graph.h"
     41 #include "gtest/gtest.h"
     42 
     43 namespace ceres {
     44 namespace internal {
     45 
     46 const int kVertexIds[] = {0, 1, 2, 3};
     47 class CanonicalViewsTest : public ::testing::Test {
     48  protected:
     49   virtual void SetUp() {
     50     // The graph structure is as follows.
     51     //
     52     // Vertex weights:   0      2      2      0
     53     //                   V0-----V1-----V2-----V3
     54     // Edge weights:        0.8    0.9    0.3
     55     const double kVertexWeights[] = {0.0, 2.0, 2.0, -1.0};
     56     for (int i = 0; i < 4; ++i) {
     57       graph_.AddVertex(i, kVertexWeights[i]);
     58     }
     59     // Create self edges.
     60     // CanonicalViews requires that every view "sees" itself.
     61     for (int i = 0; i < 4; ++i) {
     62       graph_.AddEdge(i, i, 1.0);
     63     }
     64 
     65     // Create three edges.
     66     const double kEdgeWeights[] = {0.8, 0.9, 0.3};
     67     for (int i = 0; i < 3; ++i) {
     68       // The graph interface is directed, so remember to create both
     69       // edges.
     70       graph_.AddEdge(kVertexIds[i], kVertexIds[i + 1], kEdgeWeights[i]);
     71     }
     72   }
     73 
     74   void ComputeClustering() {
     75     ComputeCanonicalViewsClustering(options_, graph_, &centers_, &membership_);
     76   }
     77 
     78   Graph<int> graph_;
     79 
     80   CanonicalViewsClusteringOptions options_;
     81   vector<int> centers_;
     82   HashMap<int, int> membership_;
     83 };
     84 
     85 TEST_F(CanonicalViewsTest, ComputeCanonicalViewsTest) {
     86   options_.min_views = 0;
     87   options_.size_penalty_weight = 0.5;
     88   options_.similarity_penalty_weight = 0.0;
     89   options_.view_score_weight = 0.0;
     90   ComputeClustering();
     91 
     92   // 2 canonical views.
     93   EXPECT_EQ(centers_.size(), 2);
     94   EXPECT_EQ(centers_[0], kVertexIds[1]);
     95   EXPECT_EQ(centers_[1], kVertexIds[3]);
     96 
     97   // Check cluster membership.
     98   EXPECT_EQ(FindOrDie(membership_, kVertexIds[0]), 0);
     99   EXPECT_EQ(FindOrDie(membership_, kVertexIds[1]), 0);
    100   EXPECT_EQ(FindOrDie(membership_, kVertexIds[2]), 0);
    101   EXPECT_EQ(FindOrDie(membership_, kVertexIds[3]), 1);
    102 }
    103 
    104 // Increases size penalty so the second canonical view won't be
    105 // chosen.
    106 TEST_F(CanonicalViewsTest, SizePenaltyTest) {
    107   options_.min_views = 0;
    108   options_.size_penalty_weight = 2.0;
    109   options_.similarity_penalty_weight = 0.0;
    110   options_.view_score_weight = 0.0;
    111   ComputeClustering();
    112 
    113   // 1 canonical view.
    114   EXPECT_EQ(centers_.size(), 1);
    115   EXPECT_EQ(centers_[0], kVertexIds[1]);
    116 }
    117 
    118 
    119 // Increases view score weight so vertex 2 will be chosen.
    120 TEST_F(CanonicalViewsTest, ViewScoreTest) {
    121   options_.min_views = 0;
    122   options_.size_penalty_weight = 0.5;
    123   options_.similarity_penalty_weight = 0.0;
    124   options_.view_score_weight = 1.0;
    125   ComputeClustering();
    126 
    127   // 2 canonical views.
    128   EXPECT_EQ(centers_.size(), 2);
    129   EXPECT_EQ(centers_[0], kVertexIds[1]);
    130   EXPECT_EQ(centers_[1], kVertexIds[2]);
    131 }
    132 
    133 // Increases similarity penalty so vertex 2 won't be chosen despite
    134 // it's view score.
    135 TEST_F(CanonicalViewsTest, SimilarityPenaltyTest) {
    136   options_.min_views = 0;
    137   options_.size_penalty_weight = 0.5;
    138   options_.similarity_penalty_weight = 3.0;
    139   options_.view_score_weight = 1.0;
    140   ComputeClustering();
    141 
    142   // 2 canonical views.
    143   EXPECT_EQ(centers_.size(), 1);
    144   EXPECT_EQ(centers_[0], kVertexIds[1]);
    145 }
    146 
    147 }  // namespace internal
    148 }  // namespace ceres
    149 
    150 #endif  // CERES_NO_SUITESPARSE
    151