简体   繁体   English

我写了一个简单的粒子过滤器,它不能用于数百个以上的粒子。 我不知道为什么

[英]I wrote a simple particle filter and it won't work with more than a few hundred particles. I can't tell why

I have written a very simple 1d particle filter using javascript and a HTML5 canvas. 我使用javascript和HTML5画布编写了一个非常简单的一维粒子过滤器。 It seems to work pretty well until the number of particles hits 283. I am not all that experienced with either particle filters or javascript, but I cannot see why 283 is the magic number! 在粒子数达到283之前,它似乎工作得很好。我对粒子过滤器或javascript的了解还不是全部,但我看不出为什么283是神奇的数字! Please could someone help? 请有人帮忙吗?

Edit: 编辑:

OK, so it seems the magic number isn't fixed between browsers, but if I set nparticles = 1000 it complains TypeError: particles[count] is undefined and I don't know why that should be the case. 好的,所以魔术数字似乎在浏览器之间不是固定的,但是如果我将nparticles = 1000设置nparticles = 1000则会抱怨TypeError: particles[count] is undefined ,我不知道为什么会这样。 Any tips would be gratefully received. 任何提示将不胜感激。

 var c; var ctx; var start_x = 600; var x_speed = 2; var dt = 1; var nparticles = 282; var gauss_dist; var particles = []; function getRandomArbitrary(min, max) { return Math.random() * (max - min) + min; } function drawBackground() { ctx.clearRect(0, 0, c.width, c.height); ctx.fillStyle="#FFFFFF"; ctx.fillRect(0,0,800,400); ctx.fillStyle="#00FF00"; ctx.fillRect(0,350,800,50); ctx.fillStyle="#FF0000"; ctx.fillRect(50,300,5,50); ctx.fillRect(750,300,5,50); } function drawRobot() { ctx.fillStyle="#000000"; start_x += x_speed*dt; if (start_x >= 750 || start_x <= 50) { x_speed *= -1; } ctx.fillRect(start_x, 300, 10, 50); } function getDistanceToNearest(x) { var to_far =Math.abs(x - 750); var to_near = Math.abs(x - 50); var true_dist; if (to_far > to_near) { true_dist = to_near; } else { true_dist = to_far; } true_dist = true_dist - 25 + 50.0*(Math.random()+Math.random()+Math.random()+Math.random()+Math.random()+Math.random()) / 3.0; return true_dist; } function w_gauss(a, b) { error = a - b; g = Math.exp(-((error *error) / (2 * 50.*50.))); return g; } function loop() { var i = 0; drawBackground(); drawRobot(); for (i=0; i < nparticles; i++) { ctx.fillStyle="#0000FF"; ctx.fillRect(particles[i].x, 345, 2,2); } var u = getDistanceToNearest(start_x); var weights = []; var wsum = 0.0; for (i=0; i < nparticles; i++) { var distance = getDistanceToNearest(particles[i].x); var w = w_gauss(u, distance); // console.log(""+w); weights.push(w); wsum += w; } //console.log("Wsum = "+wsum); var weights_norm = []; var trimmed_particles = []; for (i=0; i < nparticles; i++) { var w_norm = weights[i] / wsum; if (w_norm > 0.0001) { weights_norm.push(w_norm); trimmed_particles.push(particles[i]); // console.log(""+w_norm); } } particles = []; for (i=0; i< trimmed_particles.length; i++) { particles.push(trimmed_particles[i]); } //particles = trimmed_particles; console.log("Number of particles remaining = " + weights_norm.length + " " + particles.length); var cummul = [weights_norm[0]]; for (i=1; i < weights_norm.length; i++) { cummul.push(cummul[i-1]+weights_norm[i]); // console.log(""+cummul[i]); } /* for (i=0; i<particles.length; i++) { console.log(particles[i]); } */ // console.log("Beginning Resampling"); var resample = []; for (i = 0; i < nparticles; i++) { var rand = Math.random(); var count = 0; while(cummul[count]<=rand /*&& count < cummul.length*/) { count += 1; } //console.log("Count: "+count+ "Trimmed Particles: "+ particles.length); //console.log("Cumulative frequency: "+cummul[count]); //console.log(particles[count]); //console.log("x "+particles[count].x+" y "+particles[count].y+" weight "+weights_norm[count]); resample.push({"x":particles[count].x + (x_speed+ getRandomArbitrary(-0.5,0.5))*dt, "y":particles[count].y, "weight":weights_norm[count]}); } for (i=0; i < resample.length; i++) { particles[i] = resample[i]; } //particles = resample; } function init() { c=document.getElementById("theCanvas"); ctx = c.getContext("2d"); //gauss_dist = gaussian(50, 50); // Take a random sample using inverse transform sampling method. //setup initial particle sample for (i=0; i < nparticles; i++) { rand_x = getRandomArbitrary(50, 750); particle = {"x": rand_x, "y": 345.0, "weight":1.0/100.0}; particles.push(particle); rand_y = 345; } ctx=c.getContext("2d"); drawBackground(); setInterval(loop, 500); } init(); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <html> <body> <canvas id="theCanvas" width="800" height="400" style="border:2px solid #FFFFFF;"> </canvas> </body> </html> 

In the function loop the variable count gets larger than the length of the array particles . 在函数loop ,变量count变得大于数组particles的长度。 If I change the line 如果我换线

while(cummul[count]<=rand)

to

while(cummul[count]<=rand && count < particles.length-1)

I can raise nparticles without error. 我可以nparticles举起nparticles

You need to check the array boundaries more often. 您需要更频繁地检查数组边界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM