A Butterworth low-pass filter can be designed "graphically" by spacing its poles equally on unit circle, and then using only the poles in the left half-plane.

Is there a similar rule to find the pole locations for a Bessel-Thomson filter?

  • 1
    \$\begingroup\$ They are on an elipse that is stretched in the jw axis compared to the \$\sigma\$ axis and I think you should be able to work it out from the polynomial but I've never done that. You probably knew that, a man of your calibre. Steeper filters also have poles on an elipse but the elipse is wider in the \$\sigma\$ axis. As a steep filter morphs into a bessel it passes through the butterworth \$\omega_n\$ circle. \$\endgroup\$
    – Andy aka
    Jun 8, 2018 at 18:46
  • \$\begingroup\$ The Photon, is this a pure theoretical question? Of course, one can ask such things. My only point is - for which purpose? For designing Thomson-Bessel filters, there are other and more practical-oriented design rules (e.g. list of pole frequecies and pole-Q values). More than that, for Bessel approximations, it is not uncommon - with respect to application requirements - to define the cut-off frequencies in the time domain (delay properties). \$\endgroup\$
    – LvW
    Jun 9, 2018 at 17:06
  • \$\begingroup\$ @LvW, the reason for the question is to have a way that's easier to remember, and perhaps more intuitive, to construct (or verify) a B-T filter. \$\endgroup\$
    – The Photon
    Jun 10, 2018 at 13:56

3 Answers 3


\$\color{red}{\text{I made a mistake and I need to redo parts of the answer!}}\$ My apologies, however, the mistake is not that bad, since not all the answer is wrong. It bugged me why the group delay is not flat for a 13th order, or why the impulse response doesn't have a minor dip (since Bessel is not a Gaussian). I realized the mistake was already hinted at when I said I used the unsorted poles for the Bessel, which caused the transfer function to go wrong (though not by much). This means that I need to redo the part of the answer that deals with the comparison between the Bessel and the pole placement method; everything else is fine. Again, I am sorry for the mistake. Feel free to downvote, if you will.

Similar, though you'll not get away with just that, there is no closed form solution since they're found only based on the Bessel polynomials (i.e. root-finding). The poles are placed on an elipse, as Andy mentions, but with an offset in the right-hand side. Here's for N=13 for example (upper half):


Still, since the generating polynomial is fixed, i.e. only frequency scaling is needed, then the poles are also fixed and can be generated a priori, for a table (as an easier solution).

For clarification, here's the generating polynomial:


  • \$\color{red}{\text{This is the initial mistake.}}\$ The transfer function was based on the poles, but the phase and group delay on the polynomial above, because both the atan() and the diff() blew up numerically.

and here are the poles (unsorted):


for comparison, the poles of a Chebyshev with 0.01dB ripple:


Also, for comparison, the Bessel poles with a circle and the Chebyshev poles, both scaled for better comparison:


Note that the ellipse in the case of Chebyshev is aligned with the greater axis along the Y-axis, while the Bessel poles align themselves with the smaller axis on the Y-axis, while also having an offset.

I remember one book claiming that the poles lie on a circle, displaced to the right, and that they share the same angles as the Butterworth, but projected onto this circle. I used now an N=35 (odd for the extra, single real pole), with a circle, with proportional X and Y axis, but still scaled for better comparison:


The circle is scaled (both X and Y) by 37, and displaced to the right by 37-max(realpart(sBessel)). As you can see, the curves differ. One time I tried what you're asking now, by trying to approximate with a 90o rotated cosh() curve -- close, but no cigar, as they say. Here's a comparison:


I simply resigned and, years after, this question was asked on dsp.se (warning: lengthy post). I'm afraid that, sometimes, there just is no holy grail. In this case, you're stuck with the generating formula for the polynomial:


which can get "fluffy" for \$k\rightarrow 0\$, so the recursive one can get you a bit further, but with minor rounding issues:


From then on it's the root-finding algorithm of your choice. Or, as I said, you can make tables, for example here's the complete roots of up to N=20, in double precision. Note: these are unscaled, i.e. calculated for delay, not frequency(!):


I doubt you'll need more, but, if you do, I can copy-paste. The tables are very useful when you have memory to spare, as opposed to cycles. All you need from now on is frequency scaling, as these will get you nice 2nd order stages.

