/*!
 *  Copyright (c) 2016 by Contributors
 * \file initializer.h
 * \brief random initializer
 * \author Zhang Chen
 */

#ifndef CPP_PACKAGE_INCLUDE_MXNET_CPP_INITIALIZER_H_
#define CPP_PACKAGE_INCLUDE_MXNET_CPP_INITIALIZER_H_

#include <cmath>
#include <string>
#include <vector>
#include "mxnet-cpp/ndarray.h"

namespace mxnet {
namespace cpp {

class Initializer {
 public:
  static bool StringStartWith(const std::string& name,
                              const std::string& check_str) {
    return (name.size() >= check_str.size() &&
            name.substr(0, check_str.size()) == check_str);
  }
  static bool StringEndWith(const std::string& name,
                            const std::string& check_str) {
    return (name.size() >= check_str.size() &&
            name.substr(name.size() - check_str.size(), check_str.size()) ==
                check_str);
  }
  virtual void operator()(const std::string& name, NDArray* arr) {
    if (StringStartWith(name, "upsampling")) {
      InitBilinear(arr);
    } else if (StringEndWith(name, "bias")) {
      InitBias(arr);
    } else if (StringEndWith(name, "gamma")) {
      InitGamma(arr);
    } else if (StringEndWith(name, "beta")) {
      InitBeta(arr);
    } else if (StringEndWith(name, "weight")) {
      InitWeight(arr);
    } else if (StringEndWith(name, "moving_mean")) {
      InitZero(arr);
    } else if (StringEndWith(name, "moving_var")) {
      InitOne(arr);
    } else if (StringEndWith(name, "moving_inv_var")) {
      InitZero(arr);
    } else if (StringEndWith(name, "moving_avg")) {
      InitZero(arr);
    } else {
      InitDefault(arr);
    }
  }

 protected:
  virtual void InitBilinear(NDArray* arr) {
    Shape shape(arr->GetShape());
    std::vector<float> weight(shape.Size(), 0);
    int f = std::ceil(shape[3] / 2.0);
    float c = (2 * f - 1 - f % 2) / (2. * f);
    for (size_t i = 0; i < shape.Size(); ++i) {
      int x = i % shape[3];
      int y = (i / shape[3]) % shape[2];
      weight[i] = (1 - std::abs(x / f - c)) * (1 - std::abs(y / f - c));
    }
    (*arr).SyncCopyFromCPU(weight);
  }
  virtual void InitZero(NDArray* arr) { (*arr) = 0.0f; }
  virtual void InitOne(NDArray* arr) { (*arr) = 1.0f; }
  virtual void InitBias(NDArray* arr) { (*arr) = 0.0f; }
  virtual void InitGamma(NDArray* arr) { (*arr) = 1.0f; }
  virtual void InitBeta(NDArray* arr) { (*arr) = 0.0f; }
  virtual void InitWeight(NDArray* arr) {}
  virtual void InitDefault(NDArray* arr) {}
};

class Xavier : public Initializer {
 public:
  enum RandType {
    gaussian,
    uniform
  } rand_type;
  enum FactorType {
    avg,
    in,
    out
  } factor_type;
  float magnitude;
  Xavier(RandType rand_type = gaussian, FactorType factor_type = avg,
         float magnitude = 3)
      : rand_type(rand_type), factor_type(factor_type), magnitude(magnitude) {}

 protected:
  virtual void InitWeight(NDArray* arr) {
    Shape shape(arr->GetShape());
    float hw_scale = 1.0f;
    if (shape.ndim() > 2) {
      for (size_t i = 2; i < shape.ndim(); ++i) {
        hw_scale *= shape[i];
      }
    }
    float fan_in = shape[1] * hw_scale, fan_out = shape[0] * hw_scale;
    float factor = 1.0f;
    switch (factor_type) {
      case avg:
        factor = (fan_in + fan_out) / 2.0;
        break;
      case in:
        factor = fan_in;
        break;
      case out:
        factor = fan_out;
    }
    float scale = std::sqrt(magnitude / factor);
    switch (rand_type) {
      case uniform:
        NDArray::SampleUniform(-scale, scale, arr);
        break;
      case gaussian:
        NDArray::SampleGaussian(0, scale, arr);
        break;
    }
  }
};

}  // namespace cpp
}  // namespace mxnet

#endif  // CPP_PACKAGE_INCLUDE_MXNET_CPP_INITIALIZER_H_
