Skip to content

BUG: Student's T spatial kernel strength increases with distance instead of decreasing #591

@andrewkern

Description

@andrewkern

description

The scalar tdist() function in SpatialKernel has an incorrect sign in the exponent, causing interaction strength to increase with distance instead of decrease.

expected behavior

Student's T kernel strength should decay with distance:
strength = fmax * pow(1 + (d/\tau)²/\nu, -(\nu+1)/2)
At distance 0.5 with fmax=5, \nu=3, \tau=0.5: strength should be 2.8125

current behavior

Strength increases with distance due to double-negative in exponent:

  // spatial_kernel.h:77
  return max / pow(base, -(nu + 1.0) / 2.0);  // equals max * pow(base, (nu+1)/2)

At distance 0.5: strength is 8.889 (exceeds fmax!)

to reproduce

  Reproduction:
  initialize() {
    initializeSLiMOptions(dimensionality='x');
    initializeInteractionType('i1', 'x', maxDistance=2.0);
  }
  1 early() { sim.addSubpop('p1', 2); }
  1 late() {
    p1.individuals[0].x = 0.0;
    p1.individuals[1].x = 0.5;
    i1.setInteractionFunction('t', 5.0, 3.0, 0.5);  // fmax=5, nu=3, tau=0.5
    i1.evaluate(p1);
    catn("strength at d=0.5: " + i1.strength(p1.individuals[0], p1.individuals[1]));
    catn("fmax: 5.0");
    // Output: strength=8.889 > fmax
  }

cause:

In core/spatial_kernel.h:77:

  return max / pow(base, -(nu + 1.0) / 2.0);

Dividing by pow(x, -n) equals multiplying by pow(x, n), so the negative exponent is cancelled out.

fix:

Change to either:

  • return max * pow(base, -(nu + 1.0) / 2.0); or
  • return max / pow(base, (nu + 1.0) / 2.0);

I will issue this patch in a subsequent PR @bhaller

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions