Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible node / source id collision in symbolic analysis #17

Open
ggventurini opened this issue May 14, 2014 · 10 comments
Open

Possible node / source id collision in symbolic analysis #17

ggventurini opened this issue May 14, 2014 · 10 comments
Labels

Comments

@ggventurini
Copy link
Member

If a circuit contains a voltage source with part_id V<something> and the circuit has a node named <something>, the symbolic solver will first create two variables equally named V<something> and then it will confuse them for referring to the same quantity, incorrectly.

See the end for a work-around.

eg. the example netlist file a.ckt quoted below:

THIS FAILS.
v1 1 0 type=vdc vdc=1
r1 1 0 1k

.symbolic

Produces:

$ahkab a.ckt
Starting symbolic AC analysis...
Building symbolic MNA, N and x...  done.
Building equations...
Performing auxiliary simplification...
Symplified sytem:
To be solved for:
[V1, I[V1]]
Solving...
Traceback (most recent call last):
  File "/home/gventuri/.local/bin/ahkab", line 9, in <module>
    load_entry_point('ahkab==0.09', 'console_scripts', 'ahkab')()
  File "/home/gventuri/work/repos/ahkab/ahkab/__main__.py", line 164, in cli
    outfile=cli_options.outfile, verbose=verbose)
  File "/home/gventuri/work/repos/ahkab/ahkab/ahkab.py", line 659, in main
    results.update(run(circ, [an]))
  File "/home/gventuri/work/repos/ahkab/ahkab/ahkab.py", line 467, in run
    r = analysis[an_type](circ, **an_item)
  File "/home/gventuri/work/repos/ahkab/ahkab/symbolic.py", line 140, in symbolic_analysis
    eq, x, manual=options.symb_sympy_manual_solver, simplify=True)
  File "/usr/lib/python2.7/dist-packages/sympy/solvers/solvers.py", line 688, in solve
    symbols=symbols)
  File "/usr/lib/python2.7/dist-packages/sympy/solvers/inequalities.py", line 487, in reduce_inequalities
    "only univariate inequalities are supported")
NotImplementedError: only univariate inequalities are supported

While, just substituting V1 with Va1, as follows:

THIS WILL NOT FAIL
va1 1 0 type=vdc vdc=1
r1 1 0 1k

.symbolic

Produces, correctly:

$ahkab a.ckt 
Starting symbolic AC analysis...
Building symbolic MNA, N and x...  done.
Building equations...
Performing auxiliary simplification...
Auxiliary simplification solved the problem.
Success!
Results:
I[VA1]   = -VA1/R1
V1   = VA1

As this bug is inside the symbolic solver, it is in dependent of whether the netlist or the Python interfaces to the simulator are used.

Work-around: If you have a voltage source named V<X>, avoid naming any node X.

@OwenHempel
Copy link

Proposing a solution: Under the hood, rename the voltage source to Vs.

Alternatively, give each component in the circuit a unique identifier for symPy to use and use a dict to link those IDs back to the original string name.

@itdaniher
Copy link
Contributor

Given this bug is pretty easy to run into when writing netlists, and that mentally tracking dependencies is kinda a PITA, I'll take a stab at implementing unique naming / conflict resolution. Thanks for the thought!

@OwenHempel
Copy link

No problem. If you'd like some collaboration I'd like to contribute. I was wondering myself how possible it would be to write something like this project, give it an optional GUI and run it in a web framework. End goal is sound effects modelling, but really I can see this having applications in my line of work.

@itdaniher
Copy link
Contributor

I'd be glad to collaborate, there's plenty of room to grow, and I'm keen to see it maintained. Ahkab is a very versatile and effective platform for "continuous time" system modeling, and I have no doubt any variety of audio effect could be readily realised. I've personally used the project for modeling audio filters paramterized with physical / electrical units and converting the result into a filter which can be applied efficiently via the FFT/iFFT.

@itdaniher
Copy link
Contributor

@Phantom410 found the file I wanted to share! check out https://github.com/itdaniher/ahkab-notebook/blob/master/zttest.py - it's a bit dense, but does some of the system modeling I referred to above!

@OwenHempel
Copy link

Interesting.

The model this tool produces look really good, so let's see how we can work around this:

  1. A dict mapping internal ID to user assigned name

  2. A database with Primary Key internal ID and field external name

  3. An addition to the circuit object involving unique identifiers for each component.... probably leads back to 1).

I'd say the dict route is the quickest and most "Pythonic" way about this

@itdaniher
Copy link
Contributor

10/10 for a dict, probably belongs on the Circuit class?

@OwenHempel
Copy link

I'd think so, the circuit would "contain" the elements.

I'm on the fence as to {ID:"External Name"} versus {"External Name":ID}. I don't think in the end it matters to the internal functionality, so the question will be: How is this presented to the user?

I think the most likely way to use this is to "look up" an external name as a key and return the ID as a value, but the ID as a key more closely resembles the database solution. Also, and this occurs to me as I write this, it would be possible to have more than one element share an external name (let's pretend the user really isn't good at this), so the ID makes more sense (to me) as the key.

@itdaniher
Copy link
Contributor

Agree with {long_uid: "External Name"}.

The ID could be something magic like a hashed copy of the line in question, which would be internally consistent, easy to derive, and not freak out if there're duplicate lines....

This would mean you could name every element "R" and as long as they weren't the same value in parallel (with the same nodes specified on the relevant line), each element could get its own sanely-derived UID.

Extension could be hashed copy of the line in question, salted with the line number, as an adjustment to the pathalogical "there are two modes and a bunch of equal resistors" pathalogical case.

For add_foo on Circuit, it could just pick a number out of a hat. Guess this could also be done at the parsing stage, making fancyness above irrelevant....

I'm very pro moving to 96b or 128b element names internally, and I think adding a dict on Circuit mapping uids to display names is quite appropriate.

@OwenHempel
Copy link

Awesome, sounds like we have our plan. I like the hashed/salted with line number idea. We could use a sequential number system but I'm willing to bet that will get caught up in a problem somewhere else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants