Esempio n. 1
0
 def _eval_number(cls, arg):
     if arg.is_Number:
         if arg.is_Rational:
             return -C.Integer(-arg.p // arg.q)
         elif arg.is_Float:
             return C.Integer(int(arg.ceiling()))
         else:
             return arg
     if arg.is_NumberSymbol:
         return arg.approximation_interval(C.Integer)[1]
Esempio n. 2
0
 def _eval_number(cls, arg):
     if arg.is_Number:
         if arg.is_Rational:
             if not arg.q:
                 return arg
             return C.Integer(arg.p // arg.q)
         elif arg.is_Float:
             return C.Integer(int(arg.floor()))
     if arg.is_NumberSymbol:
         return arg.approximation_interval(C.Integer)[0]
Esempio n. 3
0
    def eval(cls, arg):
        if arg.is_integer:
            return arg
        if arg.is_imaginary or (S.ImaginaryUnit*arg).is_real:
            i = C.im(arg)
            if not i.has(S.ImaginaryUnit):
                return cls(i)*S.ImaginaryUnit
            return cls(arg, evaluate=False)

        v = cls._eval_number(arg)
        if v is not None:
            return v

        # Integral, numerical, symbolic part
        ipart = npart = spart = S.Zero

        # Extract integral (or complex integral) terms
        terms = Add.make_args(arg)

        for t in terms:
            if t.is_integer or (t.is_imaginary and C.im(t).is_integer):
                ipart += t
            elif t.has(C.Symbol):
                spart += t
            else:
                npart += t

        if not (npart or spart):
            return ipart

        # Evaluate npart numerically if independent of spart
        if npart and (
            not spart or
            npart.is_real and (spart.is_imaginary or (S.ImaginaryUnit*spart).is_real) or
                npart.is_imaginary and spart.is_real):
            try:
                re, im = get_integer_part(
                    npart, cls._dir, {}, return_ints=True)
                ipart += C.Integer(re) + C.Integer(im)*S.ImaginaryUnit
                npart = S.Zero
            except (PrecisionExhausted, NotImplementedError):
                pass

        spart += npart
        if not spart:
            return ipart
        elif spart.is_imaginary or (S.ImaginaryUnit*spart).is_real:
            return ipart + cls(C.im(spart), evaluate=False)*S.ImaginaryUnit
        else:
            return ipart + cls(spart, evaluate=False)
Esempio n. 4
0
    def canonize(cls, arg):
        if arg.is_integer:
            return arg
        if arg.is_imaginary:
            return cls(C.im(arg)) * S.ImaginaryUnit

        v = cls._eval_number(arg)
        if v is not None:
            return v

        # Integral, numerical, symbolic part
        ipart = npart = spart = S.Zero

        # Extract integral (or complex integral) terms
        if arg.is_Add:
            terms = arg.args
        else:
            terms = [arg]

        for t in terms:
            if t.is_integer or (t.is_imaginary and C.im(t).is_integer):
                ipart += t
            elif t.atoms(C.Symbol):
                spart += t
            else:
                npart += t

        if not (npart or spart):
            return ipart

        # Evaluate npart numerically if independent of spart
        orthogonal = (npart.is_real and spart.is_imaginary) or \
            (npart.is_imaginary and spart.is_real)
        if npart and ((not spart) or orthogonal):
            try:
                re, im = get_integer_part(npart,
                                          cls._dir, {},
                                          return_ints=True)
                ipart += C.Integer(re) + C.Integer(im) * S.ImaginaryUnit
                npart = S.Zero
            except (PrecisionExhausted, NotImplementedError):
                pass

        spart = npart + spart
        if not spart:
            return ipart
        elif spart.is_imaginary:
            return ipart + cls(C.im(spart), evaluate=False) * S.ImaginaryUnit
        else:
            return ipart + cls(spart, evaluate=False)
Esempio n. 5
0
    def eval(cls, n):
        n = sympify(n)

        if n.is_Number:
            if n is S.Zero:
                return S.One
            elif n.is_Integer:
                if n.is_negative:
                    return S.Zero
                else:
                    n, result = n.p, 1

                    if n < 20:
                        for i in range(2, n + 1):
                            result *= i
                    else:
                        N, bits = n, 0

                        while N != 0:
                            if N & 1 == 1:
                                bits += 1

                            N = N >> 1

                        result = cls._recursive(n) * 2**(n - bits)

                    return C.Integer(result)

        if n.is_integer:
            if n.is_negative:
                return S.Zero
        else:
            return C.gamma(n + 1)
Esempio n. 6
0
    def eval(cls, r, k):
        r, k = map(sympify, (r, k))

        if k.is_Number:
            if k is S.Zero:
                return S.One
            elif k.is_Integer:
                if k.is_negative:
                    return S.Zero
                else:
                    if r.is_Integer and r.is_nonnegative:
                        r, k = int(r), int(k)

                        if k > r:
                            return S.Zero
                        elif k > r // 2:
                            k = r - k

                        M, result = int(sqrt(r)), 1

                        for prime in sieve.primerange(2, r + 1):
                            if prime > r - k:
                                result *= prime
                            elif prime > r // 2:
                                continue
                            elif prime > M:
                                if r % prime < k % prime:
                                    result *= prime
                            else:
                                R, K = r, k
                                exp = a = 0

                                while R > 0:
                                    a = int((R % prime) < (K % prime + a))
                                    R, K = R // prime, K // prime
                                    exp = a + exp

                                if exp > 0:
                                    result *= prime**exp

                        return C.Integer(result)
                    else:
                        result = r - k + 1

                        for i in xrange(2, k + 1):
                            result *= r - k + i
                            result /= i

                        return result

        if k.is_integer:
            if k.is_negative:
                return S.Zero
        else:
            return C.gamma(r + 1) / (C.gamma(r - k + 1) * C.gamma(k + 1))