179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Ceres Solver - A fast non-linear least squares minimizer
279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Copyright 2014 Google Inc. All rights reserved.
379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// http://code.google.com/p/ceres-solver/
479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//
579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Redistribution and use in source and binary forms, with or without
679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// modification, are permitted provided that the following conditions are met:
779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//
879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// * Redistributions of source code must retain the above copyright notice,
979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//   this list of conditions and the following disclaimer.
1079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// * Redistributions in binary form must reproduce the above copyright notice,
1179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//   this list of conditions and the following disclaimer in the documentation
1279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//   and/or other materials provided with the distribution.
1379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// * Neither the name of Google Inc. nor the names of its contributors may be
1479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//   used to endorse or promote products derived from this software without
1579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//   specific prior written permission.
1679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//
1779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// POSSIBILITY OF SUCH DAMAGE.
2879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez//
2979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez// Author: richie.stebbing@gmail.com (Richard Stebbing)
3079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
3179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/dynamic_compressed_row_sparse_matrix.h"
3279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
3379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/casts.h"
3479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/compressed_row_sparse_matrix.h"
3579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/casts.h"
3679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/internal/eigen.h"
3779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/internal/scoped_ptr.h"
3879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/linear_least_squares_problems.h"
3979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "ceres/triplet_sparse_matrix.h"
4079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez#include "gtest/gtest.h"
4179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
4279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandeznamespace ceres {
4379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandeznamespace internal {
4479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
4579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandezclass DynamicCompressedRowSparseMatrixTest : public ::testing::Test {
4679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez protected:
4779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  virtual void SetUp() {
4879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    num_rows = 7;
4979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    num_cols = 4;
5079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
5179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    // The number of additional elements reserved when `Finalize` is called
5279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    // should have no effect on the number of rows, columns or nonzeros.
5379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    // Set this to some nonzero value to be sure.
5479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    num_additional_elements = 13;
5579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
5679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    expected_num_nonzeros = num_rows * num_cols - min(num_rows, num_cols);
5779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
5879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    InitialiseDenseReference();
5979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    InitialiseSparseMatrixReferences();
6079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
6179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    dcrsm.reset(new DynamicCompressedRowSparseMatrix(num_rows,
6279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                     num_cols,
6379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                                     0));
6479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
6579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
6679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  void Finalize() {
6779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    dcrsm->Finalize(num_additional_elements);
6879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
6979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
7079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  void InitialiseDenseReference() {
7179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    dense.resize(num_rows, num_cols);
7279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    dense.setZero();
7379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    int num_nonzeros = 0;
7479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    for (int i = 0; i < (num_rows * num_cols); ++i) {
7579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      const int r = i / num_cols, c = i % num_cols;
7679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      if (r != c) {
7779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        dense(r, c) = i + 1;
7879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        ++num_nonzeros;
7979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      }
8079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    }
8179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ASSERT_EQ(num_nonzeros, expected_num_nonzeros);
8279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
8379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
8479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  void InitialiseSparseMatrixReferences() {
8579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    std::vector<int> rows, cols;
8679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    std::vector<double> values;
8779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    for (int i = 0; i < (num_rows * num_cols); ++i) {
8879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      const int r = i / num_cols, c = i % num_cols;
8979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      if (r != c) {
9079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        rows.push_back(r);
9179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        cols.push_back(c);
9279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        values.push_back(i + 1);
9379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      }
9479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    }
9579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ASSERT_EQ(values.size(), expected_num_nonzeros);
9679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
9779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    tsm.reset(new TripletSparseMatrix(num_rows,
9879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                      num_cols,
9979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez                                      expected_num_nonzeros));
10079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    std::copy(rows.begin(), rows.end(), tsm->mutable_rows());
10179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    std::copy(cols.begin(), cols.end(), tsm->mutable_cols());
10279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    std::copy(values.begin(), values.end(), tsm->mutable_values());
10379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    tsm->set_num_nonzeros(values.size());
10479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
10579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    Matrix dense_from_tsm;
10679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    tsm->ToDenseMatrix(&dense_from_tsm);
10779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ASSERT_TRUE((dense.array() == dense_from_tsm.array()).all());
10879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
10979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    crsm.reset(new CompressedRowSparseMatrix(*tsm));
11079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    Matrix dense_from_crsm;
11179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    crsm->ToDenseMatrix(&dense_from_crsm);
11279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ASSERT_TRUE((dense.array() == dense_from_crsm.array()).all());
11379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
11479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
11579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  void InsertNonZeroEntriesFromDenseReference() {
11679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    for (int r = 0; r < num_rows; ++r) {
11779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      for (int c = 0; c < num_cols; ++c) {
11879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        const double& v = dense(r, c);
11979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        if (v != 0.0) {
12079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez          dcrsm->InsertEntry(r, c, v);
12179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez        }
12279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez      }
12379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    }
12479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
12579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
12679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  void ExpectEmpty() {
12779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_EQ(dcrsm->num_rows(), num_rows);
12879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_EQ(dcrsm->num_cols(), num_cols);
12979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_EQ(dcrsm->num_nonzeros(), 0);
13079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
13179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    Matrix dense_from_dcrsm;
13279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    dcrsm->ToDenseMatrix(&dense_from_dcrsm);
13379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_EQ(dense_from_dcrsm.rows(), num_rows);
13479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_EQ(dense_from_dcrsm.cols(), num_cols);
13579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_TRUE((dense_from_dcrsm.array() == 0.0).all());
13679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
13779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
13879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  void ExpectEqualToDenseReference() {
13979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    Matrix dense_from_dcrsm;
14079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    dcrsm->ToDenseMatrix(&dense_from_dcrsm);
14179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_TRUE((dense.array() == dense_from_dcrsm.array()).all());
14279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
14379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
14479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  void ExpectEqualToCompressedRowSparseMatrixReference() {
14579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    typedef Eigen::Map<const Eigen::VectorXi> ConstIntVectorRef;
14679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
14779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ConstIntVectorRef crsm_rows(crsm->rows(), crsm->num_rows() + 1);
14879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ConstIntVectorRef dcrsm_rows(dcrsm->rows(), dcrsm->num_rows() + 1);
14979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_TRUE((crsm_rows.array() == dcrsm_rows.array()).all());
15079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
15179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ConstIntVectorRef crsm_cols(crsm->cols(), crsm->num_nonzeros());
15279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ConstIntVectorRef dcrsm_cols(dcrsm->cols(), dcrsm->num_nonzeros());
15379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_TRUE((crsm_cols.array() == dcrsm_cols.array()).all());
15479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
15579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ConstVectorRef crsm_values(crsm->values(), crsm->num_nonzeros());
15679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    ConstVectorRef dcrsm_values(dcrsm->values(), dcrsm->num_nonzeros());
15779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez    EXPECT_TRUE((crsm_values.array() == dcrsm_values.array()).all());
15879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  }
15979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
16079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  int num_rows;
16179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  int num_cols;
16279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
16379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  int num_additional_elements;
16479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
16579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  int expected_num_nonzeros;
16679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
16779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  Matrix dense;
16879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  scoped_ptr<TripletSparseMatrix> tsm;
16979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  scoped_ptr<CompressedRowSparseMatrix> crsm;
17079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
17179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  scoped_ptr<DynamicCompressedRowSparseMatrix> dcrsm;
17279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez};
17379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
17479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezTEST_F(DynamicCompressedRowSparseMatrixTest, Initialization) {
17579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEmpty();
17679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
17779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  Finalize();
17879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEmpty();
17979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez}
18079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
18179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezTEST_F(DynamicCompressedRowSparseMatrixTest, InsertEntryAndFinalize) {
18279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  InsertNonZeroEntriesFromDenseReference();
18379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEmpty();
18479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
18579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  Finalize();
18679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToDenseReference();
18779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToCompressedRowSparseMatrixReference();
18879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez}
18979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
19079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos HernandezTEST_F(DynamicCompressedRowSparseMatrixTest, ClearRows) {
19179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  InsertNonZeroEntriesFromDenseReference();
19279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  Finalize();
19379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToDenseReference();
19479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToCompressedRowSparseMatrixReference();
19579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
19679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  dcrsm->ClearRows(0, 0);
19779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  Finalize();
19879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToDenseReference();
19979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToCompressedRowSparseMatrixReference();
20079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
20179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  dcrsm->ClearRows(0, num_rows);
20279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToCompressedRowSparseMatrixReference();
20379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
20479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  Finalize();
20579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEmpty();
20679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
20779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  InsertNonZeroEntriesFromDenseReference();
20879397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  dcrsm->ClearRows(1, 2);
20979397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  Finalize();
21079397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  dense.block(1, 0, 2, num_cols).setZero();
21179397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  ExpectEqualToDenseReference();
21279397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
21379397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez  InitialiseDenseReference();
21479397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez}
21579397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez
21679397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez}  // namespace internal
21779397c21138f54fcff6ec067b44b847f1f7e0e98Carlos Hernandez}  // namespace ceres
218