📄 diffuser.java
字号:
package sim.app.antsforage;import sim.engine.*;import sim.field.grid.*;public /*strictfp*/ class Diffuser implements Steppable { DoubleGrid2D updateGrid; DoubleGrid2D tempGrid; double evaporationRate; double diffusionRate; public Diffuser( final DoubleGrid2D updateGrid, final DoubleGrid2D tempGrid, final double evaporationRate, final double diffusionRate ) { this.updateGrid = updateGrid; this.tempGrid = tempGrid; this.evaporationRate = evaporationRate; this.diffusionRate = diffusionRate; } public void step(SimState state) { // stolen from HeatBugs and modified for our own purposes // locals are faster than instance variables final DoubleGrid2D _valgrid = updateGrid; final double[][] _valgrid_field = updateGrid.field; final double[][] _valgrid2_field = tempGrid.field; final int _gridWidth = _valgrid.getWidth(); final int _gridHeight = _valgrid.getHeight(); final double _evaporationRate = evaporationRate; final double _diffusionRate = diffusionRate; double average; double[] _past = _valgrid_field[_valgrid.stx(-1)]; double[] _current = _valgrid_field[0]; double[] _next; double[] _put; int yminus1; int yplus1; // for each x and y position for(int x=0;x< _gridWidth;x++) { _next = _valgrid_field[_valgrid.stx(x+1)]; _put = _valgrid2_field[_valgrid.stx(x)]; yminus1 = _valgrid.sty(-1); // initialized for(int y=0;y< _gridHeight;y++) { // for each neighbor of that position // go across top yplus1 = _valgrid.sty(y+1); average = (_past[yminus1] + _past[y] + _past[yplus1] + _current[yminus1] + _current[y] + _current[yplus1] + _next[yminus1] + _next[y] + _next[yplus1]) / 9.0; // load the new value into HeatBugs.this.valgrid2 _put[y] = (1.0-_evaporationRate) * (_current[y] + _diffusionRate * (average - _current[y])); // set y-1 to what y was "last time around" yminus1 = y; } // swap elements _past = _current; _current = _next; } // ---------------------------------------------------------------------- // If you have a multiprocessor machine, you can speed this up further by // dividing the work among two processors. We do that over in ThreadedDiffuser.java // // You can also avoid some of the array bounds checks by using linearized // double arrays -- that is, using a single array but computing the double // array location yourself. That way you only have one bounds check instead // of two. This is how, for example, Repast does it. This is certainly a // little faster than two checks. We use a two-dimensional array because a // linearized array class is just too cumbersome to use in Java right now, // what with all the get(x,y) and set(x,y,v) instead of just saying foo[x][y]. // Plus it turns out that for SMALL (say 100x100) arrays, the double array is // actually *faster* because of cache advantages. // // At some point in the future Java's going to have to fix the lack of true // multidimensional arrays. It's a significant speed loss. IBM has some proposals // in the works but it's taking time. However their proposals are for array classes. // So allow me to suggest how we can do a little syntactic sugar to make that prettier. // The array syntax for multidimensional arrays should be foo[x,y,z] and for // standard Java arrays it should be foo[x][y][z]. This allows us to mix the two: // a multidimensional array of Java arrays for example: foo[x,y][z]. Further we // should be allowed to linearize a multidimensional array, accessing all the elements // in row-major order. The syntax for a linearized array simply has empty commas: // foo[x,,] // oh yeah, we have one last step. // now finally copy HeatBugs.this.valgrid2 to HeatBugs.this.valgrid, and we're done _valgrid.setTo(tempGrid); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -