Python中SymPy求解含if-else的方程报错:无法确定Relational真值
解决SymPy中
TypeError: cannot determine truth value of Relational错误 你遇到的这个错误是SymPy符号计算里的典型问题——当你用普通Python的if-else去判断一个符号表达式的真假时,SymPy没办法直接给出确定的布尔值,就会抛出这个异常。
看你的代码,c是用Symbol('c')定义的符号变量,所以es = ec*(c-d1)/c计算后得到的是一个符号表达式,不是具体的数值。当代码走到if es>=ey:这一步时,Python要求这个比较返回True或False,但SymPy的符号关系表达式(Relational)没办法直接确定真假,自然就报错了。
解决思路:用SymPy的Piecewise替换普通if-else
要处理符号表达式的分段逻辑,得用SymPy专门提供的Piecewise函数,它能生成符号化的分段函数,让SymPy的求解器可以正常处理。下面是修改后的完整代码,重点替换了所有依赖符号变量的条件判断:
from sympy import * import math b=400*0.0393701;h=600*0.0393701;d=530*0.0393701; d1=70*0.0393701;fc=24*145.0377439;fy=400*145.0377439;Es = 29000000 # Stage1 Ag=b*h;As=math.pi*((32*0.0393701)**2)/4 ey=fy/Es peta=0.85 e=[0,200,400,600] def init(ec,f1, c): es = ec*(c-d1)/c # 用Piecewise替换原if-else,生成符号分段函数 t = Piecewise( (3*As*f1/1000, es >= ey), (3*es*Es/1000, True) # True表示默认分支 ) cc=0.85*fc*peta*c*b/1000 es1=ec*(d-c)/c cs = Piecewise( (3*As*(f1-0.85*fc)/1000, es1 >= ey), (3*As*(Es*es1-0.85*fc)/1000, True) ) res = [cc, cs, t] return res def com(ec, c,k): if k==1: # Hognestad模型:用Piecewise处理分段逻辑 e0=2*0.9*fc/(57000*(fc**(0.5))) #0.00186 fc_1 = Piecewise( (0.9*fc*((2*ec/e0) - ((ec/e0)**2)), ec <= e0), (0.9*fc*(1-0.15*((ec-e0)/(0.0038-e0))), True) ) re = init(ec, fc_1, c) elif k==2: # Collins and Mitchell模型 k3=0.6+10/24; Ec_rev = 4730*(24**(0.5)); n =0.8 + 24/17 ec_rev = (24/Ec_rev)*(n/(n-1)) k_rev = Piecewise( (1, ec/ec_rev <=1), (0.67+24/62, True) ) fc_2=k3*fc*(ec/ec_rev)*(n/(n-1+((ec/ec_rev)**(n*k_rev)))) re = init(ec, fc_2, c) return re ec_real=[]; for i in range(0,39): ec_real.append(i/10000) c= Symbol('c') peta = 0.85 a=peta*c ### Final Solution M=[] F=[] final1={} for k_final in [1, 2]: for x1 in e: for x2 in ec_real: # 构建符号方程表达式 expr = com(x2, c, k_final)[0] * (h / 2 - a / 2) + com(x2, c, k_final)[1] * (h / 2 - d1) + com(x2, c, k_final)[2] * (d - h / 2) # 求解方程并过滤有效解(排除负数、复数) solutions = solve(expr, c) valid_solutions = [sol for sol in solutions if sol.is_real and sol > 0] if valid_solutions: c_final = valid_solutions[0] # 取第一个有效解,可根据需求调整 Pn = com(x2, c_final, k_final)[0] + com(x2, c_final, k_final)[1] - com(x2, c_final, k_final)[2] Mn = Pn * x1 fai = x2 / c_final M.append(Mn); F.append(fai) ss = {str(x1):{"M": M, "Fai": F}} final1[str(k_final)]=ss print(final1)
额外优化说明
- 有效解过滤:
solve可能返回多个解(包括负数、复数),这些在工程场景中没有意义,所以加了一步筛选正实数解的逻辑。 - 逻辑修复:把
com函数里的if k==2改成elif k==2,避免出现重复赋值的逻辑漏洞。 - 代码简化:最后构建字典时合并了重复的赋值语句,让代码更简洁。
内容的提问来源于stack exchange,提问作者bricker
相关产品推荐
相关产品推荐

