Skip to content

Commit

Permalink
fix: fix error recognizing small differences in dimension exponents a…
Browse files Browse the repository at this point in the history
…s being equal

Test added
  • Loading branch information
mgreminger committed Jan 10, 2025
1 parent 2bd9f13 commit d060821
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
30 changes: 26 additions & 4 deletions public/dimensional_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
Integer
)

from sympy import S

class ExprWithAssumptions(Expr):
is_finite: bool
is_integer: bool
Expand Down Expand Up @@ -867,7 +869,22 @@ def custom_latex(expression: Expr) -> str:

_range = Function("_range")

def ensure_dims_all_compatible(*args):
def dimensional_dependencies_equal(input1, input2):
keys1 = set(input1.keys())
keys2 = set(input2.keys())

for key in keys1 ^ keys2: # symmetric difference
if input1.get(key, S.Zero).round(EXP_NUM_DIGITS) != S.Zero or \
input2.get(key, S.Zero).round(EXP_NUM_DIGITS) != S.Zero:
return False

for key in keys1 & keys2: # union
if input1[key].round(EXP_NUM_DIGITS) != input2[key].round(EXP_NUM_DIGITS):
return False

return True

def ensure_dims_all_compatible(*args, error_message=None):
if args[0].is_zero:
if all(arg.is_zero for arg in args):
first_arg = sympify('0')
Expand All @@ -880,10 +897,14 @@ def ensure_dims_all_compatible(*args):
return first_arg

first_arg_dims = custom_get_dimensional_dependencies(first_arg)
if all(custom_get_dimensional_dependencies(arg) == first_arg_dims for arg in args[1:]):

if all(dimensional_dependencies_equal(custom_get_dimensional_dependencies(arg), first_arg_dims) for arg in args[1:]):
return first_arg

raise TypeError('All input arguments to function need to have compatible units')
if error_message is None:
raise TypeError('All input arguments to function need to have compatible units')
else:
raise TypeError(error_message)

def ensure_dims_all_compatible_scalar_or_matrix(*args):
if len(args) == 1 and is_matrix(args[0]):
Expand Down Expand Up @@ -1161,7 +1182,8 @@ def custom_integral_dims(local_expr: Expr, global_expr: Expr, dummy_integral_var
return global_expr * integral_var # type: ignore

def custom_add_dims(*args: Expr):
return Add(*[Abs(arg) for arg in args])
return ensure_dims_all_compatible(*[Abs(arg) for arg in args],
error_message="Only equivalent dimensions can be added or subtracted.")

def custom_pow(base: Expr, exponent: Expr):
large_rational = False
Expand Down
22 changes: 22 additions & 0 deletions tests/test_basic.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,28 @@ test('Test zero canceling bug with exponent', async () => {
expect(content).toBe('m');
});

test('Test floating point exponent rounding', async () => {

await page.setLatex(0, String.raw`1\left\lbrack m\right\rbrack+1\left\lbrack\frac{N^{\frac13}}{m^{\frac23}}\right\rbrack\cdot1\left\lbrack\frac{m^{\frac53}}{N^{\frac13}}\right\rbrack=`);
await page.click('#add-math-cell');
await page.setLatex(1, String.raw`1\left\lbrack N\cdot s^{.0000000000001}\right\rbrack+2\left\lbrack N\right\rbrack=`);
await page.click('#add-math-cell');
await page.setLatex(2, String.raw`1\left\lbrack N\cdot s^{.000000000001}\right\rbrack+2\left\lbrack N\right\rbrack=`);

await page.waitForSelector('text=Updating...', {state: 'detached'});

let content = await page.textContent('#result-value-0');
expect(parseLatexFloat(content)).toBeCloseTo(2, precision);
content = await page.textContent('#result-units-0');
expect(content).toBe('m');

content = await page.textContent('#result-value-1');
expect(parseLatexFloat(content)).toBeCloseTo(3, precision);
content = await page.textContent('#result-units-1');
expect(content).toBe('N');

await expect(page.locator('#cell-2 >> text=Dimension Error')).toBeVisible();
});

test('Test function notation with integrals', async () => {

Expand Down

0 comments on commit d060821

Please sign in to comment.