Update: Andy's post remimded me that once I concocted up a frequency scaling formula (from the then zunzun.com., now defunct, sadly), but it works decently. For example, for -3dB point, a sweep from N=2 to 32 gives the difference between the first and the last trace of ~0.31dB, and ~0.0125dB between adjacent traces. It's not perfect, but it works:


where Asc is the attenuation, in dB, at fc and N the order. As a small example, for the same 13th order and 3dB, the scaling would be |H(j4.13082549938354)|, while the formula says |H(j4.125564879197584)|, which gives -3.0025dB (0.7077408150981647). It's not limited to only 3dB: if you want 1.57dB, then \$\omega_{scale}\$ should be 2.99434327282329, while the formula says \$\omega_{scale}\$=3.001850652953856, which results in -1.577946667040319dB (0.8338782890589183). I say it's not bad.

  • \$\color{red}{\text{This part is redone.}}\$ I will keep the mistakes and pictures only as links, for shaming.

Update: I just tried what you propose, that is, to compare the Bessel with the pole placement on the circle, as the document from analog.com, and wherever elsewhere I read, say. First, since I already have N=13 above, I made the example for N=13. Second, I scaled the Bessel poles to match the X-axis.

Since the imaginary part of the poles are separated by 2/n and placed on a circle (non-displaced), then all you have to do is generate a list based on that, and the realpart is simply \$\Re=\sqrt{1-\Im^2}\$:


And this is how both poles look like compared to the unit circle. From here on, Bessel is blue.


Next, make the transfer functions and compare them. I applied frequency scaling to both so they have -3dB@1Hz: Bessel= 3.277105084487313, p.p.=0.3193551457708009. Interesting enough, the reverse of each is close to the other (less so on lower orders). Notice that Bessel has a steeper rolloff. In addition, the magnitude according to the long polynomial above is also plotted as the dashed green line; since it overlaps with the blue one, the blue one is kept as reference from now on.


