def test_solve_mul(self): L = Dimension({"length":1}) solution = dim_solve( Mul(L, Symbol("x")), L.mul(L) ) self.assertEqual(solution["x"], L)
def test_solve_pow(self): L = Dimension({"length":1}) T = Dimension({"time":1}) solution = dim_solve( sympify("a*(t-b)**2+c"), L, {'t': T} ) self.assertEqual(solution["b"], T) self.assertEqual(solution["a"], L.mul(T.pow(-2))) self.assertEqual(solution["t"], T) self.assertEqual(solution["c"], L)
def dim_simplify(expr): """ Simplify expression by recursively evaluating the dimension arguments. This function proceeds to a very rough dimensional analysis. It tries to simplify expression with dimensions, and it deletes all what multiplies a dimension without being a dimension. This is necessary to avoid strange behavior when Add(L, L) be transformed into Mul(2, L). """ if isinstance(expr, Dimension): return expr if isinstance(expr, Symbol): return None args = [] for arg in expr.args: if isinstance(arg, (Mul, Pow, Add, Symbol, Function)): arg = dim_simplify(arg) args.append(arg) if all([arg!=None and (arg.is_number or (isinstance(arg, Dimension) and arg.is_dimensionless)) for arg in args]): return Dimension({}) if isinstance(expr, Function): raise ValueError("Arguments of this function cannot have a dimension: %s" % expr) elif isinstance(expr, Pow): if isinstance(args[0], Dimension): return args[0].pow(args[1]) else: return None elif isinstance(expr, Add): dimargs = [arg for arg in args if isinstance(arg, Dimension)] if (all(isinstance(arg, Dimension) or arg==None for arg in args) or all(arg.is_dimensionless for arg in dimargs)): if len(dimargs)>0: return reduce(lambda x, y: x.add(y), dimargs) else: return Dimension({}) else: raise ValueError("Dimensions cannot be added: %s" % expr) elif isinstance(expr, Mul): result = Dimension({}) for arg in args: if isinstance(arg, Dimension): result = result.mul(arg) elif arg == None: return None return result return None