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); }
/** * 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; }
/** * 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; }
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) { }