Skip to content

Commit

Permalink
refactor: reduce complexity for dims need values logic
Browse files Browse the repository at this point in the history
Use strings instead of BigInt for efficiency
  • Loading branch information
mgreminger committed Jan 7, 2025
1 parent 87f8bf0 commit 569a0a0
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 24 deletions.
21 changes: 11 additions & 10 deletions public/dimensional_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
ceiling,
sign,
sqrt,
factorial
factorial,
Basic
)

class ExprWithAssumptions(Expr):
Expand Down Expand Up @@ -1529,12 +1530,12 @@ def replace_placeholder_funcs(expr: Expr,
func_key: Literal["dim_func"] | Literal["sympy_func"],
placeholder_map: dict[Function, PlaceholderFunction],
placeholder_set: set[Function],
dim_values_dict: dict[tuple[int,...], list[Expr]],
function_parents: list[int],
dim_values_dict: dict[tuple[Basic,...], list[Expr]],
function_parents: list[Basic],
data_table_subs: DataTableSubs | None) -> Expr:

if (not is_matrix(expr)) and expr.func == function_id_wrapper:
function_parents.append(int(cast(Expr, expr.args[0])))
function_parents.append(expr.args[0])
expr = cast(Expr, expr.args[1])

if is_matrix(expr):
Expand Down Expand Up @@ -1564,13 +1565,13 @@ def replace_placeholder_funcs(expr: Expr,
dim_values_snapshot = list(dim_values)
for i, value in enumerate(dim_values_snapshot):
dim_values_snapshot[i] = cast(Expr, value.subs({key: cast(Matrix, value)[0,0] for key, value in data_table_subs.subs_stack[-1].items()}))
dim_values_dict[(int(cast(Expr, expr.args[0])), *function_parents_snapshot)] = dim_values_snapshot
dim_values_dict[(expr.args[0], *function_parents_snapshot)] = dim_values_snapshot
else:
dim_values_dict[(int(cast(Expr, expr.args[0])), *function_parents_snapshot)] = dim_values
dim_values_dict[(expr.args[0], *function_parents_snapshot)] = dim_values
return cast(Expr, cast(Callable, placeholder_map[cast(Function, child_expr.func)][func_key])(*dim_values))
else:
child_expr = expr.args[1]
dim_values = dim_values_dict[(int(cast(Expr, expr.args[0])),*function_parents)]
dim_values = dim_values_dict[(expr.args[0],*function_parents)]
child_processed_args = [replace_placeholder_funcs(cast(Expr, arg), func_key, placeholder_map, placeholder_set, dim_values_dict, function_parents, data_table_subs) for arg in child_expr.args]
return cast(Expr, cast(Callable, placeholder_map[cast(Function, child_expr.func)][func_key])(dim_values, *child_processed_args))
elif expr.func in dummy_var_placeholder_set and func_key == "dim_func":
Expand Down Expand Up @@ -1630,7 +1631,7 @@ def get_dimensional_analysis_expression(parameter_subs: dict[Symbol, Expr],
expression: Expr,
placeholder_map: dict[Function, PlaceholderFunction],
placeholder_set: set[Function],
dim_values_dict: dict[tuple[int,...], list[Expr]]) -> tuple[Expr | None, Exception | None]:
dim_values_dict: dict[tuple[Basic,...], list[Expr]]) -> tuple[Expr | None, Exception | None]:

expression_with_parameter_subs = cast(Expr, expression.xreplace(parameter_subs))

Expand Down Expand Up @@ -2390,9 +2391,9 @@ def get_evaluated_expression(expression: Expr,
parameter_subs: dict[Symbol, Expr],
simplify_symbolic_expressions: bool,
placeholder_map: dict[Function, PlaceholderFunction],
placeholder_set: set[Function]) -> tuple[ExprWithAssumptions, str | list[list[str]], dict[tuple[int,...],list[Expr]]]:
placeholder_set: set[Function]) -> tuple[ExprWithAssumptions, str | list[list[str]], dict[tuple[Basic,...],list[Expr]]]:
expression = cast(Expr, expression.xreplace(parameter_subs))
dim_values_dict: dict[tuple[int,...],list[Expr]] = {}
dim_values_dict: dict[tuple[Basic,...],list[Expr]] = {}
expression = replace_placeholder_funcs(expression,
"sympy_func",
placeholder_map,
Expand Down
12 changes: 6 additions & 6 deletions src/parser/LatexToSympy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { FieldTypes, Statement, QueryStatement, RangeQueryStatement, UserFu
DataTableInfo, DataTableQueryStatement,
BlankStatement, SubQueryStatement} from "./types";
import { type Insertion, type Replacement, applyEdits,
createSubQuery, cantorPairing } from "./utility";
createSubQuery } from "./utility";

