Beispiel #1
0
def main():
    print(header.lstrip())

    print('all_bfs = {')
    for dim, _dbfs in all_bfs.items():
        print('    {} : {{'.format(dim))
        for order, _bfs in _dbfs.items():
            print('        {} : ['.format(order))
            vs = [x, y, z][:dim]
            bfs = [
                sm.horner(
                    sm.simplify(
                        bf.subs({
                            x: -1 + 2 * x,
                            y: -1 + 2 * y,
                            z: -1 + 2 * z
                        }))) for bf in _bfs
            ]
            bfgs = [[sm.horner(sm.simplify(bf.diff(v))) for v in vs]
                    for bf in bfs]

            print('                [')
            for bf in bfs:
                print((' ' * 16), str(bf).replace('1.0*', ''), ',')
            print('                ],')
            print('                [')
            for bfg in bfgs:
                print((' ' * 16), str(bfg).replace('1.0*', ''), ',')
            print('                ],')

            print('        ],')
        print('    },')
    print('}')
Beispiel #2
0
def sympy_get_monomials(dimension, degree, vector=False):
    xs = smp.symbols(['x[{:d}]'.format(ii) for ii in range(dimension)],
                     real=True)
    monos = smp.polys.monomials.itermonomials(xs, degree)
    for xx in xs:
        monos = [smp.horner(mm, wrt=xx) for mm in monos]
    monos = sorted(monos,
                   key=smp.polys.orderings.monomial_key('grlex', xs[::-1]))[1:]
    if vector:
        expressions = [
            Constant([0 for ll in range(kk)] + [1] +
                     [0 for ll in range(kk + 1, dimension)])
            for kk in range(dimension)
        ]
        expressions += [
            Expression(['0' for ll in range(kk)] + [smp.ccode(mm)] +
                       ['0' for ll in range(kk + 1, dimension)],
                       degree=int(smp.degree(mm))) for mm in monos
            for kk in range(dimension)
        ]
    else:
        expressions = [Constant(1)]
        expressions += [
            Expression(smp.ccode(mm), degree=int(smp.degree(mm)))
            for mm in monos
        ]
    return expressions
 def compute_fast_beta(self):
     self.fast_beta = []
     for i in range(len(self.beta)):
         self.fast_beta.append([[sp.utilities.lambdify((self.xi),
             sp.horner(sp.Poly((self.beta[i][j][k].coef[::-1]), self.xi)), np)
                                 for k in range(len(self.beta[i][j]))]
                                for j in range(self.m + 1)])
     return None
Beispiel #4
0
def poly_factorize(poly):
    """Factorize multivariate polynomials into a sum of products of monomials.

    This function can be used to decompose polynomials into a form which
    minimizes the number of additions and multiplications, and which thus
    can be evaluated efficently."""
    max_deg = {}

    if 'horner' in dir(sympy):
        return sympy.horner(poly)

    if not isinstance(poly, Poly):
        poly = Poly(sympy.expand(poly), *poly.atoms(Symbol))

    denom, poly = poly.as_integer()

    # Determine the order of factorization.  We proceed through the
    # symbols, starting with the one present in the highest order
    # in the polynomial.
    for i, sym in enumerate(poly.symbols):
        max_deg[i] = 0

    for monom in poly.monoms:
        for i, symvar in enumerate(monom):
            max_deg[i] = max(max_deg[i], symvar)

    ret_poly = 0
    monoms = list(poly.monoms)

    for isym, maxdeg in sorted(max_deg.items(),
                               key=itemgetter(1),
                               reverse=True):
        drop_idx = []
        new_poly = []

        for i, monom in enumerate(monoms):
            if monom[isym] > 0:
                drop_idx.append(i)
                new_poly.append((poly.coeff(*monom), monom))

        if not new_poly:
            continue

        ret_poly += sympy.factor(Poly(new_poly, *poly.symbols))

        for idx in reversed(drop_idx):
            del monoms[idx]

    # Add any remaining O(1) terms.
    new_poly = []
    for i, monom in enumerate(monoms):
        new_poly.append((poly.coeff(*monom), monom))

    if new_poly:
        ret_poly += Poly(new_poly, *poly.symbols)

    return ret_poly / denom
