Created
July 7, 2016 06:32
-
-
Save Shekharrajak/ce29e63d591b3ce15c939e3d6a66cc05 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def _solve_using_known_values(result, solver): | |
"""Solves the system using already known solution | |
(result contains the dict <symbol: value>). | |
solver is `solveset_complex` or `solveset_real`. | |
""" | |
# stores imageset <expr: imageset(Lambda(n, expr), base)>. | |
soln_imageset = {} | |
total_solveset_call_inner = 0 | |
total_conditionset_inner = 0 | |
def _extract_main_soln(sol): | |
"""separate the Complements, Intersections, ImageSet lambda expr | |
and it's base_set. | |
""" | |
# if there is union, then need to check | |
# complement, intersection, Imageset | |
# order should not be changed. | |
if isinstance(sol, Complement): | |
# extract solution and complement | |
complements[sym] = sol.args[1] | |
sol = sol.args[0] | |
# complement will be added at the end | |
if isinstance(sol, Intersection): | |
# Interval will be at 0th index always | |
if sol.args[0] != Interval(-oo, oo): | |
# sometimes solveset returns soln | |
# with intersection S.Reals, to confirm that | |
# soln is in domain=S.Reals | |
intersections[sym] = sol.args[0] | |
sol = sol.args[1] | |
# after intersection and complement Imageset should | |
# be checked. | |
if isinstance(sol, ImageSet): | |
soln_imagest = sol | |
sol = sol.lamda.expr | |
soln_imageset[sol] = soln_imagest | |
return sol | |
# end of def _extract_main_soln | |
# sort such that equation with the fewest potential symbols is first. | |
# means eq with less variable first | |
for index, eq in enumerate(eqs_in_better_order): | |
newresult = [] | |
got_symbol = set() # symbols solved in one iteration | |
hit = False | |
original_imageset = {} | |
# if imageset expr is used to solve other symbol | |
imgset_yes = False | |
for res in result: | |
if soln_imageset: | |
# find the imageset and use it's expr. | |
for key_res, value_res in res.items(): | |
if isinstance(value_res, ImageSet): | |
res[key_res] = value_res.lamda.expr | |
original_imageset[key_res] = value_res | |
dummy_n = value_res.lamda.expr.atoms(Dummy).pop() | |
base = value_res.base_set | |
imgset_yes = (dummy_n, base) | |
soln_imageset = {} | |
# update eq with everything that is known so far | |
eq2 = eq.subs(res) | |
unsolved_syms = _unsolved_syms(eq2, sort=True) | |
if not unsolved_syms: | |
if res: | |
newresult.append(res) | |
break # skip as it's independent of desired symbols | |
for sym in unsolved_syms: | |
not_solvable = False | |
try: | |
soln = solver(eq2, sym) | |
total_solveset_call_inner += 1 | |
soln_new = S.EmptySet | |
if isinstance(soln, Complement): | |
# extract solution and complement | |
complements[sym] = soln.args[1] | |
soln = soln.args[0] | |
# complement will be added at the end | |
if isinstance(soln, Intersection): | |
# Interval will be at 0th index always | |
if soln.args[0] != Interval(-oo, oo): | |
# sometimes solveset returns soln | |
# with intersection S.Reals, to confirm that | |
# soln is in domain=S.Reals | |
intersections[sym] = soln.args[0] | |
soln_new += soln.args[1] | |
soln = soln_new if soln_new else soln | |
if index > 0 and solver == solveset_real: | |
# one symbol's real soln , another symbol may have | |
# corresponding complex soln. | |
if not isinstance(soln, ImageSet): | |
soln += solveset_complex(eq2, sym) | |
except NotImplementedError: | |
# If sovleset not able to solver eq2. Next time we may | |
# get soln using next eq2 | |
continue | |
if isinstance(soln, ConditionSet): | |
soln = S.EmptySet | |
# dont do `continue` we may get soln | |
# in terms of other symbol(s) | |
not_solvable = True | |
total_conditionset_inner += 1 | |
if isinstance(soln, Complement): | |
# extract solution and complement | |
complements[sym] = soln.args[1] | |
soln = soln.args[0] | |
# complement will be added at the end | |
if isinstance(soln, ImageSet): | |
soln_imagest = soln | |
expr2 = soln.lamda.expr | |
soln = FiniteSet(expr2) | |
soln_imageset[expr2] = soln_imagest | |
# if there is union of Imageset in soln | |
# no testcase is written for this if block | |
if isinstance(soln, Union): | |
soln_args = soln.args | |
soln = [] | |
# need to use list. | |
# (finiteset union imageset).args is | |
# (finiteset, Imageset). But we want only iteration | |
# so append finteset elements and imageset. | |
for soln_arg2 in soln_args: | |
if isinstance(soln_arg2, FiniteSet): | |
list_finiteset = list( | |
[sol_1 for sol_1 in soln_arg2]) | |
soln += list_finiteset | |
else: | |
# ImageSet or Intersection or complement | |
# append them directly | |
soln.append(soln_arg2) | |
for sol in soln: | |
# helper funciton. used in this loop | |
def _append_new_soln(rnew): | |
"""If rnew (A dict <symbol: soln> ) contains valid soln | |
append it to newresult list. | |
""" | |
# for check_sol using imageset expr if imageset | |
# present. | |
# TODO: put n = 0 in imageset expr | |
if not any(checksol(d, rnew) for d in exclude): | |
# if sol was imageset then add imageset | |
local_n = None | |
if imgset_yes: | |
local_n = imgset_yes[0] | |
base = imgset_yes[1] | |
# use ImageSet, we have dummy in sol | |
dummy_list = list(sol.atoms(Dummy)) | |
# use one dummy `n` which is in | |
# previous imageset | |
local_n_list = [ | |
local_n for i in range( | |
0, len(dummy_list))] | |
dummy_zip = zip(dummy_list, local_n_list) | |
lam = Lambda(local_n, sol.subs(dummy_zip)) | |
rnew[sym] = ImageSet(lam, base) | |
elif soln_imageset: | |
rnew[sym] = soln_imageset[sol] | |
# restore original imageset | |
restore_sym = set(rnew.keys()) & \ | |
set(original_imageset.keys()) | |
for key_sym in restore_sym: | |
img = original_imageset[key_sym] | |
rnew[key_sym] = img | |
newresult.append(rnew) | |
# end of def _append_new_soln | |
sol = _extract_main_soln(sol) | |
free = sol.free_symbols | |
if got_symbol and any([ | |
ss in free for ss in got_symbol | |
]): | |
# sol depends on previously solved symbols | |
# then continue | |
continue | |
rnew = res.copy() | |
# put each solution in res and append the new result | |
# in the new result list (solution for symbol `s`) | |
# along with old results. | |
for k, v in res.items(): | |
if isinstance(v, Expr): | |
# if any unsolved symbol is present | |
# Then subs known value | |
rnew[k] = v.subs(sym, sol) | |
# and add this new solution | |
rnew[sym] = sol | |
_append_new_soln(rnew) | |
hit = True | |
# solution got for sym | |
if not not_solvable: | |
got_symbol.add(sym) | |
if not hit: | |
return _return_conditionset() | |
else: | |
result = newresult | |
return result, total_solveset_call_inner, total_conditionset_inner | |
# end def _solve_using_know_values |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment