Blame internal/ceres/linear_least_squares_problems.cc

Packit ea1746
// Ceres Solver - A fast non-linear least squares minimizer
Packit ea1746
// Copyright 2015 Google Inc. All rights reserved.
Packit ea1746
// http://ceres-solver.org/
Packit ea1746
//
Packit ea1746
// Redistribution and use in source and binary forms, with or without
Packit ea1746
// modification, are permitted provided that the following conditions are met:
Packit ea1746
//
Packit ea1746
// * Redistributions of source code must retain the above copyright notice,
Packit ea1746
//   this list of conditions and the following disclaimer.
Packit ea1746
// * Redistributions in binary form must reproduce the above copyright notice,
Packit ea1746
//   this list of conditions and the following disclaimer in the documentation
Packit ea1746
//   and/or other materials provided with the distribution.
Packit ea1746
// * Neither the name of Google Inc. nor the names of its contributors may be
Packit ea1746
//   used to endorse or promote products derived from this software without
Packit ea1746
//   specific prior written permission.
Packit ea1746
//
Packit ea1746
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit ea1746
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit ea1746
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit ea1746
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Packit ea1746
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit ea1746
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit ea1746
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit ea1746
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Packit ea1746
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit ea1746
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
Packit ea1746
// POSSIBILITY OF SUCH DAMAGE.
Packit ea1746
//
Packit ea1746
// Author: sameeragarwal@google.com (Sameer Agarwal)
Packit ea1746
Packit ea1746
#include "ceres/linear_least_squares_problems.h"
Packit ea1746
Packit ea1746
#include <cstdio>
Packit ea1746
#include <string>
Packit ea1746
#include <vector>
Packit ea1746
#include "ceres/block_sparse_matrix.h"
Packit ea1746
#include "ceres/block_structure.h"
Packit ea1746
#include "ceres/casts.h"
Packit ea1746
#include "ceres/file.h"
Packit ea1746
#include "ceres/internal/scoped_ptr.h"
Packit ea1746
#include "ceres/stringprintf.h"
Packit ea1746
#include "ceres/triplet_sparse_matrix.h"
Packit ea1746
#include "ceres/types.h"
Packit ea1746
#include "glog/logging.h"
Packit ea1746
Packit ea1746
namespace ceres {
Packit ea1746
namespace internal {
Packit ea1746
Packit ea1746
using std::string;
Packit ea1746
Packit ea1746
LinearLeastSquaresProblem* CreateLinearLeastSquaresProblemFromId(int id) {
Packit ea1746
  switch (id) {
Packit ea1746
    case 0:
Packit ea1746
      return LinearLeastSquaresProblem0();
Packit ea1746
    case 1:
Packit ea1746
      return LinearLeastSquaresProblem1();
Packit ea1746
    case 2:
Packit ea1746
      return LinearLeastSquaresProblem2();
Packit ea1746
    case 3:
Packit ea1746
      return LinearLeastSquaresProblem3();
Packit ea1746
    case 4:
Packit ea1746
      return LinearLeastSquaresProblem4();
Packit ea1746
    default:
Packit ea1746
      LOG(FATAL) << "Unknown problem id requested " << id;
Packit ea1746
  }
Packit ea1746
  return NULL;
Packit ea1746
}
Packit ea1746
Packit ea1746
/*
Packit ea1746
A = [1   2]
Packit ea1746
    [3   4]
Packit ea1746
    [6 -10]
Packit ea1746
Packit ea1746
b = [  8
Packit ea1746
      18
Packit ea1746
     -18]
Packit ea1746
Packit ea1746
x = [2
Packit ea1746
     3]
Packit ea1746
Packit ea1746
D = [1
Packit ea1746
     2]
Packit ea1746
Packit ea1746
x_D = [1.78448275;
Packit ea1746
       2.82327586;]
Packit ea1746
 */
Packit ea1746
LinearLeastSquaresProblem* LinearLeastSquaresProblem0() {
Packit ea1746
  LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem;
Packit ea1746
Packit ea1746
  TripletSparseMatrix* A = new TripletSparseMatrix(3, 2, 6);
Packit ea1746
  problem->b.reset(new double[3]);
Packit ea1746
  problem->D.reset(new double[2]);
Packit ea1746
Packit ea1746
  problem->x.reset(new double[2]);
Packit ea1746
  problem->x_D.reset(new double[2]);
Packit ea1746
Packit ea1746
  int* Ai = A->mutable_rows();
Packit ea1746
  int* Aj = A->mutable_cols();
Packit ea1746
  double* Ax = A->mutable_values();
Packit ea1746
Packit ea1746
  int counter = 0;
Packit ea1746
  for (int i = 0; i < 3; ++i) {
Packit ea1746
    for (int j = 0; j< 2; ++j) {
Packit ea1746
      Ai[counter] = i;
Packit ea1746
      Aj[counter] = j;
Packit ea1746
      ++counter;
Packit ea1746
    }
Packit ea1746
  }
Packit ea1746
Packit ea1746
  Ax[0] = 1.;
Packit ea1746
  Ax[1] = 2.;
Packit ea1746
  Ax[2] = 3.;
Packit ea1746
  Ax[3] = 4.;
Packit ea1746
  Ax[4] = 6;
Packit ea1746
  Ax[5] = -10;
Packit ea1746
  A->set_num_nonzeros(6);
Packit ea1746
  problem->A.reset(A);
Packit ea1746
Packit ea1746
  problem->b[0] = 8;
Packit ea1746
  problem->b[1] = 18;
Packit ea1746
  problem->b[2] = -18;
Packit ea1746
Packit ea1746
  problem->x[0] = 2.0;
Packit ea1746
  problem->x[1] = 3.0;
Packit ea1746
Packit ea1746
  problem->D[0] = 1;
Packit ea1746
  problem->D[1] = 2;
Packit ea1746
Packit ea1746
  problem->x_D[0] = 1.78448275;
Packit ea1746
  problem->x_D[1] = 2.82327586;
Packit ea1746
  return problem;
Packit ea1746
}
Packit ea1746
Packit ea1746
Packit ea1746
/*
Packit ea1746
      A = [1 0  | 2 0 0
Packit ea1746
           3 0  | 0 4 0
Packit ea1746
           0 5  | 0 0 6
Packit ea1746
           0 7  | 8 0 0
Packit ea1746
           0 9  | 1 0 0
Packit ea1746
           0 0  | 1 1 1]
Packit ea1746
Packit ea1746
      b = [0
Packit ea1746
           1
Packit ea1746
           2
Packit ea1746
           3
Packit ea1746
           4
Packit ea1746
           5]
Packit ea1746
Packit ea1746
      c = A'* b = [ 3
Packit ea1746
                   67
Packit ea1746
                   33
Packit ea1746
                    9
Packit ea1746
                   17]
Packit ea1746
Packit ea1746
      A'A = [10    0    2   12   0
Packit ea1746
              0  155   65    0  30
Packit ea1746
              2   65   70    1   1
Packit ea1746
             12    0    1   17   1
Packit ea1746
              0   30    1    1  37]
Packit ea1746
Packit ea1746
      S = [ 42.3419  -1.4000  -11.5806
Packit ea1746
            -1.4000   2.6000    1.0000
Packit ea1746
            11.5806   1.0000   31.1935]
Packit ea1746
Packit ea1746
      r = [ 4.3032
Packit ea1746
            5.4000
Packit ea1746
            5.0323]
Packit ea1746
Packit ea1746
      S\r = [ 0.2102
Packit ea1746
              2.1367
Packit ea1746
              0.1388]
Packit ea1746
Packit ea1746
      A\b = [-2.3061
Packit ea1746
              0.3172
Packit ea1746
              0.2102
Packit ea1746
              2.1367
Packit ea1746
              0.1388]
Packit ea1746
*/
Packit ea1746
// The following two functions create a TripletSparseMatrix and a
Packit ea1746
// BlockSparseMatrix version of this problem.
Packit ea1746
Packit ea1746
// TripletSparseMatrix version.
Packit ea1746
LinearLeastSquaresProblem* LinearLeastSquaresProblem1() {
Packit ea1746
  int num_rows = 6;
Packit ea1746
  int num_cols = 5;
Packit ea1746
Packit ea1746
  LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem;
Packit ea1746
  TripletSparseMatrix* A = new TripletSparseMatrix(num_rows,
Packit ea1746
                                                   num_cols,
Packit ea1746
                                                   num_rows * num_cols);
Packit ea1746
  problem->b.reset(new double[num_rows]);
Packit ea1746
  problem->D.reset(new double[num_cols]);
Packit ea1746
  problem->num_eliminate_blocks = 2;
Packit ea1746
Packit ea1746
  int* rows = A->mutable_rows();
Packit ea1746
  int* cols = A->mutable_cols();
Packit ea1746
  double* values = A->mutable_values();
Packit ea1746
Packit ea1746
  int nnz = 0;
Packit ea1746
Packit ea1746
  // Row 1
Packit ea1746
  {
Packit ea1746
    rows[nnz] = 0;
Packit ea1746
    cols[nnz] = 0;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
Packit ea1746
    rows[nnz] = 0;
Packit ea1746
    cols[nnz] = 2;
Packit ea1746
    values[nnz++] = 2;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 2
Packit ea1746
  {
Packit ea1746
    rows[nnz] = 1;
Packit ea1746
    cols[nnz] = 0;
Packit ea1746
    values[nnz++] = 3;
Packit ea1746
Packit ea1746
    rows[nnz] = 1;
Packit ea1746
    cols[nnz] = 3;
Packit ea1746
    values[nnz++] = 4;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 3
Packit ea1746
  {
Packit ea1746
    rows[nnz] = 2;
Packit ea1746
    cols[nnz] = 1;
Packit ea1746
    values[nnz++] = 5;
Packit ea1746
Packit ea1746
    rows[nnz] = 2;
Packit ea1746
    cols[nnz] = 4;
Packit ea1746
    values[nnz++] = 6;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 4
Packit ea1746
  {
Packit ea1746
    rows[nnz] = 3;
Packit ea1746
    cols[nnz] = 1;
Packit ea1746
    values[nnz++] = 7;
Packit ea1746
Packit ea1746
    rows[nnz] = 3;
Packit ea1746
    cols[nnz] = 2;
Packit ea1746
    values[nnz++] = 8;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 5
Packit ea1746
  {
Packit ea1746
    rows[nnz] = 4;
Packit ea1746
    cols[nnz] = 1;
Packit ea1746
    values[nnz++] = 9;
Packit ea1746
Packit ea1746
    rows[nnz] = 4;
Packit ea1746
    cols[nnz] = 2;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 6
Packit ea1746
  {
Packit ea1746
    rows[nnz] = 5;
Packit ea1746
    cols[nnz] = 2;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
Packit ea1746
    rows[nnz] = 5;
Packit ea1746
    cols[nnz] = 3;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
Packit ea1746
    rows[nnz] = 5;
Packit ea1746
    cols[nnz] = 4;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  A->set_num_nonzeros(nnz);
Packit ea1746
  CHECK(A->IsValid());
Packit ea1746
Packit ea1746
  problem->A.reset(A);
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_cols; ++i) {
Packit ea1746
    problem->D.get()[i] = 1;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_rows; ++i) {
Packit ea1746
    problem->b.get()[i] = i;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  return problem;
Packit ea1746
}
Packit ea1746
Packit ea1746
// BlockSparseMatrix version
Packit ea1746
LinearLeastSquaresProblem* LinearLeastSquaresProblem2() {
Packit ea1746
  int num_rows = 6;
Packit ea1746
  int num_cols = 5;
Packit ea1746
Packit ea1746
  LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem;
Packit ea1746
Packit ea1746
  problem->b.reset(new double[num_rows]);
Packit ea1746
  problem->D.reset(new double[num_cols]);
Packit ea1746
  problem->num_eliminate_blocks = 2;
Packit ea1746
Packit ea1746
  CompressedRowBlockStructure* bs = new CompressedRowBlockStructure;
Packit ea1746
  scoped_array<double> values(new double[num_rows * num_cols]);
Packit ea1746
Packit ea1746
  for (int c = 0; c < num_cols; ++c) {
Packit ea1746
    bs->cols.push_back(Block());
Packit ea1746
    bs->cols.back().size = 1;
Packit ea1746
    bs->cols.back().position = c;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  int nnz = 0;
Packit ea1746
Packit ea1746
  // Row 1
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    values[nnz++] = 2;
Packit ea1746
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 0;
Packit ea1746
    row.cells.push_back(Cell(0, 0));
Packit ea1746
    row.cells.push_back(Cell(2, 1));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 2
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 3;
Packit ea1746
    values[nnz++] = 4;
Packit ea1746
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 1;
Packit ea1746
    row.cells.push_back(Cell(0, 2));
Packit ea1746
    row.cells.push_back(Cell(3, 3));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 3
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 5;
Packit ea1746
    values[nnz++] = 6;
Packit ea1746
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 2;
Packit ea1746
    row.cells.push_back(Cell(1, 4));
Packit ea1746
    row.cells.push_back(Cell(4, 5));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 4
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 7;
Packit ea1746
    values[nnz++] = 8;
Packit ea1746
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 3;
Packit ea1746
    row.cells.push_back(Cell(1, 6));
Packit ea1746
    row.cells.push_back(Cell(2, 7));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 5
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 9;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 4;
Packit ea1746
    row.cells.push_back(Cell(1, 8));
Packit ea1746
    row.cells.push_back(Cell(2, 9));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 6
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 5;
Packit ea1746
    row.cells.push_back(Cell(2, 10));
Packit ea1746
    row.cells.push_back(Cell(3, 11));
Packit ea1746
    row.cells.push_back(Cell(4, 12));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  BlockSparseMatrix* A = new BlockSparseMatrix(bs);
Packit ea1746
  memcpy(A->mutable_values(), values.get(), nnz * sizeof(*A->values()));
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_cols; ++i) {
Packit ea1746
    problem->D.get()[i] = 1;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_rows; ++i) {
Packit ea1746
    problem->b.get()[i] = i;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  problem->A.reset(A);
Packit ea1746
Packit ea1746
  return problem;
Packit ea1746
}
Packit ea1746
Packit ea1746
Packit ea1746
/*
Packit ea1746
      A = [1 0
Packit ea1746
           3 0
Packit ea1746
           0 5
Packit ea1746
           0 7
Packit ea1746
           0 9
Packit ea1746
           0 0]
Packit ea1746
Packit ea1746
      b = [0
Packit ea1746
           1
Packit ea1746
           2
Packit ea1746
           3
Packit ea1746
           4
Packit ea1746
           5]
Packit ea1746
*/
Packit ea1746
// BlockSparseMatrix version
Packit ea1746
LinearLeastSquaresProblem* LinearLeastSquaresProblem3() {
Packit ea1746
  int num_rows = 5;
Packit ea1746
  int num_cols = 2;
Packit ea1746
Packit ea1746
  LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem;
Packit ea1746
Packit ea1746
  problem->b.reset(new double[num_rows]);
Packit ea1746
  problem->D.reset(new double[num_cols]);
Packit ea1746
  problem->num_eliminate_blocks = 2;
Packit ea1746
Packit ea1746
  CompressedRowBlockStructure* bs = new CompressedRowBlockStructure;
Packit ea1746
  scoped_array<double> values(new double[num_rows * num_cols]);
Packit ea1746
Packit ea1746
  for (int c = 0; c < num_cols; ++c) {
Packit ea1746
    bs->cols.push_back(Block());
Packit ea1746
    bs->cols.back().size = 1;
Packit ea1746
    bs->cols.back().position = c;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  int nnz = 0;
Packit ea1746
Packit ea1746
  // Row 1
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 0;
Packit ea1746
    row.cells.push_back(Cell(0, 0));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 2
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 3;
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 1;
Packit ea1746
    row.cells.push_back(Cell(0, 1));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 3
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 5;
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 2;
Packit ea1746
    row.cells.push_back(Cell(1, 2));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 4
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 7;
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 3;
Packit ea1746
    row.cells.push_back(Cell(1, 3));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 5
Packit ea1746
  {
Packit ea1746
    values[nnz++] = 9;
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 4;
Packit ea1746
    row.cells.push_back(Cell(1, 4));
Packit ea1746
  }
Packit ea1746
Packit ea1746
  BlockSparseMatrix* A = new BlockSparseMatrix(bs);
Packit ea1746
  memcpy(A->mutable_values(), values.get(), nnz * sizeof(*A->values()));
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_cols; ++i) {
Packit ea1746
    problem->D.get()[i] = 1;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_rows; ++i) {
Packit ea1746
    problem->b.get()[i] = i;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  problem->A.reset(A);
Packit ea1746
Packit ea1746
  return problem;
Packit ea1746
}
Packit ea1746
Packit ea1746
/*
Packit ea1746
      A = [1 2 0 0 0 1 1
Packit ea1746
           1 4 0 0 0 5 6
Packit ea1746
           0 0 9 0 0 3 1]
Packit ea1746
Packit ea1746
      b = [0
Packit ea1746
           1
Packit ea1746
           2]
Packit ea1746
*/
Packit ea1746
// BlockSparseMatrix version
Packit ea1746
//
Packit ea1746
// This problem has the unique property that it has two different
Packit ea1746
// sized f-blocks, but only one of them occurs in the rows involving
Packit ea1746
// the one e-block. So performing Schur elimination on this problem
Packit ea1746
// tests the Schur Eliminator's ability to handle non-e-block rows
Packit ea1746
// correctly when their structure does not conform to the static
Packit ea1746
// structure determined by DetectStructure.
Packit ea1746
//
Packit ea1746
// NOTE: This problem is too small and rank deficient to be solved without
Packit ea1746
// the diagonal regularization.
Packit ea1746
LinearLeastSquaresProblem* LinearLeastSquaresProblem4() {
Packit ea1746
  int num_rows = 3;
Packit ea1746
  int num_cols = 7;
Packit ea1746
Packit ea1746
  LinearLeastSquaresProblem* problem = new LinearLeastSquaresProblem;
Packit ea1746
Packit ea1746
  problem->b.reset(new double[num_rows]);
Packit ea1746
  problem->D.reset(new double[num_cols]);
Packit ea1746
  problem->num_eliminate_blocks = 1;
Packit ea1746
Packit ea1746
  CompressedRowBlockStructure* bs = new CompressedRowBlockStructure;
Packit ea1746
  scoped_array<double> values(new double[num_rows * num_cols]);
Packit ea1746
Packit ea1746
  // Column block structure
Packit ea1746
  bs->cols.push_back(Block());
Packit ea1746
  bs->cols.back().size = 2;
Packit ea1746
  bs->cols.back().position = 0;
Packit ea1746
Packit ea1746
  bs->cols.push_back(Block());
Packit ea1746
  bs->cols.back().size = 3;
Packit ea1746
  bs->cols.back().position = 2;
Packit ea1746
Packit ea1746
  bs->cols.push_back(Block());
Packit ea1746
  bs->cols.back().size = 2;
Packit ea1746
  bs->cols.back().position = 5;
Packit ea1746
Packit ea1746
  int nnz = 0;
Packit ea1746
Packit ea1746
  // Row 1 & 2
Packit ea1746
  {
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 2;
Packit ea1746
    row.block.position = 0;
Packit ea1746
Packit ea1746
    row.cells.push_back(Cell(0, nnz));
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    values[nnz++] = 2;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    values[nnz++] = 4;
Packit ea1746
Packit ea1746
    row.cells.push_back(Cell(2, nnz));
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
    values[nnz++] = 5;
Packit ea1746
    values[nnz++] = 6;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  // Row 3
Packit ea1746
  {
Packit ea1746
    bs->rows.push_back(CompressedRow());
Packit ea1746
    CompressedRow& row = bs->rows.back();
Packit ea1746
    row.block.size = 1;
Packit ea1746
    row.block.position = 2;
Packit ea1746
Packit ea1746
    row.cells.push_back(Cell(1, nnz));
Packit ea1746
    values[nnz++] = 9;
Packit ea1746
    values[nnz++] = 0;
Packit ea1746
    values[nnz++] = 0;
Packit ea1746
Packit ea1746
    row.cells.push_back(Cell(2, nnz));
Packit ea1746
    values[nnz++] = 3;
Packit ea1746
    values[nnz++] = 1;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  BlockSparseMatrix* A = new BlockSparseMatrix(bs);
Packit ea1746
  memcpy(A->mutable_values(), values.get(), nnz * sizeof(*A->values()));
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_cols; ++i) {
Packit ea1746
    problem->D.get()[i] = (i + 1) * 100;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  for (int i = 0; i < num_rows; ++i) {
Packit ea1746
    problem->b.get()[i] = i;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  problem->A.reset(A);
Packit ea1746
  return problem;
Packit ea1746
}
Packit ea1746
Packit ea1746
namespace {
Packit ea1746
bool DumpLinearLeastSquaresProblemToConsole(const SparseMatrix* A,
Packit ea1746
                                            const double* D,
Packit ea1746
                                            const double* b,
Packit ea1746
                                            const double* x,
Packit ea1746
                                            int num_eliminate_blocks) {
Packit ea1746
  CHECK_NOTNULL(A);
Packit ea1746
  Matrix AA;
Packit ea1746
  A->ToDenseMatrix(&AA;;
Packit ea1746
  LOG(INFO) << "A^T: \n" << AA.transpose();
Packit ea1746
Packit ea1746
  if (D != NULL) {
Packit ea1746
    LOG(INFO) << "A's appended diagonal:\n"
Packit ea1746
              << ConstVectorRef(D, A->num_cols());
Packit ea1746
  }
Packit ea1746
Packit ea1746
  if (b != NULL) {
Packit ea1746
    LOG(INFO) << "b: \n" << ConstVectorRef(b, A->num_rows());
Packit ea1746
  }
Packit ea1746
Packit ea1746
  if (x != NULL) {
Packit ea1746
    LOG(INFO) << "x: \n" << ConstVectorRef(x, A->num_cols());
Packit ea1746
  }
Packit ea1746
  return true;
Packit ea1746
}
Packit ea1746
Packit ea1746
void WriteArrayToFileOrDie(const string& filename,
Packit ea1746
                           const double* x,
Packit ea1746
                           const int size) {
Packit ea1746
  CHECK_NOTNULL(x);
Packit ea1746
  VLOG(2) << "Writing array to: " << filename;
Packit ea1746
  FILE* fptr = fopen(filename.c_str(), "w");
Packit ea1746
  CHECK_NOTNULL(fptr);
Packit ea1746
  for (int i = 0; i < size; ++i) {
Packit ea1746
    fprintf(fptr, "%17f\n", x[i]);
Packit ea1746
  }
Packit ea1746
  fclose(fptr);
Packit ea1746
}
Packit ea1746
Packit ea1746
bool DumpLinearLeastSquaresProblemToTextFile(const string& filename_base,
Packit ea1746
                                             const SparseMatrix* A,
Packit ea1746
                                             const double* D,
Packit ea1746
                                             const double* b,
Packit ea1746
                                             const double* x,
Packit ea1746
                                             int num_eliminate_blocks) {
Packit ea1746
  CHECK_NOTNULL(A);
Packit ea1746
  LOG(INFO) << "writing to: " << filename_base << "*";
Packit ea1746
Packit ea1746
  string matlab_script;
Packit ea1746
  StringAppendF(&matlab_script,
Packit ea1746
                "function lsqp = load_trust_region_problem()\n");
Packit ea1746
  StringAppendF(&matlab_script,
Packit ea1746
                "lsqp.num_rows = %d;\n", A->num_rows());
Packit ea1746
  StringAppendF(&matlab_script,
Packit ea1746
                "lsqp.num_cols = %d;\n", A->num_cols());
Packit ea1746
Packit ea1746
  {
Packit ea1746
    string filename = filename_base + "_A.txt";
Packit ea1746
    FILE* fptr = fopen(filename.c_str(), "w");
Packit ea1746
    CHECK_NOTNULL(fptr);
Packit ea1746
    A->ToTextFile(fptr);
Packit ea1746
    fclose(fptr);
Packit ea1746
    StringAppendF(&matlab_script,
Packit ea1746
                  "tmp = load('%s', '-ascii');\n", filename.c_str());
Packit ea1746
    StringAppendF(
Packit ea1746
        &matlab_script,
Packit ea1746
        "lsqp.A = sparse(tmp(:, 1) + 1, tmp(:, 2) + 1, tmp(:, 3), %d, %d);\n",
Packit ea1746
        A->num_rows(),
Packit ea1746
        A->num_cols());
Packit ea1746
  }
Packit ea1746
Packit ea1746
Packit ea1746
  if (D != NULL) {
Packit ea1746
    string filename = filename_base + "_D.txt";
Packit ea1746
    WriteArrayToFileOrDie(filename, D, A->num_cols());
Packit ea1746
    StringAppendF(&matlab_script,
Packit ea1746
                  "lsqp.D = load('%s', '-ascii');\n", filename.c_str());
Packit ea1746
  }
Packit ea1746
Packit ea1746
  if (b != NULL) {
Packit ea1746
    string filename = filename_base + "_b.txt";
Packit ea1746
    WriteArrayToFileOrDie(filename, b, A->num_rows());
Packit ea1746
    StringAppendF(&matlab_script,
Packit ea1746
                  "lsqp.b = load('%s', '-ascii');\n", filename.c_str());
Packit ea1746
  }
Packit ea1746
Packit ea1746
  if (x != NULL) {
Packit ea1746
    string filename = filename_base + "_x.txt";
Packit ea1746
    WriteArrayToFileOrDie(filename, x, A->num_cols());
Packit ea1746
    StringAppendF(&matlab_script,
Packit ea1746
                  "lsqp.x = load('%s', '-ascii');\n", filename.c_str());
Packit ea1746
  }
Packit ea1746
Packit ea1746
  string matlab_filename = filename_base + ".m";
Packit ea1746
  WriteStringToFileOrDie(matlab_script, matlab_filename);
Packit ea1746
  return true;
Packit ea1746
}
Packit ea1746
}  // namespace
Packit ea1746
Packit ea1746
bool DumpLinearLeastSquaresProblem(const string& filename_base,
Packit ea1746
                                   DumpFormatType dump_format_type,
Packit ea1746
                                   const SparseMatrix* A,
Packit ea1746
                                   const double* D,
Packit ea1746
                                   const double* b,
Packit ea1746
                                   const double* x,
Packit ea1746
                                   int num_eliminate_blocks) {
Packit ea1746
  switch (dump_format_type) {
Packit ea1746
    case CONSOLE:
Packit ea1746
      return DumpLinearLeastSquaresProblemToConsole(A, D, b, x,
Packit ea1746
                                                    num_eliminate_blocks);
Packit ea1746
    case TEXTFILE:
Packit ea1746
      return DumpLinearLeastSquaresProblemToTextFile(filename_base,
Packit ea1746
                                                     A, D, b, x,
Packit ea1746
                                                     num_eliminate_blocks);
Packit ea1746
    default:
Packit ea1746
      LOG(FATAL) << "Unknown DumpFormatType " << dump_format_type;
Packit ea1746
  }
Packit ea1746
Packit ea1746
  return true;
Packit ea1746
}
Packit ea1746
Packit ea1746
}  // namespace internal
Packit ea1746
}  // namespace ceres