One of our forthcoming products has some analogue filtering in it (shhh, supposed to be a big secret) and naturally I’ve been on the hook for topologies, algorithms, equations and all that good stuff. Like with all of our programmable devices, the functionality is accessible through virtual ‘components’ you drag onto a schematic canvas in our “PSoC Creator” tool. So I work with our awesome component development teams to try to get my hard-won analogue expertise into these two-dimensional sprites that dance around on our circuit diagrams.
Quality control time. I delivered my “how-to” in the form of a Frankenstein cobble-up of spreadsheets and BASIC programs, which showed end-to-end the development of the target types of filters, from humble beginnings as a frequency response requirement, through the smooth infinitude of the s-plane, crashing into the rolled-up cardboard tube that is the sampled-domain representation, and finally into a set of capacitor values wrapped around a fast little amplifier and some chattering switches. (Ed. – that might be too much of a clue about what type of filter this is).
All of this expertise is then patiently turned into something of production quality by the component team, who very kindly delivered me some code to try out. In one previous exercise, I’d been delighted that the rather extreme filter we’d dialed in came out with exactly the same capacitor values as offered by my own methodology. So far, so good.
I’d done a bunch of test cases in my spreadsheet, so I started to use the new software to generate transfer functions and capacitor values, to check against what I’d pre-calculated and simulated. And the very first example I tried produced sets of values that weren’t the same. Not massively different, or slightly different, but moderately different.
So I did some eyeball-rolling and old analogue-guy harrumphing and put the numbers into a simulator and – they looked OK, at least on a little graph. But this cannot be, I thought. I have an explicit, closed-form solution for the dissipation factor and pole frequency of the section that implements that response with those constraints. And that solution generates a different set of numbers, and I know for certain that those numbers work.
Click on the calendar – time for a meeting with the component team. Can I eyeball your C# code, you may have implemented my equations slightly incorrectly?
“Uh, we didn’t use your equations, we used the ones from a memo one of us wrote a while back, we did send you a copy…”
Seen the great movie ‘Inside Out’? At that point I was the dumpy red-faced emotion with the flames coming out of his head – that’s right, Anger. Didn’t use my equations? Like, didn’t use the formally, proven, correct, wore-down-two-pencils-on-that solution from the one guy in the company who is supposed to know about filters? Rrrrrr…
The meeting went well, in the sense that the same number of people emerged from the room as went in (not a foregone conclusion around here). Though I didn’t think of the analogy at the time, it was like the scene in another favourite movie, ‘Terminator 2’, where the craggy, obsolete, old-tech T-800 battles for supremacy with the confident, supple, young, advanced prototype T-1000 in the back corridors of a shopping mall.
This guy hadn’t worn down two pencils to get his result, he’d typed a few lines into Mathematica and come up with something that just looked darned wrong to me, intuitively. My intuition up against Steven Wolfram’s baby. Guess I should have reflected on that…
“Well, we can’t both be right. Let me go and think about it.” Neither of us had proven the other wrong. The only card I really had to play was the expert / seniority one and I do try to be really careful with that as it just shuts things down, which is the last thing you want to do to a bunch of bright, enthusiastic people.
So I instrumented up my spreadsheet to show interesting things like the derivative of the magnitude response as input frequency approaches zero (maximally flat at the origin, that’s the buzz phrase; a generalization of Butterworth) and also put in my young challenger’s design equations.
Mine worked. His worked. Changing anything in either produced solutions that did not work.
It’s a problem with exactly two solutions. We were both right – and our methodologies were both incomplete. We had solved the problem two different ways, and each method found only one solution. I looked hard at my derivation, and even harder at his (because I didn’t really grok the math syntax) and could see no way of extracting the other solution from each of them.
The moral of this story – just because you’re correct, doesn’t mean you’re right. I thought my young colleague had screwed up by misunderstanding the one way of getting to the solution. But I had made the false assumption that because I had solved the problem rigorously, the solution I came up with must be the only one.
And – lest people think that, since both methods give ‘correct’ filters, that I’ll stick with mine – there’s a fairy-tale ending to this. I’m going to use his solution, and change my cobbled-together precursor to implement his transfer functions. They are simpler, more obvious and will make way more sense to our customers. And I’m going to rope this guy in to check all my stuff from now on. We need new ways of thinking, if only to dilute and challenge the old ways (which, as you know, I still try to champion in this ever-so-modern world). Maybe I need to learn Mathematica too. But then, maybe Mathematica needs some sort of Turing-esque function that can tell you how many solutions a particular problem has. And watch out for some filter news next year! – Kendall