Created
July 7, 2016 06:28
-
-
Save Shekharrajak/8925cb5c79d548d9e0e80014baffd7ca 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`. | |
""" | |
# helper functions | |
def _append_new_soln(sol, rnew, newresult, imgset_info): | |
"""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_info: | |
local_n = imgset_info[0] | |
base = imgset_info[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) | |
return newresult | |
# end of def _append_new_soln | |
def _do_solveset(eq2, unsolved_syms, newresult, imgset_info): | |
soln_imageset = {} | |
for sym in unsolved_syms: | |
not_solvable = False | |
solveset_call = 0 | |
conditionset_got = 0 | |
try: | |
soln = solver(eq2, sym) | |
solveset_call += 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: | |
return S.EmptySet, solveset_call, conditionset_got | |
if isinstance(soln, ConditionSet): | |
soln = S.EmptySet | |
# dont do `continue` we may get soln | |
# in terms of other symbol(s) | |
not_solvable = True | |
conditionset_got += 1 | |
soln, soln_imageset = _extract_main_soln(soln, soln_imageset) | |
# remove this | |
# 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 | |
# end remove | |
for sol in soln: | |
newresult = _add_valid_soln( | |
sol, newresult, soln_imageset, imgset_info) | |
# solution got for sym | |
if not not_solvable: | |
got_symbol.add(sym) | |
return soln, soln_imageset, | |
newresult, solveset_call, conditionset_got | |
# end of def _do_solveset() | |
def _add_valid_soln(sol, newresult, soln_imageset, imgset_info): | |
sol, soln_imageset = _extract_main_soln( | |
sol, soln_imageset) | |
# sol will be in FiniteSet | |
sol = list(sol)[0] | |
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 | |
return | |
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 | |
newresult = _append_new_soln(sol, rnew, newresult, imgset_info) | |
return newresult | |
def _new_soln_using_eq(eq, index, result, soln_imageset): | |
solveset_call = 0 | |
conditionset_got = 0 | |
newresult = [] | |
# if imageset expr is used to solve other symbol | |
imgset_info = () | |
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_info = (dummy_n, base) | |
# 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 | |
(soln, soln_imageset, newresult, solvest_call, | |
conditionst_got) = _do_solveset( | |
eq2, unsolved_syms, newresult, imgset_info) | |
solveset_call += solvest_call | |
conditionset_got += conditionst_got | |
result = newresult | |
return result, solveset_call, conditionset_got | |
# end of def _new_soln_using_eq() | |
# main code of def _solve_using_known_values() | |
# stores imageset <expr: imageset(Lambda(n, expr), base)>. | |
soln_imageset = {} | |
total_solveset_call_inner = 0 | |
total_conditionset_inner = 0 | |
# 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): | |
got_symbol = set() # symbols solved in one iteration | |
original_imageset = {} | |
result, solvset_call, conditionset_got = \ | |
_new_soln_using_eq(eq, index, result, soln_imageset) | |
total_solveset_call_inner += solvset_call | |
total_conditionset_inner += conditionset_got | |
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