// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: keir@google.com (Keir Mierle)
//
// A jacobian writer that directly writes to compressed row sparse matrices.

#ifndef CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_
#define CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_

#include "ceres/evaluator.h"
#include "ceres/scratch_evaluate_preparer.h"

namespace ceres {
namespace internal {

class CompressedRowSparseMatrix;
class Program;
class SparseMatrix;

class CompressedRowJacobianWriter {
 public:
  CompressedRowJacobianWriter(Evaluator::Options /* ignored */,
                              Program* program)
    : program_(program) {
  }

  // PopulateJacobianRowAndColumnBlockVectors sets col_blocks and
  // row_blocks for a CompressedRowSparseMatrix, based on the
  // parameter block sizes and residual sizes respectively from the
  // program. This is useful when Solver::Options::use_block_amd =
  // true;
  //
  // This function is static so that it is available to other jacobian
  // writers which use CompressedRowSparseMatrix (or derived types).
  // (Jacobian writers do not fall under any type hierarchy; they only
  // have to provide an interface as specified in program_evaluator.h).
  static void PopulateJacobianRowAndColumnBlockVectors(
      const Program* program,
      CompressedRowSparseMatrix* jacobian);

  // It is necessary to determine the order of the jacobian blocks
  // before copying them into a CompressedRowSparseMatrix (or derived
  // type).  Just because a cost function uses parameter blocks 1
  // after 2 in its arguments does not mean that the block 1 occurs
  // before block 2 in the column layout of the jacobian. Thus,
  // GetOrderedParameterBlocks determines the order by sorting the
  // jacobian blocks by their position in the state vector.
  //
  // This function is static so that it is available to other jacobian
  // writers which use CompressedRowSparseMatrix (or derived types).
  // (Jacobian writers do not fall under any type hierarchy; they only
  // have to provide an interface as specified in
  // program_evaluator.h).
  static void GetOrderedParameterBlocks(
      const Program* program,
      int residual_id,
      vector<pair<int, int> >* evaluated_jacobian_blocks);

  // JacobianWriter interface.

  // Since the compressed row matrix has different layout than that
  // assumed by the cost functions, use scratch space to store the
  // jacobians temporarily then copy them over to the larger jacobian
  // in the Write() function.
  ScratchEvaluatePreparer* CreateEvaluatePreparers(int num_threads) {
    return ScratchEvaluatePreparer::Create(*program_, num_threads);
  }

  SparseMatrix* CreateJacobian() const;

  void Write(int residual_id,
             int residual_offset,
             double **jacobians,
             SparseMatrix* base_jacobian);

 private:
  Program* program_;
};

}  // namespace internal
}  // namespace ceres

#endif  // CERES_INTERNAL_COMPRESSED_ROW_JACOBIAN_WRITER_H_
