10ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Ceres Solver - A fast non-linear least squares minimizer
20ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
30ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// http://code.google.com/p/ceres-solver/
40ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
50ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Redistribution and use in source and binary forms, with or without
60ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// modification, are permitted provided that the following conditions are met:
70ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
80ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions of source code must retain the above copyright notice,
90ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   this list of conditions and the following disclaimer.
100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Redistributions in binary form must reproduce the above copyright notice,
110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   this list of conditions and the following disclaimer in the documentation
120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   and/or other materials provided with the distribution.
130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// * Neither the name of Google Inc. nor the names of its contributors may be
140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   used to endorse or promote products derived from this software without
150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//   specific prior written permission.
160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// POSSIBILITY OF SUCH DAMAGE.
280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong//
290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// Author: sameeragarwal@google.com (Sameer Agarwal)
300ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
310ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#ifndef CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H_
320ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#define CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H_
330ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
340ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/sparse_matrix.h"
350ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/eigen.h"
360ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/internal/scoped_ptr.h"
370ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#include "ceres/types.h"
380ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
390ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace ceres {
400ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongnamespace internal {
410ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
420ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// An implementation of the SparseMatrix interface to store and
430ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// manipulate sparse matrices in triplet (i,j,s) form.  This object is
440ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// inspired by the design of the cholmod_triplet struct used in the
450ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong// SuiteSparse package and is memory layout compatible with it.
460ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kongclass TripletSparseMatrix : public SparseMatrix {
470ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong public:
480ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  TripletSparseMatrix();
490ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  TripletSparseMatrix(int num_rows, int num_cols, int max_num_nonzeros);
500ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  explicit TripletSparseMatrix(const TripletSparseMatrix& orig);
510ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
520ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  TripletSparseMatrix& operator=(const TripletSparseMatrix& rhs);
530ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
540ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  ~TripletSparseMatrix();
550ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
560ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // Implementation of the SparseMatrix interface.
570ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void SetZero();
580ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void RightMultiply(const double* x, double* y) const;
590ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void LeftMultiply(const double* x, double* y) const;
600ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void SquaredColumnNorm(double* x) const;
610ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void ScaleColumns(const double* scale);
620ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void ToDenseMatrix(Matrix* dense_matrix) const;
630ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void ToTextFile(FILE* file) const;
640ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual int num_rows()        const { return num_rows_;     }
650ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual int num_cols()        const { return num_cols_;     }
660ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual int num_nonzeros()    const { return num_nonzeros_; }
670ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual const double* values()  const { return values_.get(); }
680ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual double* mutable_values()      { return values_.get(); }
690ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  virtual void set_num_nonzeros(int num_nonzeros);
700ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
710ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // Increase max_num_nonzeros and correspondingly increase the size
720ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // of rows_, cols_ and values_. If new_max_num_nonzeros is smaller
730ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // than max_num_nonzeros_, then num_non_zeros should be less than or
740ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // equal to new_max_num_nonzeros, otherwise data loss is possible
750ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // and the method crashes.
760ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void Reserve(int new_max_num_nonzeros);
770ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
780ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // Append the matrix B at the bottom of this matrix. B should have
790ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // the same number of columns as num_cols_.
800ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void AppendRows(const TripletSparseMatrix& B);
810ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
820ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // Append the matrix B at the right of this matrix. B should have
830ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // the same number of rows as num_rows_;
840ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void AppendCols(const TripletSparseMatrix& B);
850ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
860ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // Resize the matrix. Entries which fall outside the new matrix
870ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // bounds are dropped and the num_non_zeros changed accordingly.
880ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void Resize(int new_num_rows, int new_num_cols);
890ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
900ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int max_num_nonzeros() const { return max_num_nonzeros_; }
910ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const int* rows()      const { return rows_.get();       }
920ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  const int* cols()      const { return cols_.get();       }
930ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int* mutable_rows()          { return rows_.get();       }
940ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int* mutable_cols()          { return cols_.get();       }
950ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
960ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // Returns true if the entries of the matrix obey the row, column,
970ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // and column size bounds and false otherwise.
980ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  bool AllTripletsWithinBounds() const;
990ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1000ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  bool IsValid() const { return AllTripletsWithinBounds(); }
1010ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1020ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // Build a sparse diagonal matrix of size num_rows x num_rows from
1030ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // the array values. Entries of the values array are copied into the
1040ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // sparse matrix.
1050ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  static TripletSparseMatrix* CreateSparseDiagonalMatrix(const double* values,
1060ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong                                                         int num_rows);
1070ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1080ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong private:
1090ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void AllocateMemory();
1100ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  void CopyData(const TripletSparseMatrix& orig);
1110ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1120ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int num_rows_;
1130ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int num_cols_;
1140ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int max_num_nonzeros_;
1150ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  int num_nonzeros_;
1160ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1170ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // The data is stored as three arrays. For each i, values_[i] is
1180ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // stored at the location (rows_[i], cols_[i]). If the there are
1190ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // multiple entries with the same (rows_[i], cols_[i]), the values_
1200ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  // entries corresponding to them are summed up.
1210ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  scoped_array<int> rows_;
1220ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  scoped_array<int> cols_;
1230ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong  scoped_array<double> values_;
1240ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong};
1250ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1260ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace internal
1270ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong}  // namespace ceres
1280ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong
1290ae28bd5885b5daa526898fcf7c323dc2c3e1963Angus Kong#endif  // CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H__
130