Skip to content

Commit

Permalink
fix: fix derivative dimensional analysis bug
Browse files Browse the repository at this point in the history
Fixes case where derivative evaluates to a number but variable of integration is not defined.
  • Loading branch information
mgreminger committed Oct 5, 2024
1 parent 5b7f576 commit 8bfc41e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
23 changes: 14 additions & 9 deletions public/dimensional_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -932,8 +932,8 @@ def ensure_dims_all_compatible(*args):
if len(args) == 1:
return first_arg

first_arg_dims = dimsys_SI.get_dimensional_dependencies(first_arg)
if all(dimsys_SI.get_dimensional_dependencies(arg) == first_arg_dims for arg in args[1:]):
first_arg_dims = custom_get_dimensional_dependencies(first_arg)
if all(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')
Expand All @@ -950,26 +950,26 @@ def ensure_dims_all_compatible_piecewise(*args):
return ensure_dims_all_compatible(*[arg[0] for arg in args])

def ensure_unitless_in_angle_out(arg):
if dimsys_SI.get_dimensional_dependencies(arg) == {}:
if custom_get_dimensional_dependencies(arg) == {}:
return angle
else:
raise TypeError('Unitless input argument required for function')

def ensure_unitless_in(arg):
if dimsys_SI.get_dimensional_dependencies(arg) == {}:
if custom_get_dimensional_dependencies(arg) == {}:
return arg
else:
raise TypeError('Unitless input argument required for function')

def ensure_any_unit_in_angle_out(arg):
# ensure input arg units make sense (will raise if inconsistent)
dimsys_SI.get_dimensional_dependencies(arg)
custom_get_dimensional_dependencies(arg)

return angle

def ensure_any_unit_in_same_out(arg):
# ensure input arg units make sense (will raise if inconsistent)
dimsys_SI.get_dimensional_dependencies(arg)
custom_get_dimensional_dependencies(arg)

return arg

Expand All @@ -983,7 +983,7 @@ def ensure_inverse_dims(arg):
row = []
rows.append(row)
for j in range(arg.cols):
dim, _ = get_mathjs_units(cast(dict[Dimension, float], dimsys_SI.get_dimensional_dependencies(arg[j,i])))
dim, _ = get_mathjs_units(cast(dict[Dimension, float], custom_get_dimensional_dependencies(cast(Expr, arg[j,i]))))
if dim == "":
row.append(sympify('0'))
else:
Expand Down Expand Up @@ -1638,6 +1638,11 @@ def get_dimensional_analysis_expression(parameter_subs: dict[Symbol, Expr],
return final_expression, error


def custom_get_dimensional_dependencies(expression: Expr | None):
if expression is not None:
expression = subs_wrapper(expression, {cast(Symbol, symbol): sympify('1') for symbol in expression.free_symbols})
return dimsys_SI.get_dimensional_dependencies(expression)

def dimensional_analysis(dimensional_analysis_expression: Expr | None, dim_sub_error: Exception | None,
custom_base_units: CustomBaseUnits | None = None):
custom_units_defined = False
Expand All @@ -1649,13 +1654,13 @@ def dimensional_analysis(dimensional_analysis_expression: Expr | None, dim_sub_e
raise dim_sub_error
# Finally, evaluate dimensions for complete expression
result, result_latex = get_mathjs_units(
cast(dict[Dimension, float], dimsys_SI.get_dimensional_dependencies(dimensional_analysis_expression),),
cast(dict[Dimension, float], custom_get_dimensional_dependencies(dimensional_analysis_expression),),
None
)

if custom_base_units is not None:
custom_units, custom_units_latex = get_mathjs_units(
cast(dict[Dimension, float], dimsys_SI.get_dimensional_dependencies(dimensional_analysis_expression),),
cast(dict[Dimension, float], custom_get_dimensional_dependencies(dimensional_analysis_expression),),
custom_base_units
)

Expand Down
12 changes: 12 additions & 0 deletions tests/test_calc.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,15 @@ test('Test numerical integral and derivative using interpolation function', asyn
content = await page.textContent('#result-units-1');
expect(content).toBe('');
});

test('Test derivative dimensional analysis bug', async () => {
await page.setLatex(0, String.raw`\frac{\mathrm{d}}{\mathrm{d}\left(x\right)}\left(x+1\right)=`);

await page.waitForSelector('.status-footer', {state: 'detached'});

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

0 comments on commit 8bfc41e

Please sign in to comment.