static PyObject * GMPy_MPC_SizeOf_Method(PyObject *self, PyObject *other) { return PyIntOrLong_FromSize_t(sizeof(MPC_Object) + \ (((mpc_realref(MPC(self))->_mpfr_prec + mp_bits_per_limb - 1) / \ mp_bits_per_limb) * sizeof(mp_limb_t)) + \ (((mpc_imagref(MPC(self))->_mpfr_prec + mp_bits_per_limb - 1) / \ mp_bits_per_limb) * sizeof(mp_limb_t))); }
static PyObject * GMPy_PyComplex_From_MPC(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; double real, imag; CHECK_CONTEXT(context); real = mpfr_get_d(mpc_realref(MPC(self)), GET_REAL_ROUND(context)); imag = mpfr_get_d(mpc_imagref(MPC(self)), GET_IMAG_ROUND(context)); return PyComplex_FromDoubles(real, imag); }
static PyObject * GMPy_Complex_Add(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPC_Check(x) && MPC_Check(y)) { SET_MPC_MPC_WAS_NAN(context, x, y); result->rc = mpc_add(result->c, MPC(x), MPC(y), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } if (IS_COMPLEX(x) && IS_COMPLEX(y)) { MPC_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context)) || !(tempy = GMPy_MPC_From_Complex(y, 1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } SET_MPC_MPC_WAS_NAN(context, tempx, tempy); result->rc = mpc_add(result->c, tempx->c, tempy->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Complex_Add()."); return NULL; /* LCOV_EXCL_STOP */ }
static PyObject * GMPy_MPC_Repr_Slot(MPC_Object *self) { PyObject *result, *temp; mpfr_prec_t rbits, ibits; long rprec, iprec; char fmtstr[60]; mpc_get_prec2(&rbits, &ibits, MPC(self)); rprec = (long)(log10(2) * (double)rbits) + 2; iprec = (long)(log10(2) * (double)ibits) + 2; if (rbits != DBL_MANT_DIG || ibits !=DBL_MANT_DIG) sprintf(fmtstr, "mpc('{0:.%ld.%ldg}',(%ld,%ld))", rprec, iprec, rbits, ibits); else sprintf(fmtstr, "mpc('{0:.%ld.%ldg}')", rprec, iprec); temp = Py_BuildValue("s", fmtstr); if (!temp) return NULL; result = PyObject_CallMethod(temp, "format", "O", self); Py_DECREF(temp); return result; }
static PyObject * GMPy_Complex_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) return NULL; if (MPC_Check(x) && MPC_Check(y)) { result->rc = mpc_sub(result->c, MPC(x), MPC(y), GET_MPC_ROUND(context)); goto done; } if (IS_COMPLEX(x) && IS_COMPLEX(y)) { MPC_Object *tempx, *tempy; tempx = GMPy_MPC_From_Complex(x, 1, 1, context); tempy = GMPy_MPC_From_Complex(y, 1, 1, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } result->rc = mpc_sub(result->c, tempx->c, tempy->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; done: GMPY_MPC_CLEANUP(result, context, "subtraction"); return (PyObject*)result; }
static PyObject * _GMPy_MPC_Atanh(PyObject *x, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_atanh(result->c, MPC(x), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; }
static PyObject * _GMPy_MPC_Minus(PyObject *x, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_neg(result->c, MPC(x), GET_MPC_ROUND(context)); GMPY_MPC_CLEANUP(result, context, "minus()"); return (PyObject*)result; }
static PyObject * GMPy_MPC_Conjugate_Method(PyObject *self, PyObject *args) { MPC_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_conj(result->c, MPC(self), GET_MPC_ROUND(context)); GMPY_MPC_CLEANUP(result, context, "conjugate()"); return (PyObject*)result; }
static PyObject * _GMPy_MPC_Sin_Cos(PyObject *x, CTXT_Object *context) { MPC_Object *s, *c; PyObject *result; int code; CHECK_CONTEXT(context); s = GMPy_MPC_New(0, 0, context); c = GMPy_MPC_New(0, 0, context); result = PyTuple_New(2); if (!s || !c || !result) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } code = mpc_sin_cos(s->c, c->c, MPC(x), GET_MPC_ROUND(context), GET_MPC_ROUND(context)); s->rc = MPC_INEX1(code); c->rc = MPC_INEX2(code); _GMPy_MPC_Cleanup(&s, context); _GMPy_MPC_Cleanup(&c, context); if (!s || !c) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } PyTuple_SET_ITEM(result, 0, (PyObject*)s); PyTuple_SET_ITEM(result, 1, (PyObject*)c); return result; }
static PyObject * GMPy_MPC_Format(PyObject *self, PyObject *args) { PyObject *result = NULL, *tempstr = NULL; char *realbuf = 0, *imagbuf = 0, *tempbuf = 0, *fmtcode = 0; char *p, *rfmtptr, *ifmtptr, *fmtptr; char rfmt[100], ifmt[100], fmt[30]; int rbuflen, ibuflen; int seensign = 0, seenalign = 0, seendecimal = 0, seendigits = 0; int seenround = 0, seenconv = 0, seenstyle = 0, mpcstyle = 0; if (!MPC_Check(self)) { TYPE_ERROR("requires 'mpc' object"); return NULL; } if (!PyArg_ParseTuple(args, "s", &fmtcode)) { return NULL; } rfmtptr = rfmt; ifmtptr = ifmt; fmtptr = fmt; *(rfmtptr++) = '%'; *(ifmtptr++) = '%'; for (p = fmtcode; *p != '\00'; p++) { if (*p == '<' || *p == '>' || *p == '^') { if (seenalign || seensign || seendecimal || seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(fmtptr++) = *p; seenalign = 1; continue; } } if (*p == '+' || *p == ' ' || *p == '-') { if (seensign || seendecimal || seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(rfmtptr++) = *p; *(ifmtptr++) = *p; seensign = 1; continue; } } if (!seensign) { *(rfmtptr++) = '-'; *(ifmtptr++) = '-'; seensign = 1; } if (*p == '.') { if (seendecimal == 2 || seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { if (!seendecimal) { *(rfmtptr++) = *p; *(ifmtptr++) = *p; } seendecimal++; if (seendecimal == 2) { while (isdigit(*(ifmtptr-1))) ifmtptr--; } continue; } } if (isdigit(*p)) { if (seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else if (seendecimal == 1) { *(rfmtptr++) = *p; *(ifmtptr++) = *p; continue; } else if (seendecimal == 2) { *(ifmtptr++) = *p; continue; } else { if (fmtptr == fmt) { *(fmtptr++) = '>'; seenalign = 1; } *(fmtptr++) = *p; continue; } } if (!seendigits) { seendigits = 1; *(rfmtptr++) = 'R'; *(ifmtptr++) = 'R'; } if (*p == 'U' || *p == 'D' || *p == 'Y' || *p == 'Z' || *p == 'N' ) { if (seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(rfmtptr++) = *p; *(ifmtptr++) = *p; seenround = 1; continue; } } if (*p == 'P' || *p == 'M') { if (seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { if (*p == 'M') mpcstyle = 1; seenstyle = 1; continue; } } if (*p == 'a' || *p == 'A' || *p == 'b' || *p == 'e' || *p == 'E' || *p == 'f' || *p == 'F' || *p == 'g' || *p == 'G' ) { *(rfmtptr++) = *p; *(ifmtptr++) = *p; seenconv = 1; break; } VALUE_ERROR("Invalid conversion specification"); return NULL; } if (!seensign) { *(rfmtptr++) = '-'; *(ifmtptr++) = '-'; } if (!seendigits) { *(rfmtptr++) = 'R'; *(ifmtptr++) = 'R'; } if (!seenconv) { *(rfmtptr++) = 'f'; *(ifmtptr++) = 'f'; } *(rfmtptr) = '\00'; *(ifmtptr) = '\00'; *(fmtptr) = '\00'; /* Format the real part.... */ rbuflen = mpfr_asprintf(&realbuf, rfmt, mpc_realref(MPC(self))); if (rbuflen < 0) { mpfr_free_str(realbuf); SYSTEM_ERROR("Internal error in mpfr_asprintf"); return NULL; } /* Format the imaginary part. If Python style is wanted, convert the '-' * or ' ' sign indicator to '+'. */ if (!mpcstyle) { if (ifmt[1] == ' ' || ifmt[1] == '-' || ifmt[1] == '+') { ifmt[1] = '+'; } else { mpfr_free_str(realbuf); VALUE_ERROR("Invalid conversion specification for imag"); return NULL; } } ibuflen = mpfr_asprintf(&imagbuf, ifmt, mpc_imagref(MPC(self))); if (ibuflen < 0) { mpfr_free_str(realbuf); mpfr_free_str(imagbuf); SYSTEM_ERROR("Internal error in mpfr_asprintf"); return NULL; } /* Combine the real and imaginary components into a single buffer. * Include space for '(', ' ', and 'j)' and possibly appending '.0' twice. */ tempbuf = GMPY_MALLOC(rbuflen + ibuflen + 10); if (!tempbuf) { mpfr_free_str(realbuf); mpfr_free_str(imagbuf); return PyErr_NoMemory(); } tempbuf[0] = '\00'; if (mpcstyle) strcat(tempbuf, "("); strcat(tempbuf, realbuf); /* If there isn't a decimal point in the output and the output * is short and only consists of digits, then append .0 */ if (strlen(realbuf) < 50 && strlen(realbuf) == strspn(realbuf, "+- 0123456789")) { strcat(tempbuf, ".0"); } if (mpcstyle) strcat(tempbuf, " "); else { /* Need to insert + if imag is nan or +inf. */ if (mpfr_nan_p(mpc_imagref(MPC(self))) || (mpfr_inf_p(mpc_imagref(MPC(self))) && mpfr_sgn(mpc_imagref(MPC(self))) > 0)) { strcat(tempbuf, "+"); } } strcat(tempbuf, imagbuf); if (strlen(imagbuf) < 50 && strlen(imagbuf) == strspn(imagbuf, "+- 0123456789")) { strcat(tempbuf, ".0"); } if (mpcstyle) strcat(tempbuf, ")"); else strcat(tempbuf, "j"); mpfr_free_str(realbuf); mpfr_free_str(imagbuf); tempstr = Py_BuildValue("s", tempbuf); if (!tempstr) { GMPY_FREE(tempbuf); return NULL; } result = PyObject_CallMethod(tempstr, "__format__", "(s)", fmt); Py_DECREF(tempstr); return result; }
int ZWS(const uint64_t P, const uint64_t O, uint64_t& NodeCounter, const int alpha, const int selectivity, const int depth, const int empties) { assert((P & O) == 0); assert(-64 <= alpha); assert(alpha <= 64); assert(0 <= depth); assert(depth <= 60); assert(0 <= empties); assert(empties <= 60); assert(empties == Empties(P, O)); assert(depth <= empties); if (depth <= 3 && depth < empties) { if (depth == 3) return Midgame::ZWS_3(P, O, NodeCounter, alpha); if (depth == 2) return Midgame::ZWS_2(P, O, NodeCounter, alpha); if (depth == 1) return Midgame::ZWS_1(P, O, NodeCounter, alpha); if (depth == 0) return Midgame::Eval_0(P, O, NodeCounter); } if (empties <= B && depth == empties) return Endgame::ZWS_B(P, O, NodeCounter, alpha, empties); int score; int bestscore = -64; uint8_t BestMove = 64; uint64_t BitBoardPossible = PossibleMoves(P, O); uint64_t LocalNodeCounter = NodeCounter; CHashTableValueType ttValue; NodeCounter++; if (!BitBoardPossible){ if (HasMoves(O, P)) return -ZWS(O, P, NodeCounter, -alpha - 1, selectivity, depth, empties); else return EvalGameOver(P, empties); } if (StabilityCutoff_ZWS(P, O, alpha, score)) return score; if (LookUpTT(P, O, ttValue) && UseTTValue(ttValue, alpha, alpha+1, depth, selectivity, score)) return score; if (MPC(P, O, NodeCounter, alpha, selectivity, depth, empties, score)) return score; CMoveList mvList(P, O, NodeCounter, BitBoardPossible, depth, alpha, ttValue, false); for (const auto& mv : mvList) // ETC { if (StabilityCutoff_ZWS(mv.P, mv.O, -alpha - 1, score)) { UpdateTT(P, O, 0, alpha, alpha + 1, -score, depth, NO_SELECTIVITY, mv.move, mvList.BestMove(), mvList.NextBestMove()); return -score; } if (LookUpTT(mv.P, mv.O, ttValue) && UseTTValue(ttValue, -alpha - 1, -alpha, depth - 1, selectivity, score) && (-score > alpha)) { UpdateTT(P, O, 0, alpha, alpha+1, -score, depth, selectivity, mv.move, mvList.BestMove(), mvList.NextBestMove()); return -score; } } for (const auto& mv : mvList) { score = -ZWS(mv.P, mv.O, NodeCounter, -alpha-1, selectivity, depth-1, empties-1); if (score > bestscore) { bestscore = score; BestMove = mv.move; if (score > alpha) break; } } if (empties-1 <= B) UpdateTT(P, O, NodeCounter-LocalNodeCounter, alpha, alpha+1, bestscore, depth, NO_SELECTIVITY, BestMove, mvList.BestMove(), mvList.NextBestMove()); else UpdateTT(P, O, NodeCounter-LocalNodeCounter, alpha, alpha+1, bestscore, depth, selectivity, BestMove, mvList.BestMove(), mvList.NextBestMove()); return bestscore; }