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: sameeragarwal (at) google.com (Sameer Agarwal)
     30 
     31 #include "ceres/detect_structure.h"
     32 #include "ceres/internal/eigen.h"
     33 #include "glog/logging.h"
     34 
     35 namespace ceres {
     36 namespace internal {
     37 
     38 void DetectStructure(const CompressedRowBlockStructure& bs,
     39                      const int num_eliminate_blocks,
     40                      int* row_block_size,
     41                      int* e_block_size,
     42                      int* f_block_size) {
     43   const int num_row_blocks = bs.rows.size();
     44   *row_block_size = 0;
     45   *e_block_size = 0;
     46   *f_block_size = 0;
     47 
     48   // Iterate over row blocks of the matrix, checking if row_block,
     49   // e_block or f_block sizes remain constant.
     50   for (int r = 0; r < num_row_blocks; ++r) {
     51     const CompressedRow& row = bs.rows[r];
     52     // We do not care about the sizes of the blocks in rows which do
     53     // not contain e_blocks.
     54     if (row.cells.front().block_id >= num_eliminate_blocks) {
     55       break;
     56     }
     57     const int e_block_id = row.cells.front().block_id;
     58 
     59     if (*row_block_size == 0) {
     60       *row_block_size = row.block.size;
     61     } else if (*row_block_size != Eigen::Dynamic &&
     62                *row_block_size != row.block.size) {
     63       VLOG(2) << "Dynamic row block size because the block size changed from "
     64               << *row_block_size << " to "
     65               << row.block.size;
     66       *row_block_size = Eigen::Dynamic;
     67     }
     68 
     69 
     70     if (*e_block_size == 0) {
     71       *e_block_size = bs.cols[e_block_id].size;
     72     } else if (*e_block_size != Eigen::Dynamic &&
     73                *e_block_size != bs.cols[e_block_id].size) {
     74       VLOG(2) << "Dynamic e block size because the block size changed from "
     75               << *e_block_size << " to "
     76               << bs.cols[e_block_id].size;
     77       *e_block_size = Eigen::Dynamic;
     78     }
     79 
     80     if (*f_block_size == 0) {
     81       if (row.cells.size() > 1) {
     82         const int f_block_id = row.cells[1].block_id;
     83         *f_block_size = bs.cols[f_block_id].size;
     84       }
     85     } else if (*f_block_size != Eigen::Dynamic) {
     86       for (int c = 1; c < row.cells.size(); ++c) {
     87         if (*f_block_size != bs.cols[row.cells[c].block_id].size) {
     88           VLOG(2) << "Dynamic f block size because the block size "
     89                   << "changed from " << *f_block_size << " to "
     90                   << bs.cols[row.cells[c].block_id].size;
     91           *f_block_size = Eigen::Dynamic;
     92           break;
     93         }
     94       }
     95     }
     96 
     97     const bool is_everything_dynamic = (*row_block_size == Eigen::Dynamic &&
     98                                         *e_block_size == Eigen::Dynamic &&
     99                                         *f_block_size == Eigen::Dynamic);
    100     if (is_everything_dynamic) {
    101       break;
    102     }
    103   }
    104 
    105   CHECK_NE(*row_block_size, 0) << "No rows found";
    106   CHECK_NE(*e_block_size, 0) << "No e type blocks found";
    107   VLOG(1) << "Schur complement static structure <"
    108           << *row_block_size << ","
    109           << *e_block_size << ","
    110           << *f_block_size << ">.";
    111 }
    112 
    113 }  // namespace internal
    114 }  // namespace ceres
    115