Examples¶
These snippets are intentionally small. They show the common shape of a
sycan workflow: build or parse a circuit, run one solver, then simplify
or substitute values with sycan.cas.
DC divider with numeric substitution¶
Use sycan.solve_dc() when all independent sources should use their
DC value.
from sycan import cas as cas
from sycan import parse, solve_dc
c = parse("""voltage divider
V1 in 0 Vin
R1 in out R1
R2 out 0 R2
.end
""")
Vin, R1, R2 = cas.symbols("Vin R1 R2")
sol = solve_dc(c)
gain = cas.simplify(sol[cas.Symbol("V(out)")] / Vin)
print(gain) # R2/(R1 + R2)
print(gain.subs({R1: 9000, R2: 1000})) # 1/10
Second-order low-pass transfer¶
Use an AC source value to drive small-signal analysis in the
Laplace domain.
from sycan import cas as cas
from sycan import parse, solve_ac
c = parse("""series RLC low-pass
V1 in 0 AC Vin
L1 in mid L
R1 mid out R
C1 out 0 C
.end
""")
sol = solve_ac(c)
H = cas.factor(sol[cas.Symbol("V(out)")] / cas.Symbol("Vin"))
print(H) # 1/(C*L*s**2 + C*R*s + 1)
Input impedance of a loaded node¶
Mark the node with a sycan.Port, then ask
sycan.solve_impedance() for that named port.
from sycan import cas as cas
from sycan import Circuit, solve_impedance
s, R, C = cas.symbols("s R C")
c = Circuit("cap load")
c.add_port("P_in", "in", "0", "input")
c.add_resistor("R1", "in", "out", R)
c.add_capacitor("C1", "out", "0", C)
Z_in = cas.simplify(solve_impedance(c, "P_in", s=s))
print(Z_in) # R + 1/(C*s)
Render a quick schematic¶
sycan.autodraw() accepts the same SPICE-style netlist strings as
sycan.parse() and returns the SVG as a string.
from sycan import autodraw
svg = autodraw("""divider
V1 in 0 Vin
R1 in out R1
R2 out 0 R2
.end
""", filename="divider.svg")
print(svg.startswith("<svg")) # True