import { RESERVED, GREEK_CHARS, UNASSIGNABLE, COMPARISON_MAP,
UNITS_WITH_OFFSET, TYPE_PARSING_ERRORS, BUILTIN_FUNCTION_MAP,
Expand Down Expand Up @@ -1154,15 +1154,15 @@ export class LatexToSympy extends LatexParserVisitor<string | Statement | UnitBl
return `_Inverse(${base})`;
}

return `_dim_needs_values_wrapper(${cantorPairing(this.equationIndex,this.dimNeedsValuesIndex++)},_Pow(${base},${exponent}))`;
return `_dim_needs_values_wrapper(__unique_marker_${this.equationIndex}_${this.dimNeedsValuesIndex++},_Pow(${base},${exponent}))`;
}

visitIndex = (ctx: IndexContext): string => {
const rowExpression = this.visit(ctx.expr(1)) as string;

const colExpression = this.visit(ctx.expr(2)) as string;

return `_dim_needs_values_wrapper(${cantorPairing(this.equationIndex,this.dimNeedsValuesIndex++)},_IndexMatrix(${this.visit(ctx.expr(0))}, ${rowExpression}, ${colExpression}))`;
return `_dim_needs_values_wrapper(__unique_marker_${this.equationIndex}_${this.dimNeedsValuesIndex++},_IndexMatrix(${this.visit(ctx.expr(0))}, ${rowExpression}, ${colExpression}))`;
}

visitArgument = (ctx: ArgumentContext): (LocalSubstitution | LocalSubstitutionRange)[] => {
Expand Down Expand Up @@ -1354,7 +1354,7 @@ export class LatexToSympy extends LatexParserVisitor<string | Statement | UnitBl
currentFunction = {
type: "assignment",
name: functionName,
sympy: `_function_id_wrapper(${cantorPairing(this.equationIndex,this.functionIndex)},${variableName})`,
sympy: `_function_id_wrapper(__unique_marker_${this.equationIndex}_${this.functionIndex},${variableName})`,
params: [variableName],
isUnitlessSubExpression: false,
isFunctionArgument: false,
Expand All @@ -1371,7 +1371,7 @@ export class LatexToSympy extends LatexParserVisitor<string | Statement | UnitBl
currentFunction = {
type: "assignment",
name: functionName,
sympy: `_function_id_wrapper(${cantorPairing(this.equationIndex,this.functionIndex)},${variableName})`,
sympy: `_function_id_wrapper(__unique_marker_${this.equationIndex}_${this.functionIndex},${variableName})`,
params: [variableName],
isUnitlessSubExpression: false,
isFunctionArgument: false,
Expand All @@ -1392,7 +1392,7 @@ export class LatexToSympy extends LatexParserVisitor<string | Statement | UnitBl
const unitsFunction: UserFunction = {
type: "assignment",
name: currentFunction.unitsQueryFunction,
sympy: `_function_id_wrapper(${cantorPairing(this.equationIndex,this.functionIndex)},${variableName})`,
sympy: `_function_id_wrapper(__unique_marker_${this.equationIndex}_${this.functionIndex},${variableName})`,
params: [variableName],
isUnitlessSubExpression: false,
isFunctionArgument: false,
Expand Down
8 changes: 0 additions & 8 deletions src/parser/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,3 @@ export function createSubQuery(name: string): SubQueryStatement {
};
}

// Implementation of the cantor pairing function https://en.wikipedia.org/wiki/Pairing_function
// Creates a unit mapping from the integer pair (a,b) to an integer
export function cantorPairing(a: number, b: number) {
const A = BigInt(a);
const B = BigInt(b)
const result = (((A+B)*(A+B+BigInt(1))) >> BigInt(1)) + B;
return result.toString();
}

0 comments on commit 569a0a0

Please sign in to comment.