aforren1 / replan-2finger

0 stars 0 forks source link

Adaptive method(s)? #7

Open aforren1 opened 6 years ago

aforren1 commented 6 years ago

The one I want to try is the accelerated stochastic approximation (Kesten 1958, found in Treutwein 1995), which takes the form:

value(n + 1) = value(n) - (c/(2 + m_shift)) * (correct - phi)

Each finger would get its own independent approximation. Things to work out:

aforren1 commented 6 years ago

So c will end up being a multiple of 1/60 (maybe 16/60, which is ~266 ms?), value[0] can be 0.5, phi is 0.5, , and I think that's it?

val = max((16 - (2 + m_shift))/60, 1/60).

  1. x[0] = 0.5
  2. x[1] = 0.5 - 16/60 * (correct - 0.5)
  3. x[2] = x[1] - 15/60 (correct - 0.5) ... n. x[n+1] = x[n] - val (correct - 0.5)
aforren1 commented 6 years ago

We can then terminate when m_shift exceeds some value, after a minimum number of trials have been completed?

aforren1 commented 6 years ago

Here's a demo. Note that rather than the (correct - 0.5), we just change the sign. The initial step size is a little lower too (8/60). We also introduced bounds (min of 100ms, max of 800ms).

import numpy as np

x = list()
sgn = list()
x.append(0.5)

val = input('Trial 1: ')
mod = -(8/60) * (1 if int(val) else -1)
sgn.append(np.sign(mod))
res = x[0] + mod
x.append(res)
print('Delta: ' + str(mod))
print('Value: ' + str(res))

val = input('Trial 2: ')
mod = -(7/60) * (1 if int(val) else -1)
sgn.append(np.sign(mod))
res = x[1] + mod
x.append(res)
print('Delta: ' + str(mod))
print('Value: ' + str(res))

m_shift = 0
if sgn[0] != sgn[1]:
    m_shift += 1

for i in range(20):
    val = input('Trial ' + str(i + 3) + ': ')
    xx = 1.0 if int(val) else -1.0
    sgn.append(-xx)
    if sgn[i + 2] != sgn[i + 1]:
        m_shift += 1
        print('Sign shift')
    tmp = max((8 - (2 + m_shift))/60, 1/60)
    mod = -tmp * xx
    res = x[i + 2] + mod
    res = max(res, 0.1) # keep from going below 0.1
    res = min(res, 0.8) # keep from going above 0.8
    print('Delta: ' + str(mod))
    print('Value: ' + str(res))
    x.append(res)
aforren1 commented 6 years ago

Maybe jumping by powers of two would work? Like going 16/60 -> 8/60 -> 4/60 -> 2/60 -> 1/60? Or is that too fast?

aforren1 commented 6 years ago

We'll start off with just allowing the adaptive method in the two-choice version. If "adaptive" is toggled in the settings, the trial table is used, but the switch times are calculated as above. We'll also need to make it obvious that the trial table wasn't totally respected.