[ I N P U T S ]
Describe a circuit and select analysis type — You can use an Input File.
Input File (optional)
About input file (.cir) formatAbout the .cir format
A plain text input file holds as many entries as you like. An
entry is one set of inputs to be solved together: a circuit, the
analysis to run on it, and the settings to run it with. Each starts
with its name in square brackets, followed by the element lines and
then its settings. The file extension is .cir.
A file may also name itself, with a title: line above the
first entry — title: Circuits for Lesson 1 of the Tutorial.
That title is what the interface shows in place of the filename, and
it is what the supplied examples are listed by. A file without one is
shown by its filename instead.
# comments start with a hash title: A couple of problems [Problem 1 — divider] e1,1,0,20 r1,1,2,5'k r2,2,0,15'k analysis: dc rounding: exact si: no units: yes [Problem 2 — RC transient] e1,1,0,10/s r1,1,2,2200 c1,2,0,4.7e-6 analysis: tr variables: v_2 rounding: exact si: no units: yes
Everything after the element lines is optional, and can be left out
entirely — leaving a key out just means the app's own default
applies, same as if you'd never touched it:
analysis (dc/ac/fd/tr), omega,
variables, tool (th/er/port) with
n1/n2/kind and
with_load (yes/no, the load question),
note (text of your own, shown when the entry is
loaded — repeat the line for a second paragraph),
image (a link to a picture of the circuit,
shown above the description when the entry is loaded — a web address,
or a path relative to this page; a picture on your own computer
cannot be linked to, because the browser will not read your files
for a web page, and you may cap how wide it is drawn by writing
[400px] after the link), and (if the circuit uses it)
the expert-mode
equations, conditions and
unknowns; the Settings
rounding (exact/approx/a number of significant
digits/exact+n for both at once), si,
units, rms and
show_equations (each yes/no); and, if you were using
them when you saved,
evaluate with its own
evaluate_conditions, the standalone equation solver's
solve_equations / solve_conditions /
solve_unknowns / solve_real_only, and the
plot tool's plottool (sweep/bode/bode_tf/plot_time) /
plotkey / plotx (the variable on the
x-axis) / plotmin /
plotmax / plotpoints.
For the two-port tool, a port whose lower terminal is not ground is written as a pair, [top,bottom], in its node field (and in n1/n2 here); a side of the circuit that has no path to node 0 is measured against a reference of its own, and the answers say which.
When the app writes a file it puts the keys in the order shown above — element lines, then the analysis type and Expert Mode, then Settings, then Evaluate, Solve equations and Plot. Nothing that reads a file back in cares about that order, so a hand-written file can put them wherever is convenient.
Two links below the circuit box put the inputs you have on screen into the open file, and only one of them shows at a time: Save inputs to new entry adds them as a new entry, and Update inputs in this entry overwrites the entry you are already working in.
Upload, at the top of this card, reads a file like the one above: its entries become the input file open in your browser, replacing whatever was open before. The file is only read, never stored. Download, beside it, writes the open file back out, and is available whenever that file has at least one entry in it.
Circuit Description
Circuit syntax referenceCircuit syntax
One element per line (or separated by :), fields
separated by ,; node 0 is ground. See
the documentation for a full walkthrough, or pick
an example circuit above to see it in practice.
The first letter of an element's name selects its type. Element
letters, element names and node names are not
case-sensitive: R1 and r1 are the same
resistor, and node A is node a.
| Letter | Element | Fields |
|---|---|---|
| j | current source | name,n1,n2,value |
| e | voltage source | name,n+,n−,value |
| r | resistor | name,n1,n2,value |
| s | short circuit | name,n1,n2 |
| c | capacitor | name,n1,n2,value[,initial voltage] |
| l | inductor | name,n1,n2,value[,initial current] |
| m | mutual inductance | name,L1,L2,M |
| t | ideal transformer | name,n1,n2,N1,N2 name,n1,n2,[N1,N2] name,[tl,bl],[tr,br],[N1,N2] |
| o | ideal op-amp | name,n+,n−,n_out |
| z | z-parameters (impedance) two-port block | name,n1,n2 name,n1,n2,[p11,p12,p21,p22] name,[tl,bl],[tr,br] name,[tl,bl],[tr,br],[p11,p12,p21,p22] |
| y | y-parameters (admittance) two-port block | name,n1,n2 name,[tl,bl],[tr,br] |
| h | h-parameters (hybrid) two-port block | name,n1,n2 name,[tl,bl],[tr,br] |
| g | g-parameters (inverse hybrid) two-port block | name,n1,n2 name,[tl,bl],[tr,br] |
| a | a-parameters (ABCD / transmission) two-port block | name,n1,n2 name,[tl,bl],[tr,br] |
| b | b-parameters (inverse transmission) two-port block | name,n1,n2 name,[tl,bl],[tr,br] |
A value can be a number, a symbol (rload,
vin) or an expression — and an expression referring
to another answer, like 2*v2, makes a dependent
(controlled) source.
TR reads a source value as a function of time:
12 is a 12 V step, u(t) the unit step,
t a ramp, δ(t) an impulse. The Greek
letter is hard to type, so delta(t) is read exactly
the same as δ(t).
FD reads it in the s-domain instead:
5/s is a 5 V step and 5 an impulse. To
write an FD source in time, wrap it —
{5}, {u(t)} — which is shorthand for
t2s(…) and works in FD only.
Write the apostrophe — 1'k — to say plainly that you
mean an SI prefix. A bare 1k also works, but it is
ambiguous (one kilo, or one times a variable named k?) and
Symbulator will stop and ask.
| Prefix | Means | Example |
|---|---|---|
| 'P | peta, ×1015 | 2'P |
| 'T | tera, ×1012 | 2'T |
| 'G | giga, ×109 | 2'G |
| 'M | mega, ×106 | 4.7'M |
| 'k or 'K | kilo, ×103 | 1'k |
| 'm | milli, ×10−3 | 5'm |
| 'u or 'µ | micro, ×10−6 | 4.7'u |
| 'n | nano, ×10−9 | 10'n |
| 'p | pico, ×10−12 | 33'p |
| 'f | femto, ×10−15 | 100'f |
| 'a | atto, ×10−18 | 5'a |
Case matters here. 'M is mega and
'm is milli — a factor of a billion apart. (Both
'k and 'K mean kilo.) Micro accepts
either u or µ, so a value pasted from a
datasheet works as typed. There is no prefix for exa: a bare
E glued directly to digits, like 8E3, is
read as scientific notation instead — see below for when
E/e mean that versus an ordinary
variable.
8000, 8000. and 8E3 all mean
the same number; the last two are read as approximate rather than
exact.
E/e only mean scientific notation when
glued directly onto digits with no space or operator in between —
1E3 and 1e3 both mean 1000. Written on
their own (E, e), or separated from a
number by *, they are ordinary variables like any
other: 1*E3 and 1*e3 mean "1 times the
variable named E3 / e3", not "1 times
E times 3".
When conducting an AC analysis, or an analysis in the AC mode,
i, I, j and J
all mean the imaginary unit and cannot be used as
variable names — write 3j, 3*j or
3*i and you get the same thing, shown as
3j. Outside AC, those four letters are ordinary
variable names like any other. pi is π. Every other
name you write is an ordinary variable, so Q,
S and beta mean what you intend rather
than something out of SymPy. Euler's number is exp(1).
In FD analysis s is the complex frequency and in TR
t is time; elsewhere both are ordinary variables.
In Evaluate and Solve you can refer to any answer
with or without its underscore, in any capitalisation — so
i_r1, ir1, i_R1 and
IR1 all mean the current through r1.
Answers are named v_<node> for node voltages and,
per element, i_ current, v_ voltage drop,
p_ power, s_ complex power,
z_/r_ impedance seen by a source.
Define (optional)
One per line,
name = expression. Each name is replaced wherever it
appears, in the circuit and in every other box. E.g.
vx = va-vb, then use vx as a dependent
source's value.
Schematic —
Analysis & Settings
Settings
x·vin/(r1 + x) is left as it is. A prefixed value is a
decimal, so SI prefixes and exact can't both apply.
Expert Mode
Provide additional equations, unknowns and/or conditions to be considered.
[ O U T P U T S ]
Equations
Results
Loading the equivalent circuit will overwrite the Circuit Description, Define and Expert Mode fields, and switch the analysis to Solve circuit. If the current circuit is not saved yet, cancel and save it first.
Evaluate
Useful SymPy functions
An answer arrives arranged the way the solver happened to leave it,
which is not always the way you want to read it. These rearrange it
without changing what it is. Wrap the answer's name in one:
expand(vo) rather than plain vo.
| Function | What it does |
|---|---|
simplify(vo) |
A general tidy-up. Tries several routes and keeps whichever comes out shortest, so it is the one to reach for first and the least predictable. |
expand(vo) |
Multiplies out.
r1*(r2 + r3) → r1*r2 + r1*r3 |
re(se), im(se) |
The real and imaginary parts of a complex answer: for a
complex power, the real and the reactive power.
abs(se) is its magnitude and conj(se)
its conjugate. |
factor(vo) |
The reverse.
r1*r2 + r1*r3 → r1*(r2 + r3) |
collect(vo, v1) |
Gathers the terms in one symbol — the second argument
says which, and it is not optional.
r1*v1 + r2*v1 + r3*v2 →
r3*v2 + v1*(r1 + r2) |
together(vo) |
Pulls a sum of fractions over one denominator.
v1/r1 + v2/r2 →
(r1*v2 + r2*v1)/(r1*r2) |
apart(v3) |
Partial fractions — the step before an inverse Laplace
transform. It wants a single variable, so it suits an FD or TR
answer in s rather than a DC one written in
several resistors.
2/(s**2 + 3*s + 2) →
2/(s + 1) - 2/(s + 2) |
powsimp, radsimp, trigsimp,
logcombine, cancel and diff
are accepted too. They are narrower: diff(vo, v1)
differentiates, and the rest gather powers, radicals, trig terms or
logs, which a circuit answer rarely has enough of to notice.
Solve
About ‘real solutions’
off searches the complex plane too (the calculator's cSolve);
on keeps the unknowns real (its solve)
Export Output
Export to .txt file
Select the information you want to export and download as a text file.
Export to SymPy
Or take the answers somewhere they can be worked on further: Export to SymPy writes them out as a small Python script, so every answer arrives as a SymPy expression you can expand, factor, substitute into or plot. Paste it into a Python prompt, a Jupyter notebook, or any online SymPy console.
[ T O O L S ]
Mini-Tools
Plotting ToolsPlotting
By-Hand Equations
The same circuit, written out the way it is taught in class — and then checked against the answers above.
What this is for
Symbulator does not solve a circuit the way a student does. It stamps every element into one system and hands the whole thing to SymPy, so it never picks a mesh or draws a supernode. That is why its equations look unfamiliar next to the ones in your notebook.
These are the ones from your notebook. They use the same names
for the same quantities — v2 is still node 2's
voltage, ir3 is still the current through
r3 — so the two systems can be read side by side.
Mesh analysis adds its own unknowns, I1,
I2, I3, and shows you how each branch
current is made of them.
Every run is compared with the classic solve. If the two ever disagree, the classic answers are the ones to trust.
Numerical Solver
Explore the equations generated for your circuit with a handy numerical solver.
What you can do with itWhat it does
The solver opens in a new tab, preloaded with this solve’s equations and results. From there:
- Untick an equation, flip a Known to Unknown, and watch the results follow.
- A transient (TR) solve hands over its
answers as functions of time, with
tas a Known you can set — or maketthe Unknown and find when a waveform reaches a value. - An FD solve hands over its s-domain
system, with
sas a Known complex number you can move around the plane. - Tick Include the derived answers and each element’s power and voltage drop cross too, as equations of their own — arriving unticked, so the sheet still lands on the circuit alone. Tick the one you want; or untick the source’s equation, pin a power Known, and the sheet finds the source value that delivers it.
This system is too large to travel in a link, so it was saved as
numerical_system.json — drop that file anywhere on
the Numerical Solver page that just opened, and it loads.
SPICE Translator
Translate a circuit between Symbulator notation and a SPICE netlist (ngspice, LTspice, PSpice). Whatever the destination notation cannot express is reported below and left out, rather than mistranslated. Check the translated circuit before relying on it: it runs in another tool, where a silent difference would surface a long way from here.
About Symbulator
Symbulator is a free linear circuit simulator for handheld devices. The name is a portmanteau of "symbolic simulator": Symbulator accepts inputs with numerical and symbolic values, and provides numerical and symbolic results. For over a quarter of a century, Symbulator has been widely considered the best symbolic simulator of linear circuits ever made for a handheld device. Symbulator is, has always been and will always be free of charge. Acknowledgements
Symbulator speaks thirteen languages, and every translation was written by an AI rather than by someone who speaks the language. If you read one of them, correcting a phrase is the most useful thing you can do for this program. The dictionaries are files you can take away, edit and send back. Help translate Symbulator
Symbulator was made by Roberto Perez-Franco on a Texas Instruments TI-89 calculator, starting in 1999, as an engineering student at Universidad Tecnológica de Panamá (UTP). An early version won 1st place at the 2000 IEEE Student Paper Contest for Latin America. Version 5 served as Roberto's graduation thesis in 2001. He released version 6 in 2013 and version 7 in 2023, both for the TI-89 Titanium, along with a port to the TI-Nspire CAS II as version 8.
This port of Symbulator to Python and SymPy is version 9 in that lineage. Whereas versions 1 through 8 were written by Roberto entirely by hand, this new version — in a sign of the times — was ported and developed using Anthropic's AI assistant. Claude took care of all the coding, while Roberto provided instructions and feedback, during an intense collaboration in August and September 2026. It is the author's hope that this port will preserve Symbulator for a new generation.
Since 2013, all versions of Symbulator are offered under a Creative Commons License (CC) BY-NC-SA. Since 2026, all versions of Symbulator are free and open-source software, released under the MIT licence: you may use, study, modify and share it, including commercially, with attribution. The solver is published as the symbulator package on PyPI, and the project for it and this interface lives on GitHub. Contributions, bug reports and circuits that break it are welcome.