def _assign(self, math): q = re_math.assignment.match(math) name, value = q.group(1), q.group(2) name = name.replace(' ', '') if '(' in name: fn = name[:name.index('(')] if not re_math.variable_name.match(fn): raise ValueError('Invalid name') params = util.get_inner(name[name.index('('):])[0] self._['functions'][fn] = { 'call': lambda *args : self.compute(util.replace_list(params.split(','), args, value), True), 'math': math } result = self._['functions'][fn]['call'] else: if not re_math.variable_name.match(name): raise ValueError('Invalid name') result = self.compute(value); self._['variables'][name] = str(result) if type(result) not in (type(np.array([])), type(np.matrix([]))) else str(result.tolist()) return result
def compute(self, math, to_string=False): math = math.lstrip() for q in re_math.parenthesis.finditer(math): inner = util.get_inner(math[q.start():])[0] math = math.replace('(' + inner + ')', self.compute(inner, True)) query = math.split(' ') if query[0] in self._['commands']: return self._['commands'][query[0]]['call'](*query[1:]) if ':=' in math: return self._assign(math) if '=' in math and not re_math.equal_sign.search(math): lhs, rhs = math.replace(' ', '').split('=') return self.compute('solve ' + lhs + '-' + rhs) for fn in self._['tex']: while fn in math: tex = util.parse_tex( math[math.index(fn):] ) math = math.replace(tex['string'], str(self._['tex'][fn]['call'](tex))) for fn in self._['functions']: while fn in math: inner = util.get_inner(math[len(fn)+math.index(fn):])[0] value = self._['functions'][fn]['call']( *self.compute('[' + inner + ']').tolist() ) math = math.replace(fn + '(' + inner + ')', value) for q in re_math.variables(self._['variables']).finditer(math): math = math.replace(q.group(0), self._['variables'][q.group(0)]) math = re_math.matrix_prod.sub(']\cdot[', math) for q in re_math.operator.finditer(math): if q.group('command') in self._['operators']: value = self._['operators'][q.group('command')]['call'](self.compute(q.group(1)), self.compute(q.group(3))) result = str(value) if type(value) is not type(np.array([])) else str(value.tolist()) math = math.replace(q.group(0), result) else: raise ValueError('Unknown Operator: ' + q.group('command')) for q in re_math.factorial.finditer(math): math = math.replace(q.group(0), str(self.compute( '\prod_{1}^{' + q.group(1) + '}{x}' ))) for q in re_math.array_index.finditer(math): math = math.replace(q.group(0), str( util.get_coordinate(self.compute(q.group(1)).tolist(), q.group(2).split(',')) )) math = re_math.in_brackets.sub(r'(\1)', math) math = math.replace('^', '**') if self.debug: print(' '.join(query) + ' = ' + math + '\n') if re_math.is_valid.search(math): for q in re_math.imaginary_number.finditer(math): math = math.replace(q.group(0), q.group(1) + '*j') math = re_math.matrix_pow.sub(r'linalg.matrix_power(\1, int(\2))', math) math = re_math.number.sub(r'np.float_(\1)', math) math = re_math.imaginary_unit.sub('1j', math) while '[' in math: inner = util.get_inner(math[math.index('['):], '[', ']')[0] math = math.replace('[' + inner + ']', 'np.array(L' + inner + 'R)' ) math = math.replace('L', '[').replace('R', ']') result = eval(math) if to_string: return str(result) if type(result) is not type(np.array([])) else str(result.tolist()) return result elif math is '': return '' else: raise ValueError('Invalid Tex')