Beispiel #5
0
def poly_factorize(poly):
    """Factorize multivariate polynomials into a sum of products of monomials.

    This function can be used to decompose polynomials into a form which
    minimizes the number of additions and multiplications, and which thus
    can be evaluated efficently."""
    max_deg = {}

    if 'horner' in dir(sympy):
        return sympy.horner(poly)

    if not isinstance(poly, Poly):
        poly = Poly(sympy.expand(poly), *poly.atoms(Symbol))

    denom, poly = poly.as_integer()

    # Determine the order of factorization.  We proceed through the
    # symbols, starting with the one present in the highest order
    # in the polynomial.
    for i, sym in enumerate(poly.symbols):
        max_deg[i] = 0

    for monom in poly.monoms:
        for i, symvar in enumerate(monom):
            max_deg[i] = max(max_deg[i], symvar)

    ret_poly = 0
    monoms = list(poly.monoms)

    for isym, maxdeg in sorted(max_deg.items(), key=itemgetter(1), reverse=True):
        drop_idx = []
        new_poly = []

        for i, monom in enumerate(monoms):
            if monom[isym] > 0:
                drop_idx.append(i)
                new_poly.append((poly.coeff(*monom), monom))

        if not new_poly:
            continue

        ret_poly += sympy.factor(Poly(new_poly, *poly.symbols))

        for idx in reversed(drop_idx):
            del monoms[idx]

    # Add any remaining O(1) terms.
    new_poly = []
    for i, monom in enumerate(monoms):
        new_poly.append((poly.coeff(*monom), monom))

    if new_poly:
        ret_poly += Poly(new_poly, *poly.symbols)

    return ret_poly / denom
Beispiel #6
0
 def compute_fast_beta(self):
     self.fast_beta = []
     for i in range(len(self.beta)):
         self.fast_beta.append([[
             sp.utilities.lambdify(
                 (self.xi),
                 sp.horner(sp.Poly((self.beta[i][j][k].coef[::-1]),
                                   self.xi)), np)
             for k in range(len(self.beta[i][j]))
         ] for j in range(self.m + 1)])
     return None
Beispiel #7
0
    def _parse(cls, raw):
        raw = list(raw)
        x = sympy.Symbol(cls._spce.x)
        exprs = list(map(sympy.parse_expr, raw))

        # attemps polynom extraction
        try:
            # polys = [sympy.poly(f, x, domain="RR") for f in exprs]
            polys = sympy.parallel_poly_from_expr(exprs, x, domain="RR")[0]
        except sympy.PolynomialError:
            pass
        else:
            ncoeff = max(len(p.all_coeffs()) for p in polys)
            coeffs = np.zeros((len(polys), ncoeff), dtype=cls.dtype)
            coeffs[:, 0] = 1
            for i, p in enumerate(polys):
                c = p.all_coeffs()[::-1]
                coeffs[i, : len(c)] = c

            expr = sympy.horner(sympy.Poly.from_list(cls._spce.symbols(ncoeff)[::-1], x))
            return expr, coeffs

        # extraction
        for formulas in list(map(sympy.simplify, exprs)), exprs:

            expr = set()
            coeffs = []
            for e, c in map(cls._spce.extract, formulas):
                expr.add(e)
                if len(expr) > 1:
                    break
                coeffs.append(c)
            else:
                (expr,) = list(expr)
                coeff0 = np.array(coeffs[0], dtype=object)
                coeffs = np.array(coeffs, dtype=cls.dtype)
                const = np.all(coeffs[:1] == coeffs, axis=0)
                symbols = np.array(cls._spce.symbols(len(const)))
                # put back constants
                expr = expr.xreplace(dict(zip(symbols[const], coeff0[const])))
                # shift symbols
                for old, new in zip(symbols[~const], symbols):
                    if old != new:
                        assert new not in expr.free_symbols
                        expr.replace(old, new)
                # shift coeffs
                coeffs = coeffs[:, ~const]

                # horner-ify
                expr = expr.replace(cls._horner_test, sympy.horner)

                return expr, coeffs

        return RuntimeError("\t\n".join(["can't unify expression:"] + raw))
