Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
trs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
trs
Commits
71bb5823
Commit
71bb5823
authored
May 02, 2012
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented substitution for solving sets of linear equations..
parent
ce4874ef
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
78 additions
and
11 deletions
+78
-11
src/parser.py
src/parser.py
+3
-2
src/rules/__init__.py
src/rules/__init__.py
+4
-2
src/rules/lineq.py
src/rules/lineq.py
+48
-2
src/rules/precedences.py
src/rules/precedences.py
+8
-4
tests/test_rules_lineq.py
tests/test_rules_lineq.py
+15
-1
No files found.
src/parser.py
View file @
71bb5823
...
...
@@ -294,8 +294,9 @@ class Parser(BisonParser):
while self.possibilities:
# Find the first implicit possibliity in the list
# FIXME: Is it smart to apply a rule that is not a hint?
# ANSWER: Yes, but there must be an extra list that prevents
# deliberately generated implicit rules from being applied
# ANSWER: Yes, but there must be something like an extra list
# that prevents deliberately generated implicit rules from
# being applied
#sugg = self.possibilities[0]
#if sugg.handler not in IMPLICIT_RULES:
...
...
src/rules/__init__.py
View file @
71bb5823
from
..node
import
OP_ADD
,
OP_MUL
,
OP_DIV
,
OP_POW
,
OP_NEG
,
OP_SIN
,
OP_COS
,
\
OP_TAN
,
OP_DER
,
OP_LOG
,
OP_INT
,
OP_INT_INDEF
,
OP_EQ
,
OP_ABS
,
OP_SQRT
OP_TAN
,
OP_DER
,
OP_LOG
,
OP_INT
,
OP_INT_INDEF
,
OP_EQ
,
OP_ABS
,
OP_SQRT
,
\
OP_AND
from
.groups
import
match_combine_groups
from
.factors
import
match_expand
from
.powers
import
match_add_exponents
,
match_subtract_exponents
,
\
...
...
@@ -27,7 +28,7 @@ from .integrals import match_solve_indef, match_constant_integral, \
match_integrate_variable_power
,
match_factor_out_constant
,
\
match_division_integral
,
match_function_integral
,
\
match_sum_rule_integral
,
match_remove_indef_constant
from
.lineq
import
match_move_term
from
.lineq
import
match_move_term
,
match_multiple_equations
from
.absolute
import
match_factor_out_abs_term
from
.sqrt
import
match_reduce_sqrt
...
...
@@ -67,4 +68,5 @@ RULES = {
OP_EQ
:
[
match_move_term
],
OP_ABS
:
[
match_factor_out_abs_term
],
OP_SQRT
:
[
match_reduce_sqrt
],
OP_AND
:
[
match_multiple_equations
],
}
src/rules/lineq.py
View file @
71bb5823
from
.utils
import
find_variable
,
evals_to_numeric
from
itertools
import
permutations
from
.utils
import
find_variable
,
evals_to_numeric
,
substitute
from
..node
import
ExpressionLeaf
as
L
,
Scope
,
OP_EQ
,
OP_ADD
,
OP_MUL
,
OP_DIV
,
\
eq
,
OP_ABS
eq
,
OP_ABS
,
OP_AND
from
..possibilities
import
Possibility
as
P
,
MESSAGES
from
..translate
import
_
...
...
@@ -148,3 +150,47 @@ def split_absolute_equation(root, args):
MESSAGES
[
split_absolute_equation
]
=
_
(
'Split absolute equation {0} into a '
\
'negative and a positive equation.'
)
def
match_multiple_equations
(
node
):
"""
Multiple equations can be solved using substitution and/or elimination.
Substitution rule:
x = a ^^ f(x) = g(x) -> x = a ^^ f(a) = g(a) # Substitute x with a
Substitution example:
x = ay + b ^^ cx + dy = e -> x = ay + b ^^ c(ay + b) + dy = e
# =>* x = eval(a * eval((e - bc) / (ca + b)) + b)
# ^^ y = eval((e - bc) / (ca + b))
"""
assert
node
.
is_op
(
OP_AND
)
scope
=
Scope
(
node
)
equations
=
filter
(
lambda
exp
:
exp
.
is_op
(
OP_EQ
),
scope
)
p
=
[]
if
len
(
equations
)
<
2
:
return
p
for
eq0
,
eq1
in
permutations
(
equations
,
2
):
x
,
subs
=
eq0
# Substitution rule
if
x
.
is_variable
()
and
eq1
.
contains
(
x
):
p
.
append
(
P
(
node
,
substitute_variable
,
(
scope
,
x
,
subs
,
eq1
)))
return
p
def
substitute_variable
(
root
,
args
):
"""
Substitution rule:
x = a ^^ f(x) = g(x) -> x = a ^^ f(a) = g(a) # Substitute x with a
"""
scope
,
x
,
subs
,
eq
=
args
scope
.
replace
(
eq
,
substitute
(
eq
,
x
,
subs
))
return
scope
.
as_nary_node
()
MESSAGES
[
substitute_variable
]
=
_
(
'Substitute {2} with {3} in {4}.'
)
src/rules/precedences.py
View file @
71bb5823
...
...
@@ -12,6 +12,7 @@ from .fractions import multiply_with_fraction, extract_fraction_terms, \
from
.integrals
import
factor_out_constant
,
integrate_variable_root
from
.powers
import
remove_power_of_one
from
.sqrt
import
quadrant_sqrt
,
extract_sqrt_mult_priority
from
.lineq
import
substitute_variable
,
swap_sides
# Functions to move to the beginning of the possibilities list. Pairs of within
...
...
@@ -39,7 +40,7 @@ LOW = [
# higher priority than B. This list ignores occurences in the HIGH or LOW lists
# above
RELATIVE
=
[
# Precedences needed for 'power rule'
# Precedences needed for 'power rule'
(derivative of an exponentiation)
(
chain_rule
,
raised_base
),
(
raised_base
,
factor_out_exponent
),
...
...
@@ -58,11 +59,15 @@ RELATIVE = [
# root first
(
extract_sqrt_mult_priority
,
multiply_numerics
),
# sqrt(2 ^ 2) -> 2 #
not sqrt 4
# sqrt(2 ^ 2) -> 2 #
rather than sqrt(4)
(
quadrant_sqrt
,
raise_numerics
),
#
# Prevent cycles that are caused by multiplication reductions when
# splitting up fractions
(
extract_fraction_terms
,
multiply_numerics
),
# Prevent useless swapping when solving multiple equations
(
substitute_variable
,
swap_sides
),
]
...
...
@@ -84,6 +89,5 @@ IMPLICIT_RULES = [
remove_zero
,
remove_power_of_one
,
negated_factor
,
multiply_numerics
,
add_numerics
,
]
tests/test_rules_lineq.py
View file @
71bb5823
from
src.rules.lineq
import
match_move_term
,
swap_sides
,
subtract_term
,
\
divide_term
,
multiply_term
,
split_absolute_equation
divide_term
,
multiply_term
,
split_absolute_equation
,
\
match_multiple_equations
,
substitute_variable
from
src.node
import
Scope
from
src.possibilities
import
Possibility
as
P
from
tests.rulestestcase
import
RulesTestCase
,
tree
...
...
@@ -107,3 +109,15 @@ class TestRulesLineq(RulesTestCase):
'x = -a * 1'
,
'x = -a'
,
])
def
test_match_multiple_equations
(
self
):
eq0
,
eq1
=
root
=
tree
(
'x = 2 ^^ ay + x = 3'
)
x
=
eq0
[
0
]
self
.
assertEqualPos
(
match_multiple_equations
(
root
),
[
P
(
root
,
substitute_variable
,
(
Scope
(
root
),
x
,
2
,
eq1
))])
def
test_substitute_variable
(
self
):
root
,
expect
=
tree
(
'x = 2 ^^ ay + x = 3, x = 2 ^^ ay + 2 = 3'
)
(
x
,
l2
),
eq
=
root
self
.
assertEqual
(
substitute_variable
(
root
,
((
Scope
(
root
),
x
,
l2
,
eq
))),
expect
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment