iconEuler Examples

Equal tempered Scale by Strähle

by R. Grothmann

We try to compute and verify a good approximation to the equal
tempered scale. The construction is due to Daniel Strähle (1743). The
idea to simulate this in Euler is from Alain Busser.

Here is a link to a related paper:

http://en.wikipedia.org/wiki/Str%C3%A4hle_construction

First we sketch the basic idea in a plot.
>t=0:0.1:1; d12=(0:12)/12; plot2d(t,d12'*t,a=-0.2,b=1.2,c=-0.2,d=1.2); ...
>m=-1.2; x=m/(m-1); y=x; x1=1-2*(1-x); y1=m*(x1-1); ...
>plot2d([x1,1],[y1,0],color=4,add=1); ...
>x=m/(m-d12); y=d12*x; plot2d(x,y,points=1,style="o",add=1); insimg;

Equal Tempered Scale by Strahle

The black lines have slopes d = 0, 1/12, 2/12, ..., 1. The blue
line has slope m (negative).

As you can see, the marks on the blue line look almost like a
guitar fret. The uppermost mark divides the fret in two, yielding
an octave.

The exact locations of the fret postions would be a fraction of
2^d from the total length. We add the exact locations to the image.
>xe=x1+(1-x1)/2^d12; ye=m*(xe-1);  ...
>  plot2d(xe,ye,points=1,style="[]",color=6,add=1); insimg;

Equal Tempered Scale by Strahle

As you can see these points are considerably off the right spot.
But we have the parameter m to play with.

First of all, compute the intersections of the black line y=d*x
and the blue line y=m*(x-1) with Maxima.
>sol &= solve([y=d*x,y=m*(x-1)],[x,y])
                               m           d m
                     [[x = - -----, y = - -----]]
                             d - m        d - m

Now let us compute the end of the blue line.
>x1 &= 1-2*(1-m/(m-1)); y1 &= m*(x1-1)
                                       m
                          - 2 m (1 - -----)
                                     m - 1

Now we can get a formula for the fraction of the total line of
our approximation for the slope d.
>&(m/(m-d)-x1)/(1-x1), function f(m,d) &= ratsimp(%)
                        m              m
                      ----- + 2 (1 - -----) - 1
                      m - d          m - 1
                      -------------------------
                                     m
                            2 (1 - -----)
                                   m - 1


                           - (d - 2) m - d
                           ---------------
                              2 m - 2 d

E.g., the fraction for the d=0.5 is 0.67, but should be 0.70.
>f(-1.2,0.5), 2^(-0.5)
0.676470588235
0.707106781187
Of course, for the octave (d=1), everything is OK.
>f(-1.2,1),
0.5
We compute the relative errors for m=-1.2.
>f(-1.2,d12)/2^(-d12)-1
[ 0  -0.0162128409521  -0.0281121289029  -0.0363321654288
-0.0413644185582  -0.043594125105  -0.0433261195711  -0.0408034134014
-0.0362207898765  -0.0297349054765  -0.0214718997475  -0.011533200105
0 ]
Let us compute the maximal absolute error.
>function map g(m) := max(abs(f(m,d12)/2^(-d12)-1))
And plot it over a range of m.
>plot2d("g",-10,-0.2); insimg;

Equal Tempered Scale by Strahle

There is a distinct minimum.
>mopt=fmin("g",-10,-0.2)
-2.41416056259
The error there looks very small.
>g(mopt)
0.00129116472778
From the following computation, we see that the maximal relative
error is about 2 cent. This is very good.
>log(1+g(mopt))/log(2^(1/12))
0.0223386650501
Note that the optimal m is very close to the exact value of -(1+sqrt(2)).
This gives an easy construction for the optimum. I will explain
below, why this value occurs.
>-(1+sqrt(2))
-2.41421356237
Finally, let us repeat the plot commands above, and compare the
exact and the apporimative fret grids.
>t=0:0.1:1; d12=(0:12)/12; plot2d(t,d12'*t,a=-0.2,b=1.2,c=-0.2,d=1.2); ...
>  m=mopt; x=m/(m-1); y=x; x1=1-2*(1-x); y1=m*(x1-1);  ...
>  plot2d([x1,1],[y1,0],color=4,add=1); ...
>  x=m/(m-d12); y=d12*x; plot2d(x,y,points=1,style="o",add=1); ...
>  xe=x1+(1-x1)/2^d12; ye=m*(xe-1);  ...
>  plot2d(xe,ye,points=1,style="[]",color=6,add=1); insimg;

Equal Tempered Scale by Strahle

The simple explanation for the optimal value of m is, that it
the value, which makes d=1/2 (the tritonus) exact.
>&solve(f(m,1/2)=1/sqrt(2),m), &rat(rhs(%[1]))|algebraic
                               sqrt(2) - 2
                         [m = -------------]
                              3 sqrt(2) - 4


                            - sqrt(2) - 1

As you see in the following plot, we get an almost alternant.
We have solved an approximation by interpolation.
>plot2d("f(-(1+sqrt(2)),x)-2^(-x)",0,1); insimg;

Equal Tempered Scale by Strahle

From the musical point of view, it would be better to make the
quint (d=7/12) exact. This leads to a simple fraction, if we take
the musical correct quint as 2/3.
>&solve(f(m,7/12)=2/3,m), &rat(rhs(%[1]))|algebraic
                                     7
                              [m = - -]
                                     3


                                   7
                                 - -
                                   3

Note that the pure quint and the equal tempered quint are very
close.
>2/3, 2^(-7/12)
0.666666666667
0.667419927085
The overall error of the fret positions gets larger, if we use
m=-7/3.
>plot2d("f(-7/3,x)-2^(-x)",0,1); insimg;

Equal Tempered Scale by Strahle

The maximal error is still only 4.5 cent, which is very small.
>log(1+g(-7/3))/log(2^(1/12))
0.0449620315388
The construction is then very easy. Just divide the hypotenuse
at 7/10 of its length.
>&solve(x=-7/3*(x-1),x)
                                    7
                               [x = --]
                                    10

Next, we plot a sketch, which is more in the spirit of David Strahle.


The basic mathematics is not changed, since the above solution
can be mapped to this sketch by an affine mapping. We devided
the side of the triangle 7:3 here.
>x0=0; y0=5; t=-1:2/12:1; ...
>plot2d(dup(x0,13)|t',dup(y0,13)|dup(0,13),a=-3,b=3,c=-0.5,d=5.5); ...
>x1=-7/10; y1=3/10*y0; x2=1-2*(1-x1); y2=2*y1; ...
>plot2d([1,x2],[0,y2],color=4,add=1); ...
>plot2d(x2+(1-x2)/2^d12,y2-y2/2^d12,points=1,style="x",color=6,add=1); ...
>plot2d(x2+(1-x2)/2^d12,y2-y2/2^d12,points=1,style="[]",color=6,add=1);  ...
>insimg(35);

Equal Tempered Scale by Strahle

We have added the correct positions here.

Using Continued Fractions

There is much simpler approximation, which comes from a continued
fraction.
>fracprint(contfracbest(2^(1/12),2))
18/17
Let us compare this to the Strähle construction.
>n=0:12; X=((2^(n/12)_f(m,1-n/12)*2_(18/17)^n)); X'
                  1                   1                   1 
      1.05946309436       1.06039942424       1.05882352941 
      1.12246204831       1.12389864513       1.12110726644 
        1.189207115       1.19074257728        1.1870547527 
      1.25992104989       1.26120263411       1.25688150286 
      1.33483985417       1.33558041128       1.33081570891 
      1.41421356237       1.41421200218        1.4090989859 
      1.49830707688       1.49747307558       1.49198716154 
      1.58740105197       1.58578487743       1.57975111222 
      1.68179283051       1.67962135893       1.67267764823 
      1.78179743628       1.77951768565       1.77107045107 
      1.88774862536       1.88608045021       1.87525106584 
                  2                   2       1.98555995207 
>plot2d(n,X[3]-X[1],a=0,b=12,c=-0.02,d=0.02,>points); ...
>plot2d(n,X[2]-X[1],>points,>add,color=red); insimg;

Equal Tempered Scale by Strahle

As expected, our optimal construction is a lot better.

But we can do better with the following continued fraction.
>fracprint(contfracbest(2^(1/12),3))
107/101
>n=0:12; X=((2^(n/12)_f(m,1-n/12)*2_(107/101)^n)); X'
                  1                   1                   1 
      1.05946309436       1.06039942424       1.05940594059 
      1.12246204831       1.12389864513       1.12234094697 
        1.189207115       1.19074257728       1.18901466659 
      1.25992104989       1.26120263411       1.25964920124 
      1.33483985417       1.33558041128       1.33447984685 
      1.41421356237       1.41421200218       1.41375587736 
      1.49830707688       1.49747307558       1.49774137503 
      1.58740105197       1.58578487743       1.58671611018 
      1.68179283051       1.67962135893       1.68097647316 
      1.78179743628       1.77951768565       1.78083646166 
      1.88774862536       1.88608045021       1.88662872671 
                  2                   2       1.99870568077 
>plot2d(n,X[3]-X[1],a=0,b=12,c=-0.02,d=0.02,>points); ...
>plot2d(n,X[2]-X[1],>points,>add,color=red); insimg;

Equal Tempered Scale by Strahle

Now the two methods are comparable.

Examples Homepage