Beispiel #8
0
def run_transmute_test(data,
                       degree,
                       prec,
                       time,
                       *,
                       expr=None,
                       plot=True,
                       _print=False,
                       run_all=True,
                       use_cache=True,
                       thetas=None,
                       alphas=None,
                       alpha0=None):
    """
    Run transmute test on the data

    If run_all=True, runs the test on all forms of the exponential. Otherwise,
    only use part_frac_complex (the fastest).
    """
    nucs, matrix = load_sparse_csr(data)

    expr = get_CRAM_from_cache(degree,
                               prec,
                               expr=expr,
                               plot=plot,
                               use_cache=use_cache)

    num, den = fraction(expr)

    if not (thetas and alphas and alpha0):
        thetas, alphas, alpha0 = thetas_alphas(expr, prec)
    part_frac = thetas_alphas_to_expr_real(thetas, alphas, alpha0)
    part_frac_complex = thetas_alphas_to_expr_complex(thetas, alphas, alpha0)
    # part_frac_complex2 = thetas_alphas_to_expr_complex2(thetas, alphas, alpha0)

    e = {}

    from ..py_solve import py_solve

    py_solve_expm = getattr(py_solve, 'expmI%d' % degree)
    e['transmutagen generated C solver'] = lambda m: py_solve_expm(m).T

    e['part_frac_complex UMFPACK'] = lambda m: (use_solver(
        useUmfpack=True) or lambdify_expr(part_frac_complex)(m))
    e['part_frac_complex SuperLU'] = lambda m: (use_solver(
        useUmfpack=False) or lambdify_expr(part_frac_complex)(m))
    e['scipy.sparse.linalg.expm'] = lambda m: expm(-m)
    if run_all:
        e['rat_func'] = lambdify_expr(expr)
        e['rat_func_horner'] = lambdify_expr(horner(num) / horner(den))
        e['part_frac'] = lambdify_expr(part_frac)
        # e['part_frac_complex2'] = lambdify_expr(part_frac_complex2)

    res = {}
    for func in sorted(e):
        if _print:
            print(func)
        arg = -matrix * time
        res[func] = time_and_run(e[func], arg, _print=_print)

    return res
def gen_lobatto(max_order):
    assert max_order > 2

    x = sm.symbols('x')

    lobs = [0, 1]
    lobs[0] = (1 - x) / 2
    lobs[1] = (1 + x) / 2

    dlobs = [lob.diff('x') for lob in lobs]

    legs = [sm.legendre(0, 'y')]
    clegs = [sm.ccode(legs[0])]
    dlegs = [sm.legendre(0, 'y').diff('y')]
    cdlegs = [sm.ccode(dlegs[0])]

    clobs = [sm.ccode(lob) for lob in lobs]
    cdlobs = [sm.ccode(dlob) for dlob in dlobs]

    denoms = []  # for lobs.

    for ii in range(2, max_order + 1):
        coef = sm.sympify('sqrt(2 * (2 * %s - 1)) / 2' % ii)
        leg = sm.legendre(ii - 1, 'y')

        pleg = leg.as_poly()
        coefs = pleg.all_coeffs()
        denom = max(sm.denom(val) for val in coefs)

        cleg = sm.ccode(sm.horner(leg * denom) / denom)

        dleg = leg.diff('y')
        cdleg = sm.ccode(sm.horner(dleg * denom) / denom)

        lob = sm.simplify(coef * sm.integrate(leg, ('y', -1, x)))
        lobnc = sm.simplify(sm.integrate(leg, ('y', -1, x)))

        plobnc = lobnc.as_poly()
        coefs = plobnc.all_coeffs()
        denom = sm.denom(coef) * max(sm.denom(val) for val in coefs)

        clob = sm.ccode(sm.horner(lob * denom) / denom)

        dlob = lob.diff('x')
        cdlob = sm.ccode(sm.horner(dlob * denom) / denom)

        legs.append(leg)
        clegs.append(cleg)
        dlegs.append(dleg)
        cdlegs.append(cdleg)
        lobs.append(lob)
        clobs.append(clob)
        dlobs.append(dlob)
        cdlobs.append(cdlob)
        denoms.append(denom)

    coef = sm.sympify('sqrt(2 * (2 * %s - 1)) / 2' % (max_order + 1))
    leg = sm.legendre(max_order, 'y')

    pleg = leg.as_poly()
    coefs = pleg.all_coeffs()
    denom = max(sm.denom(val) for val in coefs)

    cleg = sm.ccode(sm.horner(leg * denom) / denom)

    dleg = leg.diff('y')
    cdleg = sm.ccode(sm.horner(dleg * denom) / denom)

    legs.append(leg)
    clegs.append(cleg)
    dlegs.append(dleg)
    cdlegs.append(cdleg)

    kerns = []
    ckerns = []
    dkerns = []
    cdkerns = []
    for ii, lob in enumerate(lobs[2:]):
        kern = sm.simplify(lob / (lobs[0] * lobs[1]))
        dkern = kern.diff('x')

        denom = denoms[ii] / 4
        ckern = sm.ccode(sm.horner(kern * denom) / denom)
        cdkern = sm.ccode(sm.horner(dkern * denom) / denom)

        kerns.append(kern)
        ckerns.append(ckern)
        dkerns.append(dkern)
        cdkerns.append(cdkern)

    return (legs, clegs, dlegs, cdlegs, lobs, clobs, dlobs, cdlobs, kerns,
            ckerns, dkerns, cdkerns, denoms)
