Skip to content

Commit

Permalink
#330: add sigmoid and delayed sigmoid function options to continuous …
Browse files Browse the repository at this point in the history
…variable system
  • Loading branch information
Wolkenfarmer committed Sep 16, 2024
1 parent 3680da1 commit 4a741f1
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
5 changes: 5 additions & 0 deletions backend/dps_training_k/data/continuous_variables_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ def update_or_create_continuous_variables():
"materials": [str(MaterialIDs.EKG)],
"function": ContinuousVariable.Function.INCREMENT,
},
{
"actions": [str(ActionIDs.IV_ZUGANG)],
"materials": [],
"function": ContinuousVariable.Function.SIGMOID,
},
],
},
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.1 on 2024-09-16 12:51

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('template', '0011_continuousvariable'),
]

operations = [
migrations.AlterField(
model_name='continuousvariable',
name='function',
field=models.CharField(choices=[('linear', 'Linear'), ('sigmoid', 'Sigmoid'), ('delayed sigmoid', 'Sigmoid Delayed'), ('increment', 'Increment'), ('decrement', 'Decrement')]),
),
]
2 changes: 2 additions & 0 deletions backend/dps_training_k/template/models/continuous_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class Variable(models.TextChoices):

class Function(models.TextChoices):
LINEAR = "linear"
SIGMOID = ("sigmoid",)
SIGMOID_DELAYED = ("delayed sigmoid",)
INCREMENT = "increment"
DECREMENT = "decrement"

Expand Down
60 changes: 60 additions & 0 deletions frontend/src/stores/ContinuousVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export const useContinuousVariablesStore = defineStore('patientContinuous', {
switch (variable.function) {
case ContinuousFunctionName.LINEAR:
return variable.xCurrent + linear(variable, this.timeUntilPhaseChange)
case ContinuousFunctionName.SIGMOID:
// console.log("Calculate sigmoid: " + (variable.xCurrent + sigmoid(variable, this.timeUntilPhaseChange)) + "; Time until phase" +
// " change: " + this.timeUntilPhaseChange)
return variable.xCurrent + sigmoid(variable, this.timeUntilPhaseChange)
case ContinuousFunctionName.SIGMOID_DELAYED:
return variable.xCurrent + sigmoid_delayed(variable, this.timeUntilPhaseChange)
case ContinuousFunctionName.INCREMENT:
return variable.xCurrent + 1
case ContinuousFunctionName.DECREMENT:
Expand Down Expand Up @@ -106,3 +112,57 @@ export function startContinuousLogic() {
function linear(variable: ContinuousVariableInternal, timeUntilPhaseChange: number) {
return ((variable.xTarget - variable.xCurrent) / timeUntilPhaseChange)
}

function sigmoid(variable: ContinuousVariableInternal, timeUntilPhaseChange: number): number {
// higher value = steeper; higher -> lower infinTargetCorrection
const steepness = 10
// magic value (try & error for steepness 10/20) needed for correction as the target height is only reached -> infin
const infinTargetCorrection = 3.5

const t = variable.tDelta - timeUntilPhaseChange
const tMid = variable.tDelta / 2

const tStretchFactor = 1 / ((Math.pow(variable.tDelta, 2)) / Math.pow(steepness, 2))
const tStretchCorrectorNormalizer = Math.atan(Math.sqrt(1) * variable.tDelta) / Math.sqrt(1)
const tStretchCorrector = (Math.atan(Math.sqrt(tStretchFactor) * variable.tDelta) / Math.sqrt(tStretchFactor)) / tStretchCorrectorNormalizer

// original height of atanDerivative fun, - infinTargetCorrection scaled with t_delta
const pi = Math.PI - (infinTargetCorrection / variable.tDelta)
const xDelta = variable.xTarget - variable.xStart
const xStretcher = xDelta / pi

const atanDerivative = (1 / (Math.pow(t - tMid, 2) * tStretchFactor + 1))

return atanDerivative * xStretcher / tStretchCorrector
}

function sigmoid_delayed(variable: ContinuousVariableInternal, timeUntilPhaseChange: number): number {
// higher value = steeper; higher -> lower infinTargetCorrection
const steepness = 10
// magic value (try & error for steepness 10/20) needed for correction as the target height is only reached -> infin
const infinTargetCorrection = 3.5

const t = variable.tDelta - timeUntilPhaseChange
const tMid = variable.tDelta / 2

const tShiftFrac = 3
const t0Shifted = variable.tDelta / tShiftFrac // Time when sigmoid starts (shifted by one tShiftFrac)
const tDeltaShifted = variable.tDelta - t0Shifted
const tShiftedMid = tMid + (variable.tDelta - tMid) / tShiftFrac // Shifted midpoint

const tStretchFactor = 1 / ((Math.pow(tDeltaShifted, 2)) / Math.pow(steepness, 2))
const tStretchCorrectorNormalizer = Math.atan(Math.sqrt(1) * variable.tDelta) / Math.sqrt(1)
const tStretchCorrector = (Math.atan(Math.sqrt(tStretchFactor) * variable.tDelta) / Math.sqrt(tStretchFactor)) / tStretchCorrectorNormalizer

// original height of atanDerivative fun, - infinTargetCorrection scaled with t_delta
const pi = Math.PI - (infinTargetCorrection / tDeltaShifted)
const xDelta = variable.xTarget - variable.xStart
const xStretcher = xDelta / pi

const atanDerivative = (1 / (Math.pow(t - tShiftedMid, 2) * tStretchFactor + 1))

if (t < t0Shifted) {
console.log("straight")
return 0
} else return atanDerivative * xStretcher / tStretchCorrector
}

0 comments on commit 4a741f1

Please sign in to comment.