gpujs / gpu.js

GPU Accelerated JavaScript
https://gpu.rocks
MIT License
15.08k stars 650 forks source link

Math.pow(-1.5, k) = NaN for k = 1 #692

Open AstroMichael opened 3 years ago

AstroMichael commented 3 years ago

What is wrong?

When I use a for loop's index as a power for Math.pow(), for all negative values the result is NaN except for the following values: 0, 2, 3, 4.

Where does it happen?

This happens in Typescript (local development environment) as well as its minified JS version (run on a server). I installed GPU via npm install gpu.js.

How do we replicate the issue?

This is an example code that shows when this happens:

gpuTest(): void {
      const a = [-1, -2, 1.5, -1.5, 2, -1.1];
      const gpu = new GPU();
      const powTest = gpu.createKernel(function(a) {

          let sum = 0;
          for (let k = 1; k <= 1; k++) {
              sum += Math.pow(a[this.thread.x], k);
          }
          return sum;

      }).setOutput([a.length]);
      const out = powTest(a);
      console.log(a, out);
}

This results in the following output: grafik

However, when I use sum += Math.pow(a[this.thread.x], 1); all is well and the result no longer is NaN. That also applies to all the other powers. As soon as they are used as a fixed number, all is ok. Additionally, when a define const power = 1; and use that as input in Math.pow(), all is well, too.

Another thing I noticed is that Math.sign() of all negative numbers is 0. Should it not be -1?

How important is this (1-5)?

5, because according to the documentation, these things should work?

Expected behavior (i.e. solution)

I would have expected for the output to not result in NaN, and for Math.sign() to be -1 for negative numbers.

Other Comments

This is my first use of gpu.js, so I am not certain that I did everything right. I'd like to use it to speed up the computation of a function of the following form:

sum = initialValue;
for (let i = 0; i < order; i++) {
    for (let j = 0; j < order; j++) {
        sum += Math.pow(x, i) * Math.pow(y, j) * a[i][j]
    }
}

initialValue, x, and y are arrays of identical length and I thought I'd use thread.x on them. Any advice on how gpu.js would be optimally used in that case?

Finally: many thanks for creating gpu.js!