/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_tools/frame_analyzer/linear_least_squares.h"

#include <math.h>
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <numeric>
#include <type_traits>
#include <utility>

#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace test {

template <class T>
using Matrix = std::valarray<std::valarray<T>>;

namespace {

template <typename R, typename T>
R DotProduct(const std::valarray<T>& a, const std::valarray<T>& b) {
  RTC_CHECK_EQ(a.size(), b.size());
  return std::inner_product(std::begin(a), std::end(a), std::begin(b), R(0));
}

// Calculates a^T * b.
template <typename R, typename T>
Matrix<R> MatrixMultiply(const Matrix<T>& a, const Matrix<T>& b) {
  Matrix<R> result(std::valarray<R>(a.size()), b.size());
  for (size_t i = 0; i < a.size(); ++i) {
    for (size_t j = 0; j < b.size(); ++j)
      result[j][i] = DotProduct<R>(a[i], b[j]);
  }

  return result;
}

template <typename T>
Matrix<T> Transpose(const Matrix<T>& matrix) {
  if (matrix.size() == 0)
    return Matrix<T>();
  const size_t rows = matrix.size();
  const size_t columns = matrix[0].size();
  Matrix<T> result(std::valarray<T>(rows), columns);

  for (size_t i = 0; i < rows; ++i) {
    for (size_t j = 0; j < columns; ++j)
      result[j][i] = matrix[i][j];
  }

  return result;
}

// Convert valarray from type T to type R.
template <typename R, typename T>
std::valarray<R> ConvertTo(const std::valarray<T>& v) {
  std::valarray<R> result(v.size());
  for (size_t i = 0; i < v.size(); ++i)
    result[i] = static_cast<R>(v[i]);
  return result;
}

// Convert valarray Matrix from type T to type R.
template <typename R, typename T>
Matrix<R> ConvertTo(const Matrix<T>& mat) {
  Matrix<R> result(mat.size());
  for (size_t i = 0; i < mat.size(); ++i)
    result[i] = ConvertTo<R>(mat[i]);
  return result;
}

// Convert from valarray Matrix back to the more conventional std::vector.
template <typename T>
std::vector<std::vector<T>> ToVectorMatrix(const Matrix<T>& m) {
  std::vector<std::vector<T>> result;
  for (const std::valarray<T>& v : m)
    result.emplace_back(std::begin(v), std::end(v));
  return result;
}

// Create a valarray Matrix from a conventional std::vector.
template <typename T>
Matrix<T> FromVectorMatrix(const std::vector<std::vector<T>>& mat) {
  Matrix<T> result(mat.size());
  for (size_t i = 0; i < mat.size(); ++i)
    result[i] = std::valarray<T>(mat[i].data(), mat[i].size());
  return result;
}

// Returns |matrix_to_invert|^-1 * |right_hand_matrix|. |matrix_to_invert| must
// have square size.
Matrix<double> GaussianElimination(Matrix<double> matrix_to_invert,
                                   Matrix<double> right_hand_matrix) {
  // |n| is the width/height of |matrix_to_invert|.
  const size_t n = matrix_to_invert.size();
  // Make sure |matrix_to_invert| has square size.
  for (const std::valarray<double>& column : matrix_to_invert)
    RTC_CHECK_EQ(n, column.size());
  // Make sure |right_hand_matrix| has correct size.
  for (const std::valarray<double>& column : right_hand_matrix)
    RTC_CHECK_EQ(n, column.size());

  // Transpose the matrices before and after so that we can perform Gaussian
  // elimination on the columns instead of the rows, since that is easier with
  // our representation.
  matrix_to_invert = Transpose(matrix_to_invert);
  right_hand_matrix = Transpose(right_hand_matrix);

  // Loop over the diagonal of |matrix_to_invert| and perform column reduction.
  // Column reduction is a sequence of elementary column operations that is
  // performed on both |matrix_to_invert| and |right_hand_matrix| until
  // |matrix_to_invert| has been transformed to the identity matrix.
  for (size_t diagonal_index = 0; diagonal_index < n; ++diagonal_index) {
    // Make sure the diagonal element has the highest absolute value by
    // swapping columns if necessary.
    for (size_t column = diagonal_index + 1; column < n; ++column) {
      if (std::abs(matrix_to_invert[column][diagonal_index]) >
          std::abs(matrix_to_invert[diagonal_index][diagonal_index])) {
        std::swap(matrix_to_invert[column], matrix_to_invert[diagonal_index]);
        std::swap(right_hand_matrix[column], right_hand_matrix[diagonal_index]);
      }
    }

    // Reduce the diagonal element to be 1, by dividing the column with that
    // value. If the diagonal element is 0, it means the system of equations has
    // many solutions, and in that case we will return an arbitrary solution.
    if (matrix_to_invert[diagonal_index][diagonal_index] == 0.0) {
      RTC_LOG(LS_WARNING) << "Matrix is not invertible, ignoring.";
      continue;
    }
    const double diagonal_element =
        matrix_to_invert[diagonal_index][diagonal_index];
    matrix_to_invert[diagonal_index] /= diagonal_element;
    right_hand_matrix[diagonal_index] /= diagonal_element;

    // Eliminate the other entries in row |diagonal_index| by making them zero.
    for (size_t column = 0; column < n; ++column) {
      if (column == diagonal_index)
        continue;
      const double row_element = matrix_to_invert[column][diagonal_index];
      matrix_to_invert[column] -=
          row_element * matrix_to_invert[diagonal_index];
      right_hand_matrix[column] -=
          row_element * right_hand_matrix[diagonal_index];
    }
  }

  // Transpose the result before returning it, explained in comment above.
  return Transpose(right_hand_matrix);
}

}  // namespace

IncrementalLinearLeastSquares::IncrementalLinearLeastSquares() = default;
IncrementalLinearLeastSquares::~IncrementalLinearLeastSquares() = default;

void IncrementalLinearLeastSquares::AddObservations(
    const std::vector<std::vector<uint8_t>>& x,
    const std::vector<std::vector<uint8_t>>& y) {
  if (x.empty() || y.empty())
    return;
  // Make sure all columns are the same size.
  const size_t n = x[0].size();
  for (const std::vector<uint8_t>& column : x)
    RTC_CHECK_EQ(n, column.size());
  for (const std::vector<uint8_t>& column : y)
    RTC_CHECK_EQ(n, column.size());

  // We will multiply the uint8_t values together, so we need to expand to a
  // type that can safely store those values, i.e. uint16_t.
  const Matrix<uint16_t> unpacked_x = ConvertTo<uint16_t>(FromVectorMatrix(x));
  const Matrix<uint16_t> unpacked_y = ConvertTo<uint16_t>(FromVectorMatrix(y));

  const Matrix<uint64_t> xx = MatrixMultiply<uint64_t>(unpacked_x, unpacked_x);
  const Matrix<uint64_t> xy = MatrixMultiply<uint64_t>(unpacked_x, unpacked_y);
  if (sum_xx && sum_xy) {
    *sum_xx += xx;
    *sum_xy += xy;
  } else {
    sum_xx = xx;
    sum_xy = xy;
  }
}

std::vector<std::vector<double>>
IncrementalLinearLeastSquares::GetBestSolution() const {
  RTC_CHECK(sum_xx && sum_xy) << "No observations have been added";
  return ToVectorMatrix(GaussianElimination(ConvertTo<double>(*sum_xx),
                                            ConvertTo<double>(*sum_xy)));
}

}  // namespace test
}  // namespace webrtc
