or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-tools.mdexternal-data.mdfunctions-module.mdindex.mdmodel-loading.mdmodel-simulation.mdparameter-management.mdstateful-components.mdutils-module.md

stateful-components.mddocs/

0

# Stateful Model Components

1

2

PySD's stateful components maintain state between simulation time steps, implementing core System Dynamics structures like stocks (integrations), delays, smoothing functions, and forecasting components.

3

4

## Capabilities

5

6

### Base Stateful Classes

7

8

Foundation classes that provide state management capabilities for model components.

9

10

```python { .api }

11

class Stateful:

12

"""

13

Base class for stateful objects.

14

15

Provides basic state management functionality including initialization,

16

state updates, and memory management for model components that maintain

17

state between time steps.

18

"""

19

20

class DynamicStateful(Stateful):

21

"""

22

Base for dynamically updating stateful objects.

23

24

Extends Stateful with capabilities for dynamic state updates,

25

dependency tracking, and integration with the simulation engine.

26

"""

27

```

28

29

### Integration Components

30

31

Core stock and flow components that perform integration over time.

32

33

```python { .api }

34

class Integ(DynamicStateful):

35

"""

36

Integration/stock elements.

37

38

Implements System Dynamics stocks (levels) that accumulate flows over time.

39

Performs numerical integration using specified integration method.

40

41

Methods:

42

- __init__(lambda_function, initial_value, lambda_init_function=None)

43

- __call__(time) - Get current integrated value

44

- init(time, initial_value) - Initialize with specific value

45

- update(time) - Update integration state for current time step

46

"""

47

48

class NonNegativeInteg(Integ):

49

"""

50

Non-negative integration.

51

52

Integration component that ensures the integrated value never goes below zero,

53

useful for physical quantities like population, inventory, or resources.

54

55

Inherits all Integ methods with additional constraint enforcement.

56

"""

57

```

58

59

#### Usage Examples

60

61

```python

62

from pysd.py_backend.statefuls import Integ, NonNegativeInteg

63

64

# Create basic integration component

65

def population_flows():

66

return births_per_time_step - deaths_per_time_step

67

68

population = Integ(population_flows, initial_value=1000)

69

70

# Non-negative integration for physical quantities

71

def inventory_flows():

72

return production_rate - consumption_rate

73

74

inventory = NonNegativeInteg(inventory_flows, initial_value=500)

75

76

# Access current values during simulation

77

current_population = population(current_time)

78

current_inventory = inventory(current_time)

79

```

80

81

### Delay Components

82

83

Components that implement various types of delays commonly used in System Dynamics models.

84

85

```python { .api }

86

class Delay(DynamicStateful):

87

"""

88

Variable delay functions.

89

90

Implements first-order variable delay where delay time can change dynamically.

91

Models processes where items spend variable time in the delay.

92

93

Methods:

94

- __init__(delay_input, delay_time, initial_value, order=1)

95

- __call__(time) - Get delayed output value

96

- init(time, initial_value) - Initialize delay chain

97

"""

98

99

class DelayN(DynamicStateful):

100

"""

101

Nth order delay.

102

103

Implements higher-order delays by chaining multiple first-order delays.

104

Provides more realistic delay behavior with gradual buildup and decay.

105

106

Methods:

107

- __init__(delay_input, delay_time, initial_value, order=3)

108

- __call__(time) - Get delayed output value

109

"""

110

111

class DelayFixed(DynamicStateful):

112

"""

113

Fixed delay.

114

115

Implements pipeline delay with fixed delay time. Items enter and exit

116

after exactly the specified delay time (FIFO queue behavior).

117

118

Methods:

119

- __init__(delay_input, delay_time, initial_value)

120

- __call__(time) - Get delayed output value

121

"""

122

```

123

124

#### Usage Examples

125

126

```python

127

from pysd.py_backend.statefuls import Delay, DelayN, DelayFixed

128

129

# Variable delay for information processing

130

def information_input():

131

return new_information_rate

132

133

def processing_time():

134

return base_processing_time * complexity_factor

135

136

information_delay = Delay(

137

delay_input=information_input,

138

delay_time=processing_time,

139

initial_value=0,

140

order=1

141

)

142

143

# Third-order delay for material flow

144

material_delay = DelayN(

145

delay_input=lambda: production_rate,

146

delay_time=lambda: 5.0, # 5 time units

147

initial_value=100,

148

order=3

149

)

150

151

# Fixed pipeline delay for manufacturing

152

manufacturing_delay = DelayFixed(

153

delay_input=lambda: orders_received,

154

delay_time=lambda: 7.0, # Exactly 7 time units

155

initial_value=50

156

)

157

158

# Get delayed values during simulation

159

processed_info = information_delay(current_time)

160

materials_out = material_delay(current_time)

161

finished_goods = manufacturing_delay(current_time)

162

```

163

164

### Smoothing and Forecasting

165

166

Components for smoothing noisy data and generating forecasts.

167

168

```python { .api }

169

class Smooth(DynamicStateful):

170

"""

171

Smoothing functions.

172

173

Implements exponential smoothing (first-order delay applied to input).

174

Reduces noise and volatility in model variables.

175

176

Methods:

177

- __init__(smooth_input, smooth_time, initial_value)

178

- __call__(time) - Get smoothed output value

179

"""

180

181

class Trend(DynamicStateful):

182

"""

183

Trend calculation.

184

185

Calculates the trend (rate of change) of input variable using

186

exponential smoothing of the derivative.

187

188

Methods:

189

- __init__(trend_input, trend_time, initial_trend=0)

190

- __call__(time) - Get current trend value

191

"""

192

193

class Forecast(DynamicStateful):

194

"""

195

Forecasting functions.

196

197

Generates forecasts by extrapolating current value and trend.

198

Combines exponential smoothing with trend analysis.

199

200

Methods:

201

- __init__(forecast_input, average_time, horizon_time, initial_trend=0)

202

- __call__(time) - Get forecasted value

203

"""

204

```

