Berkeley Madonna Notes


These are my notes. Feel free to use them. No warranty whatsoever.

Andreas Krause


Single dose, bolus

The pulse function can be used to add bolus doses:

pulse(volume, first time of administration, repeat interval length)


For example, pulse (100, 0, 24) adds a dose of 100 every 24 time units.


To administer a limited number of doses, for example just one, all doses that follow after the first can be neutralized by deducting the same value at the same times (ad infinitum).


Putting it together, to give a single dose of 100 into the compartment “depot”, where “depot” has an absorption rate of ka, the change of the amount of drug in compartment “depot” is given as


d/dt (depot) = -ka * depot + pulse(dose, 0, 24) - pulse(dose, 24, 24)

Single dose, infusion

An infusion is administered by specifying the rate. The infusion is stopped again by multiplying it with zero from a certain point in time onwards. The latter is achieved by means of the step function: step(value, starttime).


dose=10   ; total amount

duration=2; time units

kout=0.2  ; elimination rate, 1/time


; infusion rate: constant = dose/duration until end of duration,

; then 0 until eternity (using 1-step)

rate_in = dose / duration * (1-step(1, duration))


; amount in compartment m

d/dt (m) = rate_in - kout*m;

init m=0


Thank you to Ronald Gieschke for getting me started on infusions.

Varying dose amounts

Multiple doses are basically administered as single doses. The trick is to pay attention to the time when they are administered. Here is a general scheme that allows the definition of amounts and number of administrations.



n1=7; number of days of dosing of dose1

regimen1=1; 1=once daily, 2=twice daily, etc










; Stuff the values into an array for ease of calculation.

; If we define the array only, we cannot put the values onto sliders.

; That is the only justification for not setting dose[1]=100, etc.










Note: You can put all those variables on the slider and change them interactively to visualize the effect of different doses and dosing regimens (!).

Varying Bolus Doses

The following code defines the administration of n1 doses of dose1, n2 doses of dose2, and n3 doses of dose3.


d/dt (depot) =

-ka * depot +

      pulse(dose[1], 0, regimen[1]) –

pulse(dose[1], n[1]*regimen[1], regimen[1]) +


      pulse(dose[2], n[1]*regimen[1], regimen[1]) –

pulse(dose[2], (n[1]+n[2])*regimen[2], regimen[2]) +


      pulse(dose[3], (n[1]+n[2])*regimen[3], regimen[3]) –

pulse(dose[3], (n[1]+n[2]+n[3])*regimen[3], regimen[3])

Varying Infusions

Giving a pre-defined sequence of infusions is a little bit tricky – at least to me.

Time is forwarded by Berkeley Madonna, so what we need to find out for a given TIME value is whether or not we are currently giving an infusion, and if we do, what the current dosing scheme is.


The code below looks lengthy, but that’s to the best of my knowledge. Any suggestions for improvement – let me know!


{ ------------------------------- }

{ Infusion dose scheme definition }

{ ------------------------------- }


; 100 mg for 3 days, twice daily

dose [1]=100; amount

n    [1]=3; number of days

regimen[1]=2; 1=once daily, 2=twice daily, etc.


; 200 mg for 3 days, once daily

dose [2]=200

n    [2]=3



; 500 mg for 3 days, once daily

dose [3]=500

n    [3]=3



DST=3; number of dose steps total (length of arrays above)


; derive total number of doses


nd[2..DST]=nd[i-1] + n[i]*regimen[i]

ndoses=nd[DST]; number of doses total


; time interval of dosing

t_int[1..DST] = 24 / regimen[i]


; infusion start and end (first infusion of each new trt regimen)

inf_start[1]      = 0

inf_start[2..DST] = tsum[i-1]*24


inf_end  [1]      = D1

inf_end  [2..DST] = tsum[i-1]*24+D1


; rates at times of rate change:

rate_in[1]      = dose[1] / D1

rate_in[2..DST] = dose[i] / D1


; for each period, set a flag whether we are in this time period or not

after_period_start[1     ] = 1

after_period_start[2..DST] = IF TIME >= 24*tsum[i-1] then 1 else 0

before_period_end [1..DST] = IF TIME <= 24*tsum[i  ] then 1 else 0

this_period       [1..DST] = after_period_start[i] * before_period_end[i]


; Set flags for infusion time for each period

; Either all values are 0 (no infusion in none of the time periods) or

; exactly one of them equals 1, when it is infusion time in that period i


is_inf_time[1..DST] = IF (MOD(TIME, t_int[i]) <= D1) then 1 else 0

is_inf_time[1..DST] = is_inf_time[i] * this_period[i]


; Since is_inf_time is all 0 or exactly one entry equals 1, the sum of the

; product is now the rate of administration at this point in time


rate_vector[1..DST] = rate_in[i] * is_inf_time[i]

rate = arraysum(rate_vector[*])


{ Administer the infusion doses }


d/dt(A1_infusion) = rate - ka*A1_infusion


Switching between different dosing schemes using sliders

To easily compare different dosing schemes by using sliders, one needs to define a parameter that sets the dosing scheme:




Moving the slider to values 2, 3, 4, etc. shall change the values for dose, n, and regimen in the examples above.

In order to achieve that, I use arrays to define the different dosing schemes. The example that follows is for bolus dosing.


; first dosing scheme


dose[1, 1]=100

n[1, 1]=7

regimen[1, 1]=1


dose[1, 2]=200

n[1, 2]=14

regimen[1, 2]=2


dose_steps_total[1]=2; number of steps to define array dimension


; second dosing scheme


dose[2, 1]=200



; now we do the calculations for each dosing scheme


DS=dosingscheme; for shorter code



; times of dose change (after start of treatment)

tsum[1] = n[DS,1]

tsum[2..DST] = tsum[i-1] + n[DS,i]


; add a pulse (ad infinitum) per dosing event

dose_add[1]         = pulse(dose[DS, 1],         0*24, 24/regimen[DS, 1])

dose_add[2..DST]    = pulse(dose[DS, i], tsum[i-1]*24, 24/regimen[DS, i])


; subtract the added pulses at the end of a dosing regimen

; such that only the next dose is just the new dose or 0 at the end of dosing

dose_remove[1..DST] = pulse(dose[DS, i], tsum[i]  *24, 24/regimen[DS, i])


{ --- Administer the doses --- }


; The amount in the first (dosing) compartment is the sum of the added pulses and

; the subtracted pulses (doses)


d/dt(A1_bolus) = -ka*A1_bolus + arraysum(dose_add[*]) - arraysum(dose_remove[*])



Now you can switch between dosing regimen 1 and dosing regimen 2 by just setting the value of dosingscheme to the corresponding value (using a slider or changing the value in the parameter window).

Check the “overlay” box and see the effect of the different dosing schemes overlaid.




The End.