# Difference between revisions of "Nowhere differentiable continuous function"

A WASSERMANN (talk | contribs) |
A WASSERMANN (talk | contribs) |
||

(5 intermediate revisions by the same user not shown) | |||

Line 1: | Line 1: | ||

− | This page shows the graph of the nowhere differentiable, but | + | 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> | :<math> f(x) = \sum_{k=1}^{N} a^k\cos(b^k\pi x), </math> | ||

− | where <math>0<a<1</math> and <math>ab>1+3/2\pi</math>. | + | where <math>0< a <1</math> and <math>ab>1+3/2\pi</math>. |

<jsxgraph width="500" height="500" box="box"> | <jsxgraph width="500" height="500" box="box"> | ||

(function(){ | (function(){ | ||

Line 44: | Line 44: | ||

</source> | </source> | ||

− | + | == Speed optimization == | |

<jsxgraph width="500" height="500" box="box2"> | <jsxgraph width="500" height="500" box="box2"> | ||

Line 53: | Line 53: | ||

var N = bd.create('slider', [[0.5,1.0],[2.5,1.0],[0,2,30]], {name:'N'}); | var N = bd.create('slider', [[0.5,1.0],[2.5,1.0],[0,2,30]], {name:'N'}); | ||

var f = function(x, suspendedUpdate){ | var f = function(x, suspendedUpdate){ | ||

− | var k, s=0.0 | + | var k, s=0.0; |

if (!suspendedUpdate) { | if (!suspendedUpdate) { | ||

− | n = N.Value(); | + | this.n = N.Value(); |

− | aa= a.Value(); | + | this.aa= a.Value(); |

− | bb = b.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<n; k++) { | + | for (k=1; k<this.n; k++) { |

− | s += | + | s += this.aArr[k]*Math.cos(this.bArr[k]*x); |

} | } | ||

return s; | return s; | ||

Line 68: | Line 74: | ||

</jsxgraph> | </jsxgraph> | ||

+ | 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. | ||

+ | <source lang="javascript"> | ||

+ | (function(){ | ||

+ | })(); | ||

+ | </source> | ||

+ | 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. | ||

+ | |||

+ | <source lang="javascript"> | ||

+ | (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}); | ||

+ | })(); | ||

+ | </source> | ||

[[Category:Examples]] | [[Category:Examples]] | ||

[[Category:Curves]] | [[Category:Curves]] |

## Latest revision as of 17:11, 14 January 2021

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\lt a \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});
})();
```