// 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 writes to block sparse matrices. The "writer" name is
// misleading, since the Write() operation on the block jacobian writer does not
// write anything. Instead, the Prepare() method on the BlockEvaluatePreparers
// makes a jacobians array which has direct pointers into the block sparse
// jacobian. When the cost function is evaluated, the jacobian blocks get placed
// directly in their final location.

#ifndef CERES_INTERNAL_BLOCK_JACOBIAN_WRITER_H_
#define CERES_INTERNAL_BLOCK_JACOBIAN_WRITER_H_

#include <vector>
#include "ceres/evaluator.h"
#include "ceres/internal/port.h"

namespace ceres {
namespace internal {

class BlockEvaluatePreparer;
class Program;
class SparseMatrix;

class BlockJacobianWriter {
 public:
  BlockJacobianWriter(const Evaluator::Options& options,
                      Program* program);

  // JacobianWriter interface.

  // Create evaluate prepareres that point directly into the final jacobian.
  // This makes the final Write() a nop.
  BlockEvaluatePreparer* CreateEvaluatePreparers(int num_threads);

  SparseMatrix* CreateJacobian() const;

  void Write(int /* residual_id */,
             int /* residual_offset */,
             double** /* jacobians */,
             SparseMatrix* /* jacobian */) {
    // This is a noop since the blocks were written directly into their final
    // position by the outside evaluate call, thanks to the jacobians array
    // prepared by the BlockEvaluatePreparers.
  }

 private:
  Program* program_;

  // Stores the position of each residual / parameter jacobian.
  //
  // The block sparse matrix that this writer writes to is stored as a set of
  // contiguos dense blocks, one after each other; see BlockSparseMatrix. The
  // "double* values_" member of the block sparse matrix contains all of these
  // blocks. Given a pointer to the first element of a block and the size of
  // that block, it's possible to write to it.
  //
  // In the case of a block sparse jacobian, the jacobian writer needs a way to
  // find the offset in the values_ array of each residual/parameter jacobian
  // block.
  //
  // That is the purpose of jacobian_layout_.
  //
  // In particular, jacobian_layout_[i][j] is the offset in the values_ array of
  // the derivative of residual block i with respect to the parameter block at
  // active argument position j.
  //
  // The active qualifier means that non-active parameters do not count. Care
  // must be taken when indexing into jacobian_layout_ to account for this.
  // Consider a single residual example:
  //
  //   r(x, y, z)
  //
  // with r in R^3, x in R^4, y in R^2, and z in R^5.
  // Take y as a constant (non-active) parameter.
  // Take r as residual number 0.
  //
  // In this case, the active arguments are only (x, z), so the active argument
  // position for x is 0, and the active argument position for z is 1. This is
  // similar to thinking of r as taking only 2 parameters:
  //
  //   r(x, z)
  //
  // There are only 2 jacobian blocks: dr/dx and dr/dz. jacobian_layout_ would
  // have the following contents:
  //
  //   jacobian_layout_[0] = { 0, 12 }
  //
  // which indicates that dr/dx is located at values_[0], and dr/dz is at
  // values_[12]. See BlockEvaluatePreparer::Prepare()'s comments about 'j'.
  vector<int*> jacobian_layout_;

  // The pointers in jacobian_layout_ point directly into this vector.
  vector<int> jacobian_layout_storage_;
};

}  // namespace internal
}  // namespace ceres

#endif  // CERES_INTERNAL_BLOCK_JACOBIAN_WRITER_H_
