Created
August 6, 2012 15:14
-
-
Save jacksonhenry3/3275332 to your computer and use it in GitHub Desktop.
javascript fft (from http://home.fuse.net/clymer/graphs/fourier.html)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
<html> | |
<head> | |
<meta http-equiv="content-type" | |
content="text/html; charset=ISO-8859-1"> | |
<title>Fourier Transform in JavaScript</title> | |
<meta name="keywords" | |
content="graph, graphs, graphing, JavaScript, DHTML, Clymer, function, functions, Fourier, Fourier transform, FFT"> | |
<style type="text/css" media="screen"></style> | |
</head> | |
<body> | |
<div id="gbox" | |
style="border: 1px solid black; position: absolute; top: 10px; left: 10px; width: 514px; height: 202px; background-color: rgb(255, 255, 187);"> | |
<font size="-2"> Function to be transformed</font></div> | |
<div id="fbox" | |
style="border: 1px solid black; position: absolute; top: 220px; left: 10px; width: 514px; height: 202px; background-color: rgb(255, 255, 187);"> | |
<font size="-2"> Fourier Transform</font></div> | |
<div id="formbox" | |
style="background-color: rgb(255, 255, 255); position: absolute; top: 10px; left: 530px; width: 270px; height: 541px; visibility: visible;"> | |
<form method="get" name="f"> | |
<p>Function<br> | |
<input name="func" value="sin(8*x)" size="40" tabindex="1" type="text" | |
border="0"></p> | |
<p><input name="xmin" value="0.0" size="10" tabindex="2" type="text" | |
border="0"> <label>x min</label><br> | |
<input name="xmax" value="+6.283" size="10" tabindex="3" type="text" | |
border="0"> <label>x max</label><br> | |
<input name="ymin" value="-1.5" size="10" tabindex="4" type="text" | |
border="0"> <label> y min</label><br> | |
<input name="ymax" value="+1.5" size="10" tabindex="5" type="text" | |
border="0"> <label>y max</label></p> | |
<p> <input name="replotbutton" value=" Replot! " | |
tabindex="6" onclick="replot()" type="button" border="0"></p> | |
<p><br> | |
</p> | |
<p> <input name="fftButton" value=" FFT! " | |
tabindex="7" onclick="fft()" type="button" border="0"></p> | |
<p><input name="numax" readonly="readonly" size="10" tabindex="12" | |
type="text" border="0"> <label>ν max</label><br> | |
<input name="omega" readonly="readonly" size="10" tabindex="13" | |
type="text" border="0"> <label>ω max</label></p> | |
<p><input name="Fmax" size="10" tabindex="8" type="text" border="0"> <label>F | |
max</label></p> | |
<p> <input name="replot2but" value=" Replot! " | |
tabindex="9" onclick="replot2()" type="button" border="0"></p> | |
<p><textarea name="exportfield" rows="20" cols="38" | |
readonly="readonly" tabindex="11" wrap="off"></textarea></p> | |
</form> | |
</div> | |
<script type="text/javascript"> | |
var screenx=512, screeny=200, offset=10, x; | |
var yr = new Array(512); yi = new Array(512); | |
var n=1024, g=10, p=2*Math.PI/n, g1, l, m, k, k1, k2, k3; | |
var y1, y2, j; | |
var dend = "px; position:absolute; top:1px; width:2px; height:2px; font-size=1; background-color:#0000ff\'></div>" | |
var fend = "px; position:absolute; top:1px; width:1px; height:2px; font-size=1; background-color:#0000ff\'></div>" | |
for (var i=1; i<=screenx; i++) { | |
x=i + offset; | |
document.write("<div id=\'d"+i+"\' style=\' left:"+x+dend); | |
document.write("<div id=\'f"+i+"\' style=\' left:"+x+fend); | |
} | |
replot(); | |
fft(); | |
function replot() { | |
var xmin=1 * document.f.xmin.value; | |
var xmax=1 * document.f.xmax.value; | |
var ymin=1 * document.f.ymin.value; | |
var ymax=1 * document.f.ymax.value; | |
if (ymin==ymax) { ymin=-Math.abs(ymin); ymax=Math.abs(ymax); | |
document.f.ymin.value = ymin; | |
document.f.ymax.value = ymax; } | |
if (xmin==xmax) { xmin=-Math.abs(xmin); xmax=Math.abs(xmax); | |
document.f.xmin.value = xmin; | |
document.f.xmax.value = xmax; } | |
var func=document.f.func.value; | |
var xf=(xmax-xmin)/screenx, yf=screeny/(ymax-ymin); | |
var y, x1, y1, obj, ptr; | |
var scry = screeny + offset; | |
with (Math) { | |
for (var i=1; i<=screenx; i++) { | |
x = i*xf + xmin; | |
y =eval(func); | |
if (y>ymax) y=ymax; | |
if (y<ymin) y=ymin; | |
y1=scry-(y-ymin)*yf; | |
ptr = "d"+i; | |
obj = document.getElementById(ptr); | |
obj.style.top = y1; | |
} } } | |
function fft() { | |
var func=document.f.func.value; | |
var xmin=1 * document.f.xmin.value; | |
var xmax=1 * document.f.xmax.value; | |
var xf=(xmax-xmin)/n, mg1; | |
with (Math) { | |
for (var i=1; i<=n; i++) { | |
x = i*xf + xmin; | |
y =eval(func); | |
yr[i]=y; yi[i]=0; | |
} } | |
with (Math) { | |
for (l=0; l<=(g-1); l++) { | |
g1 = pow(2,(g-l-1)); | |
m=0; | |
for (i=1; i<=pow(2,l); i++) { | |
k1=floor(m/g1); | |
kaylyn(); | |
y1=cos(p*k2); | |
y2=-sin(p*k2); | |
for (j=1; j<=g1; j++) { | |
m=m+1; | |
mg1=m+g1; | |
y3=yr[mg1]*y1-yi[mg1]*y2; | |
y4=yr[mg1]*y2+yi[mg1]*y1; | |
yr[mg1]=yr[m]-y3; | |
yi[mg1]=yi[m]-y4; | |
yr[m]=yr[m]+y3; | |
yi[m]=yi[m]+y4; | |
} | |
m = m + g1; | |
} } | |
for (i=0; i<=(n-1); i++) { | |
k1 = i; | |
kaylyn(); | |
if (k2>=i) continue; | |
k3 = yr[i+1]; | |
yr[i+1] = yr[k2+1]; | |
yr[k2+1] = k3; | |
k3 = yi[i+1]; | |
yi[i+1] = yi[k2+1]; | |
yi[k2+1] = k3; | |
} | |
var ymax=0; | |
for (i=1; i<=n/2; i++) { | |
yr[i] = Math.sqrt((yr[i]*yr[i] + yi[i]*yi[i]))*2/n; | |
ymax=max(yr[i], ymax); | |
} | |
yr[1] = yr[1]/2; | |
var ymaxstr = Math.ceil(ymax*1.1*100)/100; | |
document.f.Fmax.value = ymaxstr.toString(); | |
replot2(); | |
export1(); | |
} } | |
function kaylyn() { | |
k2=0; | |
for (k=1; k<=g; k++) { | |
k3=Math.floor(k1/2); | |
k2=2*(k2-k3) + k1; | |
k1=k3; | |
} | |
} | |
function replot2() { | |
var xmin = 1 * document.f.xmin.value; | |
var xmax = 1 * document.f.xmax.value; | |
var ymin=0; | |
var ymax=1 * document.f.Fmax.value; | |
var numax = n/2/(xmax-xmin); | |
var omega = numax*2*Math.PI; | |
var numaxstr = Math.round(numax*10)/10; | |
document.f.numax.value = numaxstr.toString(); | |
var omegastr = Math.round(omega*10)/10; | |
document.f.omega.value = omegastr.toString(); | |
var yf=screeny/(ymax-ymin); | |
var y, x1, y1, obj, ptr; | |
var yoff = 220+screeny; | |
with (Math) { | |
for (var i=1; i<=n/2; i++) { | |
y = yr[i]; | |
if (y>ymax) y=ymax; | |
if (y<ymin) y=ymin; | |
y1=round(yoff-(y-ymin)*yf); | |
ptr="f"+i; | |
obj=document.getElementById(ptr); | |
obj.style.top=y1; | |
obj.style.height=yoff-y1+1; | |
} } } | |
function export1() { | |
var longstr=""; | |
for (var i=1; i<=n/2; i++) { | |
longstr += i-1 + ", " + yr[i] + "\n"; | |
} | |
document.f.exportfield.value = longstr; | |
} | |
</script> | |
<div id="layer1" | |
style="border: 0px solid black; position: absolute; top: 440px; left: 10px; width: 514px; height: 202px; background-color: rgb(255, 255, 255);"> | |
<p>This page demonstrates the use of JavaScript to perform Fourier | |
Transforms, and DHTML to produce graphs of functions. Enter a function | |
in terms of x in the top box. Enter minimum and maximum values for x | |
and y in the next four boxes. Then, hit the Replot! button. If you make | |
a mistake in entering a formula, use the Refresh feature of your | |
browser.</p> | |
<p>Functions available in JavaScript are abs(x), acos(x), asin(x), | |
atan(x), ceil(x), cos(x), exp(x), floor(x), log(x), max(x,n), min(x,n), | |
pow(x,n), random(), round(x), sin(x), sqrt(x) and tan(x).</p> | |
<p>Once a function is displayed, a Fourier Transform can be performed | |
by pressing the FFT! button. Although only 512 points are shown in the | |
upper grapph, a Fast Fourier Transform is calculated on 1024 points | |
from the entered function. So the Nyquist frequency for the FT is twice | |
the apparent Nyquist frequency for the upper plot. Each of the | |
resulting 512 real and imaginary FT points are squared and added | |
together to produce a power spectrum. The maximum frequency, ν, and | |
angular freqency, ω (=2πν), are displayed as determined | |
from the maximum and mininum x values. The individual data points of | |
the power spectrum are also listed in the lower text box. The vertical | |
axis of the Fourier transform can be magnified by changing the value of | |
Fmax and hitting the lower Replot! button.</p> | |
<p>Here's a good <a | |
href="http://www.cage.curtin.edu.au/mechanical/info/vibrations/tut4.htm">tutorial | |
on | |
Fourier | |
transforms</a>.</p> | |
And one from <a href="http://www.colby.edu/chemistry/NMR/NMR.html">Colby | |
College</a>. | |
<p>Here are some interesting functions on which to perform Fourier | |
transforms:</p> | |
<ul> | |
<li><i>sine wave</i>: sin(128*x) </li> | |
<li><i>two sine waves</i>: sin(100*x)+2*sin(150*x) </li> | |
<li><i>modulated sine wave</i>: sin(140*x)*sin(20*x) </li> | |
<li><i>modulated sine wave</i>: sin(100*x)*sin(120*x) </li> | |
<li><i>sine wave exponentially damped</i>: sin(128*x)*exp(-2*x) </li> | |
<li><i>square wave</i>: (sin(32*x)>0)?1:-1 </li> | |
<li><i>sine wave pulse</i>: (x<0.2)?sin(128*x):0 </li> | |
<li><i>sine of x-squared</i>: sin(4*x*x) </li> | |
<li><i>sine wave log multiplied</i>: sin(100*x)*log(x) </li> | |
<li><i>sinc function</i>: sin(100*x)/(100*x) </li> | |
<li><i>sine of an exponential</i>: sin(exp(x)) </li> | |
<li><i>sine squared</i>: sin(x)*sin(x)-0.5</li> | |
<li><span style="font-style: italic;">multiple pulse</span>: | |
sin(200*x)*(exp(-20*(x-1)*(x-1))+exp(-20*(x-3)*(x-3))+exp(-20*(x-5)*(x-5)))</li> | |
</ul> | |
<p>For the following use, a whole number, such as 8, for x max.</p> | |
<ul> | |
<li><i>square pulse</i>: (x<0.1)?1:0 </li> | |
<li><i>sawtooth</i>: 2*x%1-0.5 </li> | |
<li><i>triangle</i>: (8*x%2<1)?8*x%1-0.5:0.5-(8*x%1) </li> | |
<li><i>gaussian</i>: exp(-(x-4)*(x-4)*1000) </li> | |
</ul> | |
<hr> | |
<p><font size="-1"><a href="http://home.cincyarts.org">Other pages</a> | |
by the author. <a href="mailto:jclymer@fuse.net">Email</a>.<br> | |
</font><font size="-1">Debut: December 26, 2003. Revision No. 7. <csobj | |
format="LongDate" h="16" region="0" t="DateTime" w="169">August 23, | |
2006</csobj> | |
</font>Visitors:<!-- Start of StatCounter Code --> | |
<script type="text/javascript" language="javascript"> | |
var sc_project=497377; | |
var sc_partition=3; | |
</script> | |
<script type="text/javascript" language="javascript" | |
src="http://www.statcounter.com/counter/counter.js"></script><noscript><a | |
href="http://www.statcounter.com/" | |
target="_blank"><img | |
src="http://c4.statcounter.com/counter.php?sc_project=497377&java=0" | |
alt="free hit counter script" border="0"></a> </noscript><!-- End of StatCounter Code --></p> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment