Nowhere differentiable continuous function

From JSXGraph Wiki
Jump to: navigation, search

This page shows the graph of the nowhere differentiable, but continuous function

[math] f(x) = \sum_{k=1}^{N} a^k\cos(b^k\pi x), [/math]

where [math]0\lta\lt1[/math] and [math]ab\gt1+3/2\pi[/math].

Reference

Wei-Chi Yang, "Technology has shaped up mathematics comunities", Proceedings of the Sixteenth Asian Technology Conference in Mathmatics (ATCM 16), pp 81-96.

The underlying JavaScript code

 var bd = JXG.JSXGraph.initBoard('box', {axis:true, boundingbox: [-5, 3, 5, -3]});
 var a = bd.create('slider', [[0.5,2],[2.5,2],[0,0.3,1]], {name:'a'});
 var b = bd.create('slider', [[0.5,1.5],[2.5,1.5],[0,20,100]], {name:'b'}); 
 var N = bd.create('slider', [[0.5,1.0],[2.5,1.0],[0,2,30]], {name:'N'}); 
 var f = function(x){
            var k, s=0.0, n = N.Value(), aa= a.Value(), bb = b.Value(); 
            for (k=1; k<n; k++) {
                s += Math.pow(aa,k)*Math.cos(Math.pow(bb,k)*Math.PI*x);
            }
            return s;
         };
 var c = bd.create('functiongraph', [f], {
                    doAdvancedPlot:false, 
                    numberPointsHigh:15000, numberPointsLow:1000, 
                    strokeWidth:1});

Speed optimization

This is a speed optimized version of the above JSXGraph construction. First, the code is wrapped into an anonymous function which is executed at once.

(function(){
})();

The only reason to do this is to avoid global variables. Otherwise, these variables would interfere with the variables of the same name in the above construction.

In order to optimize the execution speed the second parameter "suspendedUpdate" of the function is used. This parameter is set true in the first call of the function during an update of the board. Since in each update the function is called several thousand times it is useful to compute values that do not change during the update only once. In the above case, in each call of the function the powers [math]aa^k[/math] and [math]bb^k[/math] are used many times. Since [math]aa[/math] and [math]bb[/math] do not change during a single update, we can precompute these values and store them.

(function(){
 var bd = JXG.JSXGraph.initBoard('box2', {axis:true, boundingbox: [-5, 3, 5, -3]});
 var a = bd.create('slider', [[0.5,2],[2.5,2],[0,0.3,1]], {name:'a'});
 var b = bd.create('slider', [[0.5,1.5],[2.5,1.5],[0,20,100]], {name:'b'}); 
 var N = bd.create('slider', [[0.5,1.0],[2.5,1.0],[0,2,30]], {name:'N'}); 
 var f = function(x, suspendedUpdate){
            var k, s=0.0;
            if (!suspendedUpdate) {
                this.n = N.Value();
                this.aa= a.Value();
                this.bb = b.Value();
                this.aArr = [1.0];
                this.bArr = [1.0*Math.PI];
                for (k=1; k<this.n; k++) {
                  this.aArr[k] = this.aArr[k-1]*this.aa;
                  this.bArr[k] = this.bArr[k-1]*this.bb;
                }     
            }
            for (k=1; k<this.n; k++) {
                s += this.aArr[k]*Math.cos(this.bArr[k]*x);
            }
            return s;
         };
 var c = bd.create('functiongraph', [f], {doAdvancedPlot:false, numberPointsHigh:6000, numberPointsLow:500, strokeWidth:1});
})();