Comments (6)
Wow @BGerwe this is a fantastic write up of your exploration ๐ thanks for working on getting this implemented correctly!!!
from impedance.py.
I started working on this again last night, and came to the conclusion that our implementation of LinKK treats the ohmic resistance as a fitting parameter, rather than holding it constant. In the case presented above, the simulated data above has a high-frequency intercept of 100.323 ฮฉ, but the "under-fitting" uses 100.65 ฮฉ and the "over-fitting" case uses ฮฉ. OK, maybe that's not so convincing. So, I simulated another circuit with only RC elements and an ohmic resistance.
circ = 'R0-p(R1,C1)-p(R2,C2)-p(R3,C3)-p(R4,C4)'
vals = [10, 100, 1e-6, 60, 1e-5, 200, 3e-4, 300, 1e-5]
circuit = CustomCircuit(circ, initial_guess=vals)
When I apply LinKK and look at the circuit string, I see s([R([7.602373651530629],[100000.0,...
proving the ohmic resistor can change values, since the RC-elements are represented by a K element in this case. After making some changes to (hopefully) hold the ohmic resistance constant, I verify that's true by looking at the circuit string again s([R([10.025830624944371],[100000.0,...
Now, checking out how the fits compare:
As another accuracy check, I went through the hassle of installing the LinKK Test Software M. Schonleber et al wrote, and cross-checked my results by forcing their software to use the same M:
With the ohmic resistance held constant this looks better but still doesn't match the results from their software. A particularly noticeable feature is the maximum residuals from their software peaked above 2% around 20-30 Hz. In my analysis we see a similar peak above 2%, but it occurs around 1 kHz. So, I reincorporated a change mentioned in my first comment, namely that the paper uses radial frequencies, but our implementation used linear frequencies.
Now, our residuals look nearly identical except for mild discrepancies at the highest frequencies.
As a final check, I let their software detect the appropriate number of RC elements instead of manual enforcing a number. Unfortunately, their software doesn't report a final ยต-value for their fit, but it does report using 66 RC-elements for the fit.
On the other hand, if we set a c = 0.75 (vs their recommended 0.85), we reach ยต=0.747 at 23 RC-elements. I think the fit looks pretty good, if a little under-fitted. But, if we increase M to 66 I see no difference between their results and ours (not shown).
The final thing, which has me rather stumped still, is these changes make LinKK fail for data with a low-frequency warburg even if they're simulated. Even using a high M (M=45 vs #data=71)
On the other hand, their software finds a nice fit with M=32, though a little oscillation in the residuals is still evident at the lowest frequencies.
For an apples-to-apples comparison, I used M=32 in our software:
As you can see, there's quite a bit of oscillation with my changes that occur in the original implementation. My guess is they have a more sophisticated algorithm for guessing initial values, but I have no way to verify.
Final Thoughts
Despite failing to totally fit data with a low-frequency Warburg, I think we should move forward with my changes. With them, LinKK correctly validates data it failed to validate before (there are several iterations of circuit simulations I looked at but didn't present here). Further, it closely matches results from their published software (under the same conditions) whereas the current method often gives very different results.
from impedance.py.
Quoting from PR #87 so I can close that but keep the conversation going:
Looks great! Nice job ๐ only thought is if there's an relatively easy way to repurpose all your exploratory comparisons with the Lin-KK tool into a test for
linKK()
?
Do you mean something for unit testing? Or a way to test if the result appears underfit?
from impedance.py.
Unit testing (although building on their algorithm is also an interesting thought). validation
is by far our weakest remaining point in terms of test coverage. I was thinking that you've got through and manually figured out what should be "right," maybe it would be straightforward to add that as a test. ๐ค
If it's not simple to just plop in your exploratory code, I think this is a separate issue and we should come up with a circuit-derived impedance that should pass and an intentionally bad impedance (e.g. imag shifted) that doesn't (or something like that) at some point.
from impedance.py.
Yeah, I don't think my exploration would be a good drop-in test. That said, I have ideas for validation unit testing that I'll write up fairly soon.
from impedance.py.
sounds good! ๐
from impedance.py.
Related Issues (20)
- [BUG] .append no longer available in pandas > 2.0
- [Element]
- Error in visualization with looping through and fitting multiple data sets HOT 2
- [BUG] Deprecation warnings with Altair v5
- [BUG] Matplotlib warnings when plotting Bode or Nyquist plot HOT 1
- Very confused about fitting HOT 3
- BaseCircuit.predict() won't take float as input
- Confusion with the word "initial_guess" used in CustomCircuit(circuit_string,initial_guess) HOT 1
- Initial_guess HOT 2
- Replace print with proper logging HOT 1
- RC components
- A worked example of .nox Metrohm file reading and pre-processing HOT 3
- high frequency fitting problem HOT 12
- Accuracy of data in .par file about VersaStudio HOT 3
- Ask for help extracting parameter values from fitted circuits HOT 1
- [BUG] error in impedance definition of La-element
- reading data from Excel files
- Circuit Element Unit scalable feature
- Adding Distribution of relaxation times feature HOT 2
- Recommendation for dealing with noisy data?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from impedance.py.