# Why solve function can't solve system which can be solved manually

This returns an empty list:

reset()
var('i_B10 i_B6 i_B11 i_C10 i_C6 i_C11 beta i_in i_out i_E10 i_E6 i_E11')
solve([
i_C10 == i_B10 * beta,
i_E10 == i_C10 + i_B10,

i_C6 == i_B6 * beta,
i_E6 == i_B6 + i_C6,

i_C11 == i_B11 * beta,
i_E11 == i_B11 + i_C11,

i_E10 == i_B11 + i_E6,

i_E11 + i_E6 == i_in + i_out,

i_B11 == i_B6,
i_in == i_B10 + i_C11,
i_out == i_C10

], i_out)


Output:

[]


But it can be solved manually

reset()
var('i_B10 i_B6 i_B11 i_C10 i_C6 i_C11 beta i_in i_out i_E10 i_E6 i_E11')

i_C10 = i_B10 * beta
i_E10 = i_C10 + i_B10
i_C6 = i_B6 * beta
i_E6 = i_B6 + i_C6
i_C11 = i_B11 * beta
i_E11 = i_B11 + i_C11
i_B10 = (i_E10 == i_B11 + i_E6).solve(i_B10)[0].right()
i_B10 = i_B10(i_B11=i_B6)
i_C10 = i_C10(i_B10=i_B10)
i_B6 = solve(i_in == i_B10 + i_C11(i_B11=i_B6), i_B6)[0].right()
i_out = i_C10(i_B6=i_B6)

i_out = i_out.simplify_rational()
i_out


Output:

(beta^2 + 2*beta)*i_in/(beta^2 + 2*beta + 2)


Why solve doesn't work? Do I need to set some assumptions or etc? Or is because i_out depends only on one variable? How to make "solve" function work in this case?

edit retag close merge delete

Sort by ยป oldest newest most voted

This system of equations is based on electronic circuit. Seems 'solve' works fine if asked to find all unknown values: ('beta' and 'i_in' is excluded as they are known)

reset()
var('i_B10 i_B6 i_B11 i_C10 i_C6 i_C11 beta i_in i_out i_E10 i_E6 i_E11')
i=solve([
i_C10 == i_B10 * beta,
i_E10 == i_C10 + i_B10,

i_C6 == i_B6 * beta,
i_E6 == i_B6 + i_C6,

i_C11 == i_B11 * beta,
i_E11 == i_B11 + i_C11,

i_E10 == i_B11 + i_E6,

i_E11 + i_E6 == i_in + i_out,

i_B11 == i_B6,
i_in == i_B10 + i_C11,
i_out == i_C10

], [i_B10, i_B6, i_B11, i_C10, i_C6, i_C11, i_out, i_E10, i_E6, i_E11])

i[0][6].simplify_rational()


output

i_out == (beta^2 + 2*beta)*i_in/(beta^2 + 2*beta + 2)

more

Your program rebinds the Python variables initially bound to the objects representing your mathematical variables. Therefore, it does not solve the *same *system of equations.

This can be illustrated by tracing the state of your variables. Your initial setup, with a slight modification :

reset()
# Collect variable names
Vars = var('i_B10 i_B6 i_B11 i_C10 i_C6 i_C11 beta i_in i_out i_E10 i_E6 i_E11')
# Collect equations
Sys = [i_C10 == i_B10 * beta,
i_E10 == i_C10 + i_B10,
i_C6 == i_B6 * beta,
i_E6 == i_B6 + i_C6,
i_C11 == i_B11 * beta,
i_E11 == i_B11 + i_C11,
i_E10 == i_B11 + i_E6,
i_E11 + i_E6 == i_in + i_out,
i_B11 == i_B6,
i_in == i_B10 + i_C11,
i_out == i_C10]
# *Text* of the program
Txt="""i_C10 = i_B10 * beta
i_E10 = i_C10 + i_B10
i_C6 = i_B6 * beta
i_E6 = i_B6 + i_C6
i_C11 = i_B11 * beta
i_E11 = i_B11 + i_C11
i_B10 = (i_E10 == i_B11 + i_E6).solve(i_B10)[0].right()
i_B10 = i_B10(i_B11=i_B6)
i_C10 = i_C10(i_B10=i_B10)
i_B6 = solve(i_in == i_B10 + i_C11(i_B11=i_B6), i_B6)[0].right()
i_out = i_C10(i_B6=i_B6)"""


We create a copy by renaming variables (and modify program text accordingly).

# New (= renamed) variables
uVars = var([repr(u).replace("i_","u_") for u in Vars])
# use them in program text (and split it in lines)
uTxt = Txt.replace("i_","u_").split("\n")


Now, we can execute the program step by step, and trace identifier's values after each step :

State = []
for t in uTxt:
exec(t)
State.append([eval(repr(u)) for u in uVars])
# Effective history of identifiers :
view(table(State, header_row=uVars, header_column=["After"]+[u.replace("_","\\_") for u in uTxt]))


The result cannot currently be displayed in this site, whose typesetting is questionable, but is visible in Sagecell.

HTH,

EDIT : avi9526's answer to his own question, which is correct, can be clarified as :

reset()
Vars = var('i_B10 i_B6 i_B11 i_C10 i_C6 i_C11 beta i_in i_out i_E10 i_E6 i_E11')
Sys = [
i_C10 == i_B10 * beta,
i_E10 == i_C10 + i_B10,
i_C6 == i_B6 * beta,
i_E6 == i_B6 + i_C6,
i_C11 == i_B11 * beta,
i_E11 == i_B11 + i_C11,
i_E10 == i_B11 + i_E6,
i_E11 + i_E6 == i_in + i_out,
i_B11 == i_B6,
i_in == i_B10 + i_C11,
i_out == i_C10
]
Unk = [i_B10, i_B6, i_B11, i_C10, i_C6, i_C11, i_out, i_E10, i_E6, i_E11]
Sol =solve(Sys,Unk)


This solution is unique :

sage: len(Sol)
1


ad can be displayed as :

sage: print("\n".join(map(repr,Sol[0])))
i_B10 == (beta*i_in + 2*i_in)/(beta^2 + 2*beta + 2)
i_B6 == (beta*i_in + i_in)/(beta^2 + 2*beta + 2)
i_B11 == (beta*i_in + i_in)/(beta^2 + 2*beta + 2)
i_C10 == (beta^2*i_in + 2*beta*i_in)/(beta^2 + 2*beta + 2)
i_C6 == (beta^2*i_in + beta*i_in)/(beta^2 + 2*beta + 2)
i_C11 == (beta^2*i_in + beta*i_in)/(beta^2 + 2*beta + 2)
i_out == (beta^2*i_in + 2*beta*i_in)/(beta^2 + 2*beta + 2)
i_E10 == (beta^2*i_in + 3*beta*i_in + 2*i_in)/(beta^2 + 2*beta + 2)
i_E6 == (beta^2*i_in + 2*beta*i_in + i_in)/(beta^2 + 2*beta + 2)
i_E11 == (beta^2*i_in + 2*beta*i_in + i_in)/(beta^2 + 2*beta + 2)


HTH,

more

I'm sorry, but I'm a bit confused by what you're saying. I manually derived that formula, and it appears to be the correct solution for calculating i_out. Please see my answer. Your approach of presenting all the steps in the form of a table is quite elegant - thank you for sharing it.

( 2023-08-21 04:07:01 +0200 )edit

Your first attempt was a series of statements, assigning values to variables (through the = operator). Doing so introduced inconsistencies...

This version creates a list of equations (whose operator is ==, a. k. a.eq) , then solves it; See my edit to my anser.

I suggest perusing this excellent book.

( 2023-08-21 07:58:03 +0200 )edit