pyCLINE 0.1.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,417 @@
1
+
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ from tqdm import tqdm
5
+
6
+ import torch
7
+ import torch.nn as nn
8
+ import torch.optim as optim
9
+ from torch.utils.data import DataLoader, TensorDataset
10
+
11
+ #Error handling
12
+ class NeuralNetworkError(Exception):
13
+ """Error raised for neural network issues."""
14
+
15
+ class NeuralNetworkSetupError(NeuralNetworkError):
16
+ """Error raised when parameters of the network are 0 but can not be zero."""
17
+ def __init__(self, parameter_name, parameter, message="parameter has to be greater then zero/be provided."):
18
+ self.parameter_name = parameter_name
19
+ self.parameter = parameter
20
+ self.message = message
21
+ super().__init__(f'Error: {self.parameter_name} '+self.message+f' Value given: {self.parameter}')
22
+
23
+ class NeuralNetworkSetupTrainingError(NeuralNetworkError):
24
+ """Error raised when setting up training of the neural network."""
25
+ def __init__(self, parameter_name, parameter, message="parameter has to be greater then zero."):
26
+ self.parameter_name = parameter_name
27
+ self.parameter = parameter
28
+ self.message = message
29
+ super().__init__(f'Error: {self.parameter_name} '+self.message+f' Value given: {self.parameter}')
30
+
31
+ class NeuralNetworkDataError(NeuralNetworkError):
32
+ """Error raised when data for the neural network is incorrect."""
33
+ def __init__(self, errors):
34
+ self.errors = errors
35
+ message = "; ".join(errors)
36
+ super().__init__(f'Error: {message}')
37
+
38
+
39
+ class FFNN(nn.Module):
40
+ """
41
+ Feedforward Neural Network (FFNN) class.
42
+
43
+ Args:
44
+ nn (torch.nn module): PyTorch neural network module
45
+ """
46
+ def __init__(self, Nin, Nout, Nlayers, Nnodes, activation):
47
+ super(FFNN, self).__init__()
48
+ layers = [nn.Linear(Nin, Nnodes), activation()]
49
+ for _ in range(Nlayers - 1):
50
+ layers.append(nn.Linear(Nnodes, Nnodes))
51
+ layers.append(activation())
52
+ layers.append(nn.Linear(Nnodes, Nout))
53
+ # layers.append(nn.Sigmoid())
54
+ self.model = nn.Sequential(*layers)
55
+
56
+ def forward(self, x):
57
+ return self.model(x)
58
+
59
+ def init_weights(m):
60
+ """
61
+ Initialize the weights of the neural network.
62
+
63
+ Args:
64
+ m (torch model): PyTorch model
65
+ """
66
+ if isinstance(m, nn.Linear):
67
+ nn.init.xavier_uniform_(m.weight)
68
+ nn.init.zeros_(m.bias)
69
+
70
+ def configure_FFNN_model(Nin, Nout, Nlayers, Nnodes, activation=nn.SiLU, optimizer_name='Adam', lr=1e-4,
71
+ loss_fn=nn.MSELoss, summary=False):
72
+ """
73
+ Configure the Feedforward Neural Network (FFNN) model.
74
+
75
+ Args:
76
+ Nin (int): Number of input features
77
+ Nout (int): Number of output features
78
+ Nlayers (int): Number of layers
79
+ Nnodes (int): Number of nodes
80
+ activation (torch neural network activation function module, optional): Activation function of neural network training. Defaults to nn.SiLU.
81
+ optimizer_name (str, optional): Optimizer for model training. Defaults to 'Adam'.
82
+ lr (float, optional): Learning rate for training. Defaults to 1e-4.
83
+ loss_fn (torch loss function module, optional): Loss function for training. Defaults to nn.MSELoss.
84
+ summary (bool, optional): If model summary should be generated. Defaults to False.
85
+
86
+ Returns:
87
+ model (torch model): setup FFNN model
88
+ optimizer (torch optimizer): optimizer for training
89
+ loss_fn (torch loss function): loss function for training
90
+ """
91
+ if Nin == 0:
92
+ raise NeuralNetworkSetupError('Nin', Nin)
93
+ if Nout == 0:
94
+ raise NeuralNetworkSetupError('Nout', Nout)
95
+ if Nlayers == 0:
96
+ raise NeuralNetworkSetupError('Nlayers', Nlayers)
97
+ if Nnodes == 0:
98
+ raise NeuralNetworkSetupError('Nnodes', Nnodes)
99
+ if lr == 0:
100
+ raise NeuralNetworkSetupError('Learning rate', lr)
101
+ if optimizer_name == '':
102
+ raise NeuralNetworkSetupError('Optimizer', optimizer_name)
103
+ if loss_fn == '' or loss_fn == None:
104
+ raise NeuralNetworkSetupError('Loss function', loss_fn)
105
+
106
+ model = FFNN(Nin, Nout, Nlayers, Nnodes, activation)
107
+ model.apply(init_weights)
108
+ if optimizer_name == 'SGD':
109
+ optimizer = optim.SGD(model.parameters(), lr=lr, momentum=0.9)
110
+ elif optimizer_name == 'RMSprop':
111
+ optimizer = optim.RMSprop(model.parameters(), lr=lr, alpha=0.99)
112
+ elif optimizer_name == 'Adam':
113
+ optimizer = optim.Adam(model.parameters(), lr=lr, weight_decay=1e-10)
114
+ elif optimizer_name == 'Nadam':
115
+ optimizer = optim.Nadam(model.parameters(), lr=lr)
116
+ elif optimizer_name == 'Adagrad':
117
+ optimizer = optim.Adagrad(model.parameters(), lr=lr)
118
+ elif optimizer_name == 'Adadelta':
119
+ optimizer = optim.Adadelta(model.parameters(), lr=lr)
120
+
121
+ loss_fn = loss_fn()
122
+
123
+ if summary:
124
+ print(model)
125
+
126
+ return model, optimizer, loss_fn
127
+
128
+ # Monitor gradients
129
+ def monitor_gradients(model):
130
+ """
131
+ Monitor the gradients of the model.
132
+
133
+ Args:
134
+ model (torch model feature): torch model
135
+
136
+ Returns:
137
+ gradients (float): gradients of the model
138
+ """
139
+ for name, param in model.named_parameters():
140
+ if param.requires_grad:
141
+ gradients=param.grad.norm()
142
+ return gradients
143
+
144
+ def loss_function(input, target, nc_prediction, nullcline_guess, factor):
145
+ """
146
+ Loss function for the neural network model.
147
+
148
+ Args:
149
+ input (torch tensor): input data
150
+ target (torch tensor): target data
151
+ nc_prediction (torch tensor): nullcline prediction data
152
+ nullcline_guess (torch tensor): nullcline guess data
153
+ factor (float): penalty factor for loss function
154
+
155
+ Returns:
156
+ loss (float): loss function
157
+ """
158
+ mse_loss = nn.MSELoss()
159
+ mse_loss_nc = nn.MSELoss()
160
+ loss_train=mse_loss(input, target)
161
+ loss_nc = mse_loss_nc(nc_prediction, nullcline_guess)
162
+ return loss_nc+factor*loss_train
163
+
164
+ def train_FFNN_model(model, optimizer, loss_fn, input_train, target_train, input_test, target_test, validation_data,
165
+ epochs=200, batch_size=64, plot_loss=True, device='cpu', use_progressbar=True, save_evolution=True,
166
+ loss_target='limit_cycle', nullcline_guess=None, factor=1.0, method=None, minimal_value=0.0, maximal_value=1.0):
167
+ """
168
+ Train the Feedforward Neural Network (FFNN) model.
169
+
170
+ Args:
171
+ model (torch model): configured FFNN model
172
+ optimizer (torch optimizer): optimizer
173
+ loss_fn (torch loss function): loss function
174
+ input_train (pandas dataframe): input training data
175
+ target_train (pandas dataframe): target training data
176
+ input_test (pandas dataframe): input testing data
177
+ target_test (pandas dataframe): target testing data
178
+ validation_data (pandas dataframe): validation data
179
+ epochs (int, optional): number of epochs. Defaults to 200.
180
+ batch_size (int, optional): batch size. Defaults to 64.
181
+ plot_loss (bool, optional): plot the loss. Defaults to True.
182
+ device (str, optional): device to train the model on. For 'cuda', necessary GPU and CUDA Toolkit are required. Defaults to 'cpu'.
183
+ use_progressbar (bool, optional): use progress bar when running the training. Defaults to True.
184
+ save_evolution (bool, optional): save the evolution of limit cycle and nullcline predictions. Defaults to True.
185
+ loss_target (str, optional): Decide if the target is not limit cycle, but the inital nullcline seed. Defaults to 'limit_cycle'.
186
+ nullcline_guess (torch tensor, optional): Torch tensor containing inital nullcline guess. Defaults to None.
187
+ factor (float, optional): The penalty factor for nullcline guess loss evaluation. Defaults to 1.0.
188
+ method (str, optional): Method used for prediction, can be derivative or delayed variables. Defaults to None.
189
+ minimal_value (float, optional): Minimal value of minmax normalization for inbetween prediction. Defaults to 0.0.
190
+ maximal_value (int, optional): Maximal value of minmax normalization for inbetween prediction. Defaults to 1.0.
191
+
192
+ Returns:
193
+ train_losses (list): training losses
194
+ val_losses (list): validation losses
195
+ test_loss (float): testing loss
196
+ predictions (list): predictions of nullcline structure over all epochs
197
+ lc_predictions (list): limit cycle predictions over all epochs
198
+ """
199
+ #Error handling
200
+ if input_train.shape[0] == 0:
201
+ raise NeuralNetworkDataError(['Input training data is empty.'])
202
+ if target_train.shape[0] == 0:
203
+ raise NeuralNetworkDataError(['Target training data is empty.'])
204
+ if input_test.shape[0] == 0:
205
+ raise NeuralNetworkDataError(['Input testing data is empty.'])
206
+ if target_test.shape[0] == 0:
207
+ raise NeuralNetworkDataError(['Target testing data is empty.'])
208
+
209
+ if input_train.shape[0]!=target_train.shape[0]:
210
+ raise NeuralNetworkDataError(['Input and target training data have different lengths.'])
211
+ if input_test.shape[0]!=target_test.shape[0]:
212
+ raise NeuralNetworkDataError(['Input and target testing data have different lengths.'])
213
+
214
+ if validation_data[0].shape[0] == 0:
215
+ raise NeuralNetworkDataError(['Validation input data is empty.'])
216
+ if validation_data[1].shape[0] == 0:
217
+ raise NeuralNetworkDataError(['Validation target data is empty.'])
218
+ if validation_data[0].shape[0]!=validation_data[1].shape[0]:
219
+ raise NeuralNetworkDataError(['Validation input and target data have different lengths.'])
220
+
221
+ if epochs == 0:
222
+ raise NeuralNetworkSetupTrainingError('epochs', epochs)
223
+ if batch_size == 0:
224
+ raise NeuralNetworkSetupTrainingError('batch_size', batch_size)
225
+
226
+ # Move model to the specified device
227
+ model.to(device)
228
+ if loss_target=='limit_cycle':
229
+ train_dataset = TensorDataset(torch.tensor(input_train.values, dtype=torch.float32), torch.tensor(target_train.values, dtype=torch.float32))
230
+ test_dataset = TensorDataset(torch.tensor(input_test.values, dtype=torch.float32), torch.tensor(target_test.values, dtype=torch.float32))
231
+ val_dataset = TensorDataset(torch.tensor(validation_data[0].values, dtype=torch.float32), torch.tensor(validation_data[1].values, dtype=torch.float32))
232
+
233
+ train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
234
+ test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
235
+ val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
236
+ if loss_target=='nullcline_guess':
237
+
238
+ train_dataset = TensorDataset(torch.tensor(input_train.values, dtype=torch.float32), torch.tensor(target_train.values, dtype=torch.float32), torch.tensor(np.array([nullcline_guess]*input_train.shape[0]), dtype=torch.float32))
239
+ test_dataset = TensorDataset(torch.tensor(input_test.values, dtype=torch.float32), torch.tensor(target_test.values, dtype=torch.float32), torch.tensor(np.array([nullcline_guess]*input_test.shape[0]), dtype=torch.float32))
240
+ val_dataset = TensorDataset(torch.tensor(validation_data[0].values, dtype=torch.float32), torch.tensor(validation_data[1].values, dtype=torch.float32), torch.tensor(([nullcline_guess]*validation_data[0].shape[0]), dtype=torch.float32))
241
+
242
+ train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
243
+ test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
244
+ val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
245
+
246
+ train_losses = []
247
+ val_losses = []
248
+ predictions=[]
249
+ lc_predictions=[]
250
+ gradients=[]
251
+
252
+ for epoch in range(epochs):
253
+ if use_progressbar:
254
+ progressbar=tqdm(enumerate(train_loader), total=len(train_loader), desc=f'Epoch {epoch+1}/{epochs}')
255
+ else:
256
+ progressbar=enumerate(train_loader)
257
+ model.train()
258
+ running_loss = 0.0
259
+ for batch_idx, data in progressbar:
260
+ # Move inputs and targets to the specified device
261
+ if loss_target=='limit_cycle':
262
+ inputs, targets = data
263
+ inputs, targets = inputs.to(device), targets.to(device)
264
+ if loss_target=='nullcline_guess':
265
+ inputs, targets, nullcline_guess = data
266
+ inputs, targets, nullcline_guess = inputs.to(device), targets.to(device), nullcline_guess.to(device)
267
+
268
+ optimizer.zero_grad()
269
+ outputs = model(inputs)
270
+ if loss_target=='limit_cycle':
271
+ loss = loss_fn(outputs, targets)
272
+
273
+ if loss_target=='nullcline_guess':
274
+ input_null = np.zeros((nullcline_guess.shape[1], model.model[0].in_features))
275
+ for i in range(model.model[0].in_features):
276
+ input_null[:,i] = np.linspace(0, 1,nullcline_guess.shape[1])
277
+ input_null = torch.tensor(input_null, dtype=torch.float32).to(device)
278
+ nc_prediction = model(input_null)
279
+ loss = loss_function(outputs, targets, nc_prediction[:,0], nullcline_guess[0,:], factor)
280
+ loss.backward()
281
+ optimizer.step()
282
+ running_loss += loss.item() * inputs.size(0)
283
+
284
+ train_loss = running_loss / len(train_loader.dataset)
285
+ train_losses.append(train_loss)
286
+
287
+ model.eval()
288
+ val_loss = 0.0
289
+ with torch.no_grad():
290
+ for data in val_loader:
291
+
292
+ if loss_target=='limit_cycle':
293
+ inputs, targets = data
294
+ inputs, targets = inputs.to(device), targets.to(device)
295
+ if loss_target=='nullcline_guess':
296
+ inputs, targets, nullcline_guess = data
297
+ inputs, targets, nullcline_guess = inputs.to(device), targets.to(device), nullcline_guess.to(device)
298
+
299
+ outputs = model(inputs)
300
+ if loss_target=='limit_cycle':
301
+ loss = loss_fn(outputs, targets)
302
+
303
+ if loss_target=='nullcline_guess':
304
+ input_null = np.zeros((nullcline_guess.shape[1], model.model[0].in_features))
305
+ for i in range(model.model[0].in_features):
306
+ input_null[:,i] = np.linspace(0, 1,nullcline_guess.shape[1])
307
+ input_null = torch.tensor(input_null, dtype=torch.float32).to(device)
308
+ nc_prediction = model(input_null)
309
+ loss = loss_function(outputs, targets, nc_prediction[:,0], nullcline_guess[0,:], factor)
310
+ val_loss += loss.item() * inputs.size(0)
311
+
312
+ val_loss /= len(val_loader.dataset)
313
+ val_losses.append(val_loss)
314
+
315
+ if save_evolution:
316
+ _ , prediction_null = nullcline_prediction(model, Nsteps=500, method=method, min_val=minimal_value, max_val=maximal_value)
317
+ predictions.append(prediction_null)
318
+ input_prediction=torch.tensor(input_train.values, dtype=torch.float32)
319
+ with torch.no_grad():
320
+ output_prediction = model(input_prediction).cpu().numpy()
321
+ lc_predictions.append(output_prediction)
322
+ if use_progressbar:
323
+ progressbar.set_description(f'Epoch [{epoch+1}/{epochs}], Batch [{batch_idx}/{len(train_loader)}], Loss: {train_loss:.4f}')
324
+ progressbar.refresh()
325
+
326
+ if plot_loss:
327
+ # plt.plot(gradients, label='Gradients')
328
+ plt.plot(train_losses, label='Train Loss')
329
+ plt.plot(val_losses, label='Validation Loss')
330
+ plt.yscale('log')
331
+ plt.legend()
332
+ plt.show()
333
+
334
+ model.eval()
335
+ test_loss = 0.0
336
+ with torch.no_grad():
337
+ for data in test_loader:
338
+ if loss_target=='limit_cycle':
339
+ inputs, targets = data
340
+ inputs, targets = inputs.to(device), targets.to(device)
341
+ if loss_target=='nullcline_guess':
342
+ inputs, targets, nullcline_guess = data
343
+ inputs, targets, nullcline_guess = inputs.to(device), targets.to(device), nullcline_guess.to(device)
344
+
345
+ outputs = model(inputs)
346
+ if loss_target=='limit_cycle':
347
+ loss = loss_fn(outputs, targets)
348
+
349
+ if loss_target=='nullcline_guess':
350
+ input_null = np.zeros((nullcline_guess.shape[1], model.model[0].in_features))
351
+ for i in range(model.model[0].in_features):
352
+ input_null[:,i] = np.linspace(0, 1,nullcline_guess.shape[1])
353
+ input_null = torch.tensor(input_null, dtype=torch.float32).to(device)
354
+
355
+ nc_prediction = model(input_null)
356
+ loss = loss_function(outputs, targets, nc_prediction[:,0], nullcline_guess[0,:], factor)
357
+ test_loss += loss.item() * inputs.size(0)
358
+
359
+ test_loss /= len(test_loader.dataset)
360
+ predictions_evolution=np.array(predictions)
361
+ lc_predictions = np.array(lc_predictions)
362
+ return train_losses, val_losses, test_loss, predictions_evolution, lc_predictions
363
+
364
+ def nullcline_prediction(model, Nsteps, device='cpu', method=None,min_val=0.0, max_val=1.0):
365
+ """
366
+ Predict the nullcline of the model.
367
+
368
+ Args:
369
+ model (torch model): FFNN model
370
+ Nsteps (int): Number of steps for discretization of input variable for nullcline prediction
371
+ device (str, optional): device to train the model on. For 'cuda', necessary GPU and CUDA Toolkit are required. Defaults to 'cpu'.
372
+ method (str, optional): Method used for prediction, can be derivative or delayed variables. Defaults to None.
373
+ min_val (float, optional): Minimum value for minmax normalization. Defaults to 0.0.
374
+ max_val (float, optional): Maximum value for minmax normalization. Defaults to 1.0.
375
+
376
+ Returns:
377
+ input_null (numpy array): input variable for nullcline prediction
378
+ prediction_null (numpy array): predicted nullcline
379
+ """
380
+ input_null = np.zeros((Nsteps, model.model[0].in_features))
381
+ if method=='derivative':
382
+ for i in range(model.model[0].in_features-1):
383
+ input_null[:,i] = np.linspace(min_val, max_val, Nsteps)
384
+ else:
385
+ for i in range(model.model[0].in_features):
386
+ input_null[:,i] = np.linspace(min_val, max_val,Nsteps)
387
+
388
+ input_null = torch.tensor(input_null, dtype=torch.float32).to(device)
389
+ model.eval()
390
+ with torch.no_grad():
391
+ prediction_null = model(input_null).cpu().numpy()
392
+ return input_null.cpu().numpy(), prediction_null.reshape(Nsteps,)
393
+
394
+ def compute_nullcline(fnull, xvar, yvar, Nsteps, df_coef, value_min=0.0, value_max=1.0, normalize=True):
395
+ """
396
+ Compute the nullcline of the model from the ground true function.
397
+
398
+ Args:
399
+ fnull (function): ground true function
400
+ xvar (str): x variable for nullcline computation
401
+ yvar (str): y variable for nullcline computation
402
+ Nsteps (int): Number of steps for discretization of input variable for nullcline prediction
403
+ df_coef (pandas dataframe): dataframe containing the coefficients of the model
404
+ value_min (float, optional): Minimum value for minmax normalization. Defaults to 0.0.
405
+ value_max (float, optional): Maximum value for minmax normalization.. Defaults to 1.0.
406
+ normalize (bool, optional): If values should be minmax normalized. Defaults to True.
407
+
408
+ Returns:
409
+ xnull (list): x variable for nullcline prediction
410
+ ynull (list): predicted nullcline
411
+ """
412
+ xnull = np.linspace(df_coef[xvar]['min'],df_coef[xvar]['max'], Nsteps)
413
+ ynull = fnull(xnull)
414
+ if normalize:
415
+ ynull = (ynull - df_coef[yvar]['min'])*(value_max-value_min)/(df_coef[yvar]['max'] - df_coef[yvar]['min'])+value_min
416
+
417
+ return xnull, ynull
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025, Bartosz Prokop, Nikita Frolov, Lendert Gelens
4
+ Laboratory of Dynamics in Biological Systems (DiBS/Gelens lab)
5
+ Department of Cellular and Mollecular Medicine, KU Leuven
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.2
2
+ Name: pyCLINE
3
+ Version: 0.1.7
4
+ Summary: This package is the python implementation of the CLINE method introduced by Prokop, Billen, Frolov, Gelens (2025).
5
+ Author-email: Bartosz Prokop <bartosz.prokop@kuleuven.be>, Nikita Frolov <nikita.frolov@kuleuven.be>, Lendert Gelens <lendert.gelens@kuleuven.be>
6
+ Project-URL: Homepage, https://pycline-ec8369.pages.gitlab.kuleuven.be/
7
+ Project-URL: Issues, https://gitlab.kuleuven.be/gelenslab/publications/pycline/-/issues
8
+ Keywords: model,model identification,nullcline,data-driven,machine learning,deep learning,torch,dynamics,oscillator,nonlinear dynamics,complex systems
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: matplotlib>=3.6.2
16
+ Requires-Dist: numpy<1.25.0,>=1.24.1
17
+ Requires-Dist: pandas~=1.5.2
18
+ Requires-Dist: torch>=2.4.1
19
+ Requires-Dist: tqdm>=4.66.1
20
+ Requires-Dist: jitcdde>=1.8.1
21
+ Requires-Dist: scipy>=1.9.3
22
+
23
+ # PyCLINE - python package for CLINE
24
+
25
+ The `pyCLINE` package is the python package based on the CLINE (**C**omputational **L**earning and **I**dentification of **N**ullclin**E**s).
26
+ It can be downloaded from PyPI with pip by using
27
+
28
+ pip install pyCLINE
29
+
30
+ The package allows to recreate all data, models and results shown in XXX, and to apply CLINE to other data sets.
31
+ In order to generate data used in XXX, a set of different models is being provided under `pyCLINE.model`.
32
+ Data from these models can be generated using `pyCLINE.generate_data()`.
33
+ For setting up the data prepartion and adjacent training a neural network, the submodule `pyCLINE.recovery_methods` is used.
34
+ The submodule contains the module for data_preparation `pyCLINE.recovery_methods.data_preparation` and for neural network training `pyCLINE.recovery_methods.nn_training`.
35
+
36
+ For a better understanding, `pyCLINE` also contains the module `pyCLINE.example` which provides four example also found in XXX with step by step instructions on how to setup a CLINE pipeline.
37
+
38
+ The structure of `pyCLINE` is shown here:
39
+
40
+ ![PyCLINE structure](pycline_structure.png)
@@ -0,0 +1,12 @@
1
+ pyCLINE/__init__.py,sha256=Z38oxkRTnb_EiU31_03Ba2bUKs1S2PEajMMGtlUOlf8,726
2
+ pyCLINE/example.py,sha256=pU-5tT7MA3qlygbsa-_CsjfZRUH5A66mJV7-lDMMP6c,8300
3
+ pyCLINE/generate_data.py,sha256=mQd5e-qyRv3iDecrYrPELOkR_JtMwxBaC_hBzf7Ddho,3642
4
+ pyCLINE/model.py,sha256=Qq5sQd7bXmI7efoN_IidWjfHAB--ZskEzGDkZYKsE38,35337
5
+ pyCLINE/recovery_methods/__init__.py,sha256=MQ9ZF_SVZNBJkZ0cyM5zXimiug9yu42lHBCnOMYw080,488
6
+ pyCLINE/recovery_methods/data_preparation.py,sha256=59DBwMhfkEmi3icb21smugCbhs99syUpAYAuwPQZ6u4,19708
7
+ pyCLINE/recovery_methods/nn_training.py,sha256=i8OeY72UcdGYmI_cloKnK2uqvaxLGUtMqT56-MgFVx8,20357
8
+ pycline-0.1.7.dist-info/LICENSE,sha256=6XV86fklwr93DuwtgX05Jg3n25_0c726oBhoSMn1aoc,1245
9
+ pycline-0.1.7.dist-info/METADATA,sha256=pxAt1XNClFORBZYPhZcHu-QuoY6bSYMVJ_FWPeQlwxQ,2245
10
+ pycline-0.1.7.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
11
+ pycline-0.1.7.dist-info/top_level.txt,sha256=w0zzQfaPH2RNTWfJ_lsPf-EbkvT6m3quM69exCTMBvU,8
12
+ pycline-0.1.7.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ pyCLINE