(wrong: https://i.stack.imgur.com/7PtRa.png)

and the difference between them (it shows zero towards the end because of numerical inaccuracies, given the huge numbers in the original Bessel polynomial -- no longer the case, the transfer function is made up of 2nd order sections, made up of sorted out poles.):


(wrong: https://i.stack.imgur.com/VEbgY.png)

Then, the phases. Not surprisingly, differences due to the different rolloff:


(wrong: https://i.stack.imgur.com/EH5z1.png)

and the difference:


(wrong: https://i.stack.imgur.com/VQIA8.png)

And the most important, the group delay Bessel is truncated for the same reasons as above). Note that the p.p. method has lower delay, due to the slower rolloff, but also that it is not as flat as Bessel:


(wrong: https://i.stack.imgur.com/yWv7g.png)

and the difference (both normalized to 1, for easier comparison):


(wrong: https://i.stack.imgur.com/lVjQI.png)

Update: The flatness of the group delay can be verified with the derivative:


Conclusion: the pole placement is not a Bessel response, but it comes very reasonably close, so if you don't mind the minor differences, this is a very convenient and, perhaps most importantly, cheap way to generate the poles by avoiding the expensive root-finding algorithms. Note, however, that I only used N=13 for this, so, for an attempt at completion's sake, here's what the differences for N=5 look like, in order: magnitude, phase, group delay, update and flatness of group delay:

mag5 ph5 gd5 flat5

(wrong: https://i.stack.imgur.com/YVA1j.png, https://i.stack.imgur.com/gNKCc.png, https://i.stack.imgur.com/gqegm.png)

As a minor addendum, here are the impulse responses of the two 5th order, with the same Bessel=blue (using the -3dB frequency scaled versions):

(wrong: https://i.stack.imgur.com/BG4MF.png)

[I added this part at the end]

  • \$\color{red}{\text{End of redone, part 1.}}\$

Well, you've opened up an old wound, congratulations. I thought about modifying the Bessel poles (blue) by projecting them onto the unit circle along the X-axis, so they will lose whatever curve they normally have and convert them, forcefully (red). In addition, by comparison, the black squares are the p.p. method.


  • \$\color{red}{\text{Redone, part 2.}}\$

and the magnitudes of the Bessel (blue) near the converted Bessel (red dashed magenta) and p.p. (black red) -- for some reason, the rolloff is slower for p.p., I must have some typo somewhere, I won't find it today:.


(wrong: https://i.stack.imgur.com/vOmao.png)

All for N=13, and the results are consistent for 5, 9, 25, so on it seems. The conclusion remains: not Bessel, but darn close. Pick your choice.

This should be the last edit (before I go over the rabbit hole's event horizon) to address the issue of the displacement of the underlying circle. Doubts crept up so I wanted to clear this out. From previous pictures, it's clear it's not a circle, it's not some cosh(), but something else, but numbers are clearer than pictures, so I started a reductio ad absurdum: what if it is a circle? Then it should be scaled and displaced. Here's the basic idea:


The circle of radius OM (grey, dashed) is the unit circle, and the blue one of radius MQ would be the underlying circle. At point C is a pole whose coordinates are known. OM is also known, so \$AM=1-\Re(C)\$ amd \$AC=\Im(C)\$ => the red angle (ignore the reading), \$\alpha=\arctan\frac{AM}{AC}\$, while the green angle, \$\beta=\frac{\pi}{2}-\alpha=\arctan\frac{AQ}{AC}\$ => \$MQ=AM+AC\tan\left(\frac{\pi}{2}-\arctan\frac{AM}{AC}\right)\$, with the displacement being a simple subtraction.

But, for N=13, calculating the radius of the underlying circle should be the same for all the poles, yet it isn't. Here's the values for all the radii for the positive imaginary parts of the poles that are not on the X-axis or Y-axis (5 poles, see 1st picture):

  • \$\color{red}{\text{Redone, part 3.}}\$ Since the poles were mingled, the results came mingled, plus, I calculated the diameter. Not a biggie this one, since the result is the same: no underlying circle.

[2.882849152139202,2.896382080602158,2.920436970785266,2.957894588441385,3.014834976457822] [1.448191040223894,1.460218485342188,1.478947294206138,1.507417488214167,1.553654588674449]

And here is a graphical representation of what the underlying circles would be for each of these poles. Note that, not only they don't overlap, but only one of each pole lies on a circle at a time (of course, the one after the circle has been calculated):


This should be the proof that, however flat the group delay is from the pole placement approximation, it's just an approximation, not a Bessel in the true sense. IMHO, this should have been specified by both analog.com and whatever other sources mention it -- that it's an approximation, a very good good one, but not Bessel(-Thompson).

And, since the wound goes deep, here's some more. It strikes me that, the larger the order, the more the p.p. method converges towards a Gaussian filter, and, sure enough, here's a plot of a reference gaussian function, \$\exp\left(-\frac{\ln2}{2}x^2\right)\$ (black), an approximated transfer function "a la Bessel" (blue, frequency scaling needed), and a free, non-frequency scaled version of the p.p. method (red):


If you can't see any difference it's because of the small things in life:


Does this mean that the p.p. method converges towards a Gaussian filter? No. Here are the poles of the Gaussian (blue) and the Bessel (red), scaled for comparison with the unit circle:


They're even more spread out. But are they, at least, placed on a circle, displaced or not? Here are the results of the radii of the circles, in a method similar to one for Bessel, above:


and the graphical representation, after another forced attempt at projecting them onto the unit circle (again, same way as Bessel, above):


For completeness, here's the impulse reponse of the Gaussian (blue), compared to the Bessel (red), and the p.p. method (green):


Given this final proof, the p.p. method is even better in terms of time-domain compared to Gaussian, but that also means that, frequency-wise, it's a mess. However, I am thinking of another pproach, but that will be for another day.

  • \$\begingroup\$ I'm not 100% but that looks more like a cheby placement of poles. Again I'm not certain but this looks more like an elipse that is flatter rather than taller and is indicative of a steeper roll-off compared with bessel. You should double check your diagram. \$\endgroup\$
    – Andy aka
    Jun 8, 2018 at 19:25
  • \$\begingroup\$ Which way the ellipses are oriented might be more obvious if you used the same scaling for x and y axes. Is there any simple(ish) rule for the parameters of the ellipse? \$\endgroup\$
    – The Photon
    Jun 8, 2018 at 21:58
  • \$\begingroup\$ @ThePhoton I used the same scaling on both X and Y, also updated the answer, maybe you'll find it useful. \$\endgroup\$ Jun 9, 2018 at 6:35
  • \$\begingroup\$ @ThePhoton I've added a frequency scaling approximation, in case you're interested. \$\endgroup\$ Jun 9, 2018 at 18:49
  • \$\begingroup\$ Thanks, that's exactly what I was looking for. Especially for the n=5 case, which is a filter used in a bunch of networking standards. \$\endgroup\$
    – The Photon
    Jun 10, 2018 at 14:00

I am making this answer separate, because it deals with finding an approximation, directly, as opposed to the answer if there is such a thing.

Before I go on, I should mention that this has been an old thought which was left aside, after trying poles of the form \$\cosh n+j\sinh n\$, or a hyperbolic distorted Butterworth, among others. This time, and particularly after this revival, I'll try a different, more (hopefully) educated approach.

As shown in the other answer, there is no underlying circle, and the curve isn't some exotic cosh(), either. But it is a curve, and let's see if, maybe, we can use the visual cues to determine an approximation. Here are the poles for the same Bessel with N=13, but this time split into real (blue) and imaginary (red) parts (normalized to the unit circle):


The axes are not proportional, so that the real parts look very much like a circle, which would explain why someone would think they are placed on an underlying circle, if they haven't plotted them as in the previous answer, directly compared to one. But, if you look closely, the imaginary parts are not linear, they curve up and down towards the ends, like a tangent. The circle is also, not quite a circle (seen later on), so the erros only add up.

So, let's see what we get if we try a circle, \$\sqrt{1-x^2}\$, and a tangent. But with what values? Let's try from 1 to -1, to keep things smooth. The stepping should be 2/N, just as in the reference(s), but also a logical choice:


The circle seems close enough, already, but the tangent is too much. A smoother curve is needed. Due to the nature of the Bessel transfer function as an approximation of \$\exp(-s)=\frac{1}{\sinh s+\cosh s}\$, sinh() comes to mind:


The curve looks much better, all there's needed is scaling, say 1.2. The circle could also use some "bending", so let's try raising the square root to a fractional power, small enough, say 1.1:


The sinh() could use less curving, the circle could use less drooping towards the ends, but it looks fine, certainly better than simply projecting onto a circle. So let's try them. First with unscaled circle and sinh(), a 5th order, compared to a Bessel, both scaled for -3dB@1Hz:


I have to say that looks very nice for a simple sqrt() and a sinh(), as opposed to some big polynomial made up from factorials, solved with root-finding algorithms:

.func real(x) {sqrt(1-((x-evenN/2)*2/N)**2)}
.func imag(x) {sinh((x-evenN/2)*2/N)}

where evenN is 1 if N is even, and 0 if not (pretty self-explanatory), and the transfer function was used as a Laplace (using LTspice), in .AC, as this source shows it (last one is a single order for evenN=0):

E1 1 0 i 0 Laplace=({real(1)}^2 + {imag(1)}^2)/((s/w)^2 + s/w*2*{real(1)} + {real(1)}^2 + {imag(1)}^2)

Since Laplace, in LTspice, can be very unreliable in .TRAN (to say the least), the following 2nd order stage can be used, instead. Warning: this is for all-pole lowpass only, is unbuffered, and assumes a strictly-proper transfer function!


To conclude, a sweep for N from 2 to 8:


For some reason I find this beautiful, compared to the results of the pole placement method in the previous answer. For lower orders some tweaks might be needed, for example the power of the sqrt() and the scaling of the sinh(), and there needs to be some frequency scaling, here the following table has been used:

.func wsc(x) {table(x, 2, 0.806, 3, 0.7367, 4, 0.6783, 5, 0.6259, 6, 0.5803, 7, 0.5416, 8, 0.509)}

It's not restricted to lower orders, here's how it looks for N=13 (frequency scaling 0.42054):


And what about the scaling for the poles? Here's another sweep (N=2..8) for 1.1 as power to sqrt() and 1.2 scaling for sinh() (also some other frequency scaling table):


Strangely, despite the visual higher similarity to the original poles, the results seem to come slightly worse.

Conclusion: For the aforementioned reasons, I declare this method a good enough, but much better approximation of a Bessel filter. No doubt someone can improve it, while keeping the simplicity of the equations for calculating the poles. Now it's late and I'm off to sleep, hopefully the wound can close now.

Just one final note and then I'll leave it at that. After some minor hammering (I'm not afraid to get dirty), I returned to my original guess for the imaginary part, tan(), and then tweaked the formulas to end up with:

.func real(x) {sqrt(1-abs((x-evenN/2)*2/N)**2.1)}
.func imag(x) {tan((x-evenN/2)*2/N/2.5)*3.1}

The change is abs(x), instead of x, to allow for fractional power which changes the curve differently than a power over all of the function, while tan() has some extra division to get into the softer part of the curve, then simply scaled upwards. I won't encumber the thread with another picture for the poles, they'er similar to what has already been posted, but the response is now changed. Here's a sweep for .step param N 2 18 3, for a non-frequency scaled version of both (that is, calculated for group delay, not frequency):


The lower orders (N=2,3) have slightly more rolloff, which results in a bit more group delay, thus the impulse response is temporally-smudged a bit, but it only goes better from then on. The only thing that I ad to do to get to this was to multiply \$\omega\$ by a fixed frequency scaling term equal to \$0.69N\$. This means that the formula for frequency scaling, given in the previous answer, can be valid for the approximated Bessel! Here's the formula at work:


Sure, there are minor incosistencies, particularly at lower levels, but those can be addressed, easily. In rest, I've also tried the initial try form years ago, where the poles were thought to be of the type \$(2-\cosh n)+j\sinh n\$, but the group delay is softer towards fc, however, I now added the power and scaling, which seems to give small control over the sharpness, but not as the ones above. And with this I conclude the whole story. Hopefully.

  • \$\begingroup\$ I won't make another edit, but there's a tweaked version for the formulas: instead of 2/N, it's 2/N/ADJ (for both), and instead of 0.69*N it's 0.69*ADJ, where ADJ=(N*N+1/1.4)/N. Here's a sweep from N=2..18: i.stack.imgur.com/ccUTi.png . \$\endgroup\$ Jun 13, 2018 at 5:45

I'm throwing my twopenneth in because it's interesting. I haven't got an answer but just a picture of the pole positions for 2nd order to 10th order. I think it's more important to to see the trends between different order filters that have the same 3 dB point. The data was taken from this table: -

enter image description here

And, taking the numbers and using excel you can get this picture: -

enter image description here

Is there a similar rule to find the pole locations for a Bessel-Thomson filter?

There probably is but it's beyond my math. This is the best I can come up with on my own.

However, MT-204 by Analog devices suggests a relationship between the poles like this: -

enter image description here

I recognize the authority of the source but it does seem to disagree with the tables you can commonly find on the subject. It also lists the same table I used (later on in the AD document) so I'm unsure how they managed to fit things around a circle when clearly they are not. But, if the circle centre is not at the origin of sigma and jw, maybe the poles do lie on a circle?

  • 1
    \$\begingroup\$ I found that Analog doc a few minutes after posting the question. When I've got a minute I want to plot the circular approximation vs the table values. \$\endgroup\$
    – The Photon
    Jun 9, 2018 at 19:56
  • \$\begingroup\$ Should be interesting. \$\endgroup\$
    – Andy aka
    Jun 9, 2018 at 20:01
  • \$\begingroup\$ Could it also be possible that to create an nth order Bessel filter, there may be more than one valid solution. Maybe that is something worth considering @ThePhoton \$\endgroup\$
    – Andy aka
    Jun 9, 2018 at 21:34
  • \$\begingroup\$ @ThePhoton That's an interesting take, so I thought I'd try it. I've updated my answer with some very interesting results. \$\endgroup\$ Jun 10, 2018 at 7:36
  • 1
    \$\begingroup\$ There is another (small) disagreement of Zumbahlen`s Mini Tutorial if compared with theoretical analyses . It is not correct to state that the step response of the Bessel filter would exhibit "no overshoot". Each filter with complex poles shows an overshoot because the pole-Q is >0.5. \$\endgroup\$
    – LvW
    Jun 11, 2018 at 6:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.