diff --git a/numga/backend/python/context.py b/numga/backend/python/context.py index 15b9970..34707a1 100644 --- a/numga/backend/python/context.py +++ b/numga/backend/python/context.py @@ -4,10 +4,10 @@ class PythonContext(AbstractContext): - def __init__(self, algebra, dtype=float): + def __init__(self, algebra, dtype=float, otype=PythonSparseOperator): super(PythonContext, self).__init__( algebra=algebra, dtype=dtype, - otype=PythonSparseOperator, + otype=otype, mvtype=PythonMultiVector ) diff --git a/numga/backend/python/operator.py b/numga/backend/python/operator.py index 9d5ba9a..9158664 100644 --- a/numga/backend/python/operator.py +++ b/numga/backend/python/operator.py @@ -16,9 +16,28 @@ def __call__(self, *inputs: Tuple[PythonMultiVector]) -> PythonMultiVector: math.prod((inp.values[ii] for inp, ii in zip(inputs, idx)), start=scalar) for (idx, scalar) in term ) + return output - # def partial(self, inputs: Dict[int, PythonMultiVector]) -> "PythonSparseOperator": + +class PythonCodegenOperator(AbstractConcreteOperator): + """quick and dirty python codegen example""" + + def __call__(self, *inputs: Tuple[PythonMultiVector]) -> PythonMultiVector: + terms = self.precompute_sparse + inputs = [f'i{i}' for i in range(self.operator.arity)] + inp = ','.join(inputs) + text = f'def foo({inp}):\n' + def make_term(idx, scalar): + q = [inp + f'[{ii}]' for inp, ii in zip(inputs, idx)] + return '*'.join([str(scalar)] + q) + + def make_line(ci, term): + return f'\to[{ci}] = ' + '+'.join(make_term(idx, scalar) for idx, scalar in term) + + return text + '\n'.join(make_line(ci, term) for ci, term in terms) + +# def partial(self, inputs: Dict[int, PythonMultiVector]) -> "PythonSparseOperator": # expr = self.precompute_einsum_partial(tuple(inputs.keys())) # return PythonSparseOperator( # self.context, diff --git a/numga/backend/test/test_python.py b/numga/backend/test/test_python.py index d9c14f4..86c8c5d 100644 --- a/numga/backend/test/test_python.py +++ b/numga/backend/test/test_python.py @@ -11,3 +11,12 @@ def test_sparse_operator(): output = q.sandwich(v) print(output) + + +def test_codegen(): + from numga.backend.python.operator import PythonCodegenOperator + ga = PythonContext('x+y+z+', otype=PythonCodegenOperator) + even = ga.subspace.even_grade() + op = ga.operator.product(even, even) + print() + print(op())