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: keir@google.com (Keir Mierle)
30//
31// A jacobian writer that directly writes to compressed row sparse matrices.
32
33#ifndef CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_
34#define CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_
35
36#include "ceres/evaluator.h"
37#include "ceres/scratch_evaluate_preparer.h"
38
39namespace ceres {
40namespace internal {
41
42class CompressedRowSparseMatrix;
43class Program;
44class SparseMatrix;
45
46class CompressedRowJacobianWriter {
47 public:
48  CompressedRowJacobianWriter(Evaluator::Options /* ignored */,
49                              Program* program)
50    : program_(program) {
51  }
52
53  // PopulateJacobianRowAndColumnBlockVectors sets col_blocks and
54  // row_blocks for a CompressedRowSparseMatrix, based on the
55  // parameter block sizes and residual sizes respectively from the
56  // program. This is useful when Solver::Options::use_block_amd =
57  // true;
58  //
59  // This function is static so that it is available to other jacobian
60  // writers which use CompressedRowSparseMatrix (or derived types).
61  // (Jacobian writers do not fall under any type hierarchy; they only
62  // have to provide an interface as specified in program_evaluator.h).
63  static void PopulateJacobianRowAndColumnBlockVectors(
64      const Program* program,
65      CompressedRowSparseMatrix* jacobian);
66
67  // It is necessary to determine the order of the jacobian blocks
68  // before copying them into a CompressedRowSparseMatrix (or derived
69  // type).  Just because a cost function uses parameter blocks 1
70  // after 2 in its arguments does not mean that the block 1 occurs
71  // before block 2 in the column layout of the jacobian. Thus,
72  // GetOrderedParameterBlocks determines the order by sorting the
73  // jacobian blocks by their position in the state vector.
74  //
75  // This function is static so that it is available to other jacobian
76  // writers which use CompressedRowSparseMatrix (or derived types).
77  // (Jacobian writers do not fall under any type hierarchy; they only
78  // have to provide an interface as specified in
79  // program_evaluator.h).
80  static void GetOrderedParameterBlocks(
81      const Program* program,
82      int residual_id,
83      vector<pair<int, int> >* evaluated_jacobian_blocks);
84
85  // JacobianWriter interface.
86
87  // Since the compressed row matrix has different layout than that
88  // assumed by the cost functions, use scratch space to store the
89  // jacobians temporarily then copy them over to the larger jacobian
90  // in the Write() function.
91  ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads) {
92    return ScratchEvaluatePreparer::Create(*program_, num_threads);
93  }
94
95  SparseMatrix* CreateJacobian() const;
96
97  void Write(int residual_id,
98             int residual_offset,
99             double **jacobians,
100             SparseMatrix* base_jacobian);
101
102 private:
103  Program* program_;
104};
105
106}  // namespace internal
107}  // namespace ceres
108
109#endif  // CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_
110