Browse Source

approx exp, use for gaussian summation

Alexander Rose 4 years ago
parent
commit
09c46447d9
2 changed files with 25 additions and 2 deletions
  1. 22 0
      src/mol-math/approx.ts
  2. 3 2
      src/mol-math/geometry/gaussian-density/cpu.ts

+ 22 - 0
src/mol-math/approx.ts

@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ *
+ * adapted from https://gist.github.com/imbcmdth/6338194
+ * which is ported from https://code.google.com/archive/p/fastapprox/ (BSD licensed)
+ */
+
+const _a_fasterPow2 = new ArrayBuffer(4);
+const _i_fasterPow2 = new Int32Array(_a_fasterPow2);
+const _f_fasterPow2 = new Float32Array(_a_fasterPow2);
+
+export function fasterPow2(v: number) {
+    const clipNumber = (v < -126) ? -126 : v;
+    _i_fasterPow2[0] = ((1 << 23) * (clipNumber + 126.94269504));
+    return _f_fasterPow2[0];
+};
+
+export function fasterExp(v: number) {
+    return fasterPow2(1.442695040 * v);
+};

+ 3 - 2
src/mol-math/geometry/gaussian-density/cpu.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -10,6 +10,7 @@ import { RuntimeContext } from '../../../mol-task';
 import { PositionData, DensityData } from '../common';
 import { OrderedSet } from '../../../mol-data/int';
 import { GaussianDensityProps } from '../gaussian-density';
+import { fasterExp } from '../../approx';
 
 export async function GaussianDensityCPU(ctx: RuntimeContext, position: PositionData, box: Box3D, radius: (index: number) => number,  props: GaussianDensityProps): Promise<DensityData> {
     const { resolution, radiusOffset, smoothness } = props;
@@ -96,7 +97,7 @@ export async function GaussianDensityCPU(ctx: RuntimeContext, position: Position
                         const dz = gridz[zi] - vz;
                         const dSq = dxySq + dz * dz;
                         if (dSq <= r2sq) {
-                            const dens = Math.exp(-alpha * (dSq * rSqInv));
+                            const dens = fasterExp(-alpha * (dSq * rSqInv));
                             const idx = zi + xyIdx;
                             data[idx] += dens;
                             if (dens > densData[idx]) {