205

206

#### Usage Examples

207

208

```python

209

from pysd.py_backend.statefuls import Smooth, Trend, Forecast

210

211

# Smooth noisy sales data

212

def raw_sales():

213

return daily_sales_with_noise

214

215

smoothed_sales = Smooth(

216

smooth_input=raw_sales,

217

smooth_time=5.0, # 5-day smoothing

218

initial_value=1000

219

)

220

221

# Calculate trend in market growth

222

def market_size():

223

return current_market_size

224

225

market_trend = Trend(

226

trend_input=market_size,

227

trend_time=10.0, # 10-period trend calculation

228

initial_trend=0.05 # 5% initial growth rate

229

)

230

231

# Forecast future demand

232

demand_forecast = Forecast(

233

forecast_input=lambda: current_demand,

234

average_time=8.0, # 8-period averaging

235

horizon_time=12.0, # 12-period forecast horizon

236

initial_trend=0.02

237

)

238

239

# Access values during simulation

240

current_smooth_sales = smoothed_sales(current_time)

241

current_trend = market_trend(current_time)

242

future_demand = demand_forecast(current_time)

243

```

244

245

### Sampling and Control

246

247

Components for conditional sampling and initial value handling.

248

249

```python { .api }

250

class SampleIfTrue(DynamicStateful):

251

"""

252

Conditional sampling.

253

254

Samples and holds input value when condition is true, maintaining

255

the last sampled value when condition is false.

256

257

Methods:

258

- __init__(sample_input, condition, initial_value)

259

- __call__(time) - Get current sampled value (held if condition false)

260

"""

261

262

class Initial(Stateful):

263

"""

264

Initial value storage.

265

266

Stores and provides access to initial values of model variables.

267

Used for reference and reset operations.

268

269

Methods:

270

- __init__(initial_function)

271

- __call__(time) - Get initial value

272

"""

273

```

274

275

#### Usage Examples

276

277

```python

278

from pysd.py_backend.statefuls import SampleIfTrue, Initial

279

280

# Sample price when market is open

281

def current_price():

282

return stock_price

283

284

def market_open():

285

return trading_hours_active

286

287

sampled_price = SampleIfTrue(

288

sample_input=current_price,

289

condition=market_open,

290

initial_value=100.0

291

)

292

293

# Store initial population for comparison

294

def initial_population():

295

return starting_population_value

296

297

population_initial = Initial(initial_population)

298

299

# Use during simulation

300

price_when_open = sampled_price(current_time)

301

baseline_population = population_initial(current_time)

302

```

303

304

### State Management

305

306

All stateful components provide common state management functionality:

307

308

#### Initialization

309

310

```python

311

# Components can be initialized with specific values

312

component.init(time=0, initial_value=500)

313

314

# Or use default initialization

315

component.__init__(input_function, initial_value=100)

316

```

317

318

#### State Updates

319

320

```python

321

# Components automatically update during simulation

322

# Manual update if needed:

323

component.update(current_time)

324

325

# Access current state

326

current_value = component(current_time)

327

```

328

329

#### Memory Management

330

331

Stateful components automatically manage their internal memory:

332

- Maintain necessary historical values for calculations

333

- Clean up old data beyond required history

334

- Handle time step changes dynamically

335

336

### Integration with Models

337

338

Stateful components are typically created automatically when models are translated from Vensim/XMILE, but can also be used directly:

339

340

```python

341

import pysd

342

from pysd.py_backend.statefuls import Integ, Smooth

343

344

# In translated models, stateful components are created automatically

345

model = pysd.read_vensim('model_with_stocks.mdl')

346

results = model.run()

347

348

# Direct usage for custom components

349

def custom_flow():

350

return some_calculation()

351

352

custom_stock = Integ(custom_flow, initial_value=1000)

353

354

# Use in custom simulation loop

355

time_step = 0.25

356

current_time = 0

357

358

while current_time <= 50:

359

stock_value = custom_stock(current_time)

360

print(f"Time {current_time}: Stock = {stock_value}")

361

custom_stock.update(current_time)

362

current_time += time_step

363

```

364

365

### Error Handling

366

367

Stateful components include robust error handling:

368

369

- **Division by zero** in delay times handled gracefully

370

- **Negative delay times** raise appropriate warnings

371

- **Initialization errors** provide clear diagnostic messages

372

- **Time step consistency** automatically managed

373

374

```python

375

try:

376

problem_delay = Delay(input_func, delay_time=lambda: -1, initial_value=0)

377

except ValueError as e:

378

print(f"Invalid delay configuration: {e}")

379

```

380

381

### Performance Considerations

382

383

Stateful components are optimized for simulation performance:

384

385

- Efficient memory usage for long simulations

386

- Vectorized operations where possible

387

- Automatic caching of intermediate calculations

388

- Minimal overhead for state updates

389

390

For large models with many stateful components, consider:

391

- Using appropriate integration time steps

392

- Monitoring memory usage for very long simulations

393

- Utilizing model caching capabilities