Nowhere differentiable continuous function: Difference between revisions
A WASSERMANN (talk | contribs) No edit summary |
A WASSERMANN (talk | contribs) No edit summary |
||
(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 15:11, 14 January 2021
This page shows the graph of the nowhere differentiable, but continuous function
- [math]\displaystyle{ f(x) = \sum_{k=1}^{N} a^k\cos(b^k\pi x), }[/math]
where [math]\displaystyle{ 0\lt a \lt 1 }[/math] and [math]\displaystyle{ ab\gt 1+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]\displaystyle{ aa^k }[/math] and [math]\displaystyle{ bb^k }[/math] are used many times. Since [math]\displaystyle{ aa }[/math] and [math]\displaystyle{ 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});
})();