/*
 *  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
