예제 #1
0
nd::callable nd::functional::rolling(const nd::callable &window_op, intptr_t window_size)
{
  // Validate the input callable
  if (window_op.is_null()) {
    throw invalid_argument("make_rolling_callable() 'window_op' cannot be null");
  }
  const ndt::callable_type *window_af_tp = window_op.get_type();
  if (window_af_tp->get_npos() != 1) {
    stringstream ss;
    ss << "To make a rolling window callable, an operation with one "
          "argument is required, got "
       << window_af_tp;
    throw invalid_argument(ss.str());
  }
  const ndt::type &window_src_tp = window_af_tp->get_pos_type(0);
  if (window_src_tp.get_ndim() < 1) {
    stringstream ss;
    ss << "To make a rolling window callable, an operation with which "
          "accepts a dimension is required, got "
       << window_af_tp;
    throw invalid_argument(ss.str());
  }

  std::string rolldimname("RollDim");
  ndt::type roll_src_tp = ndt::typevar_dim_type::make(rolldimname, window_src_tp.get_type_at_dimension(NULL, 1));
  ndt::type roll_dst_tp = ndt::typevar_dim_type::make(rolldimname, window_af_tp->get_return_type());

  // Create the data for the callable
  std::shared_ptr<rolling_callable_data> data(new rolling_callable_data);
  data->window_size = window_size;
  data->window_op = window_op;

  return callable::make<rolling_ck>(ndt::callable_type::make(roll_dst_tp, roll_src_tp), data);
}
예제 #2
0
/**
 * Returns true if ``lhs`` and ``rhs`` are consistent, but neither
 * supercedes the other.
 *
 * e.g. "(int16, int32) -> int16)" and "(int32, int16) -> int32"
 */
static bool ambiguous(const nd::callable &lhs, const nd::callable &rhs)
{
  // TODO: Deal with keyword args
  if (lhs.get_type()->get_nkwd() > 0 || rhs.get_type()->get_nkwd() > 0) {
    return false;
  }

  intptr_t npos = lhs.get_type()->get_npos();
  if (npos == rhs.get_type()->get_npos()) {
    intptr_t lsupercount = 0, rsupercount = 0;
    for (intptr_t i = 0; i < npos; ++i) {
      const ndt::type &lpt = lhs.get_type()->get_pos_type(i);
      const ndt::type &rpt = rhs.get_type()->get_pos_type(i);
      bool either = false;
      std::map<std::string, ndt::type> typevars;
      if (nd::functional::can_implicitly_convert(lpt, rpt, typevars)) {
        lsupercount++;
        either = true;
      }
      typevars.clear();
      if (nd::functional::can_implicitly_convert(rpt, lpt, typevars)) {
        rsupercount++;
        either = true;
      }
      if (!either) {
        return false;
      }
    }
    return (lsupercount != npos && rsupercount != npos) ||
           (lsupercount == rsupercount);
  }
  return false;
}
예제 #3
0
/**
 * Returns true if every argument type in ``lhs`` is implicitly
 * convertible to the corresponding argument type in ``rhs``.
 *
 * e.g. "(int16, int16) -> int16)" and "(int32, int16) -> int32"
 */
static bool supercedes(const nd::callable &lhs, const nd::callable &rhs)
{
  // TODO: Deal with keyword args
  if (lhs.get_type()->get_nkwd() > 0 || rhs.get_type()->get_nkwd() > 0) {
    return false;
  }

  intptr_t npos = lhs.get_type()->get_npos();
  if (npos == rhs.get_type()->get_npos()) {
    for (intptr_t i = 0; i < npos; ++i) {
      const ndt::type &lpt = lhs.get_type()->get_pos_type(i);
      const ndt::type &rpt = rhs.get_type()->get_pos_type(i);
      std::map<std::string, ndt::type> typevars;
      if (!nd::functional::can_implicitly_convert(lpt, rpt, typevars)) {
        return false;
      }
    }
    return true;
  }
  return false;
}
예제 #4
0
ndt::adapt_type::adapt_type(const nd::callable &forward, const nd::callable &inverse)
    : adapt_type(forward.get_type()->get_return_type(), forward.get_type()->get_pos_type(0), forward, inverse)
{
}