Beispiel #10
0
def gen_lobatto(max_order):
    assert max_order > 2

    x = sm.symbols('x')

    lobs = [0, 1]
    lobs[0] = (1 - x) / 2
    lobs[1] = (1 + x) / 2

    dlobs = [lob.diff('x') for lob in lobs]

    legs = [sm.legendre(0, 'y')]
    clegs = [sm.ccode(legs[0])]
    dlegs = [sm.legendre(0, 'y').diff('y')]
    cdlegs = [sm.ccode(dlegs[0])]

    clobs = [sm.ccode(lob) for lob in lobs]
    cdlobs = [sm.ccode(dlob) for dlob in dlobs]

    denoms = [] # for lobs.

    for ii in range(2, max_order + 1):
        coef = sm.sympify('sqrt(2 * (2 * %s - 1)) / 2' % ii)
        leg = sm.legendre(ii - 1, 'y')

        pleg = leg.as_poly()
        coefs = pleg.all_coeffs()
        denom = max(sm.denom(val) for val in coefs)

        cleg = sm.ccode(sm.horner(leg*denom)/denom)

        dleg = leg.diff('y')
        cdleg = sm.ccode(sm.horner(dleg*denom)/denom)

        lob = sm.simplify(coef * sm.integrate(leg, ('y', -1, x)))
        lobnc = sm.simplify(sm.integrate(leg, ('y', -1, x)))

        plobnc = lobnc.as_poly()
        coefs = plobnc.all_coeffs()
        denom = sm.denom(coef) * max(sm.denom(val) for val in coefs)

        clob = sm.ccode(sm.horner(lob*denom)/denom)

        dlob = lob.diff('x')
        cdlob = sm.ccode(sm.horner(dlob*denom)/denom)

        legs.append(leg)
        clegs.append(cleg)
        dlegs.append(dleg)
        cdlegs.append(cdleg)
        lobs.append(lob)
        clobs.append(clob)
        dlobs.append(dlob)
        cdlobs.append(cdlob)
        denoms.append(denom)

    coef = sm.sympify('sqrt(2 * (2 * %s - 1)) / 2' % (max_order + 1))
    leg = sm.legendre(max_order, 'y')

    pleg = leg.as_poly()
    coefs = pleg.all_coeffs()
    denom = max(sm.denom(val) for val in coefs)

    cleg = sm.ccode(sm.horner(leg*denom)/denom)

    dleg = leg.diff('y')
    cdleg = sm.ccode(sm.horner(dleg*denom)/denom)

    legs.append(leg)
    clegs.append(cleg)
    dlegs.append(dleg)
    cdlegs.append(cdleg)

    kerns = []
    ckerns = []
    dkerns = []
    cdkerns = []
    for ii, lob in enumerate(lobs[2:]):
        kern = sm.simplify(lob / (lobs[0] * lobs[1]))
        dkern = kern.diff('x')

        denom = denoms[ii] / 4
        ckern = sm.ccode(sm.horner(kern*denom)/denom)
        cdkern = sm.ccode(sm.horner(dkern*denom)/denom)

        kerns.append(kern)
        ckerns.append(ckern)
        dkerns.append(dkern)
        cdkerns.append(cdkern)

    return (legs, clegs, dlegs, cdlegs,
            lobs, clobs, dlobs, cdlobs,
            kerns, ckerns, dkerns, cdkerns,
            denoms)
 def parse(f, fac=1, vec=False, toOpenCL=True,
           CLBuiltins=False, keep=False):
     """
     Parsing function.
     @param f : functions to parse as string
     @param fac : numeric factor for all formulas
     @param vec : is OpenCL output is generated to use vector builtin types
     @param toOpenCL : is OpenCL output
     @param CLBuiltins : is OpenCL output uses fma builtin function
     @param keep : low parsing
     """
     msg = 'Vector works only in OpenCL parsing'
     assert not (vec and not toOpenCL), msg
     assert not (CLBuiltins and not toOpenCL),\
         "CLBuiltins only in OpenCL parsing"
     t = "float__N__" if vec else "float"
     cteEnd = ".0" if toOpenCL else "."
     res = ""
     # Split each line
     fl = f.split('\n')
     # sympy formulas
     y = sp.symbols('y')
     print (y)
     sw = [None] * f.count(';')
     i = 0
     for wl in fl:
         if len(wl) > 2:
             # replace pow
             power = re.search('pow\(y, ([0-9]+)\)', wl)
             if power is not None:
                 np = "y" + "*y" * (int(power.group(1)) - 1)
                 wl = wl.replace(power.group(0), np)
             sw[i] = '('
             sw[i] += str(sp.horner(eval(wl.split(';')[0].split('=')[1]) * fac))
             sw[i] += ')/' + str(fac)
             i += 1
     for i, s in enumerate(sw):
         if not keep:
             if toOpenCL:
                 res += "inline " + t + " "
                 res += weights_names[i] + "(" + t + " y){\n"
                 res += '  return '
             else:
                 res += 'lambda y, s: s * '
             res += '('
             # replace y**n
             power = re.findall('y\*\*[0-9]+', s)
             if power is not None:
                 for pw in power:
                     n = int(pw.split('**')[1])
                     npower = 'y' + "*y" * (n - 1)
                     s = s.replace(pw, npower)
             s = s.replace(' ', '')
             if CLBuiltins:
                 s = createFMA(s)
             # From integers to floats
             s = re.sub(r"(?P<id>[0-9]+)", r"\g<id>" + cteEnd, s)
             s = s.replace('*', ' * ')
             s = s.replace('/', ' / ')
             s = s.replace('+', ' + ')
             s = s.replace('-', ' - ')
             s = s.replace('( - ', '(-')
             s = s.replace('  ', ' ')
             s = s.replace(", - ", ", -")
             res += s + ')'
             if toOpenCL:
                 res += ";}"
             if i < len(sw) - 1:
                 res += "\n"
         else:
             res += "w[{0}] = ".format(i)
             # replace y**n
             power = re.findall('y\*\*[0-9]+', s)
             if power is not None:
                 for pw in power:
                     n = int(pw.split('**')[1])
                     npower = 'y' + "*y" * (n - 1)
                     s = s.replace(pw, npower)
             # From integers to floats
             s = re.sub(r"(?P<id>[0-9]+)", r"\g<id>.", s)
             s = s.replace('*', ' * ')
             s = s.replace('/', ' / ')
             s = s.replace('+', ' + ')
             s = s.replace('-', ' - ')
             s = s.replace('( - ', '(-')
             s = s.replace('  ', ' ')
             s = s.replace(", - ", ", -")
             res += s + "\n"
     return res