pyphysim.simulations package

Submodules

pyphysim.simulations.configobjvalidation module

Module implementing validation functions to define “specs” for configobj validation.

This module is not intended to be used directly. The functions defined here are used in the other modules in the pyphysim.simulations package.

pyphysim.simulations.configobjvalidation.integer_numpy_array_check(value: str, min: Optional[int] = None, max: Optional[int] = None) → List[int][source]

Parse and validate value as a numpy array (of integers).

Value can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions.

Parameters
  • value (str) – The string to be converted. This can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions.

  • min (int) – The minimum allowed value. If the converted value is (or have) lower than min then the VdtValueTooSmallError exception will be raised.

  • max (int) – The maximum allowed value. If the converted value is (or have) greater than man then the VdtValueTooSmallError exception will be raised.

Returns

The parsed numpy array.

Return type

List[int]

Notes

You can either separate the values with commas or spaces (any comma will have the same effect as a space). However, if you separate with spaces the values should be brackets, while if you separate with commands there should be no brackets.

>> max_iter = 5,10:20 >> max_iter = [0 5 10:20]

pyphysim.simulations.configobjvalidation.integer_scalar_or_integer_numpy_array_check(value: str, min: Optional[int] = None, max: Optional[int] = None) → Union[int, List[int]][source]

Parse and validate value as an integer number if possible and, if not, parse it as a numpy array (of integers).

Value can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions. The difference regarding the integer_numpy_array_check function is that if value is a single number it will be parsed as a single integer value, instead of being parsed as an integer numpy array with a single element.

Parameters
  • value (str) – The string to be converted. This can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions.

  • min (int) – The minimum allowed value. If the converted value is (or have) lower than min then the VdtValueTooSmallError exception will be raised.

  • max (int) – The maximum allowed value. If the converted value is (or have) greater than man then the VdtValueTooSmallError exception will be raised.

Returns

The parsed numpy array.

Return type

int | List[int]

Notes

You can either separate the values with commas or spaces (any comma will have the same effect as a space). However, if you separate with spaces the values should be brackets, while if you separate with commands there should be no brackets.

>> max_iter = 5,10:20 >> max_iter = [0 5 10:20]

pyphysim.simulations.configobjvalidation.real_numpy_array_check(value: str, min: Optional[int] = None, max: Optional[int] = None)[source]

Parse and validate value as a numpy array (of floats).

Value can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions.

Parameters
  • value (str) – The string to be converted. This can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions.

  • min (int) – The minimum allowed value. If the converted value is (or have) lower than min then the VdtValueTooSmallError exception will be raised.

  • max (int) – The maximum allowed value. If the converted value is (or have) greater than man then the VdtValueTooSmallError exception will be raised.

Returns

The parsed numpy array.

Return type

List[float]

Notes

You can either separate the values with commas or spaces (any comma will have the same effect as a space). However, if you separate with spaces the values should be in brackets, while if you separate with commands there should be no brackets.

>> SNR = 0,5,10:20 >> SNR = [0 5 10:20]

pyphysim.simulations.configobjvalidation.real_scalar_or_real_numpy_array_check(value: str, min=None, max=None)[source]

Parse and validate value as a float number if possible and, if not, parse it as a numpy array (of floats).

Value can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions. The difference regarding the real_numpy_array_check function is that if value is a single number it will be parsed as a single float value, instead of being parsed as a real numpy array with a single element.

Parameters
  • value (str | list[str]) – The string to be converted. This can be either a single number, a range expression in the form of min:max or min:step:max, or even a list containing numbers and range expressions.

  • min (int | float) – The minimum allowed value. If the converted value is (or have) lower than min then the VdtValueTooSmallError exception will be raised.

  • max (int | float) – The maximum allowed value. If the converted value is (or have) greater than man then the VdtValueTooSmallError exception will be raised.

Returns

The parsed numpy array.

Return type

float | List[float]

Notes

You can either separate the values with commas or spaces (any comma will have the same effect as a space). However, if you separate with spaces the values should be in brackets, while if you separate with commands there should be no brackets.

>> SNR = 0,5,10:20 >> SNR = [0 5 10:20]

pyphysim.simulations.parameters module

Module containing simulation parameter classes.

class pyphysim.simulations.parameters.SimulationParameters[source]

Bases: pyphysim.util.serialize.JsonSerializable

Class to store the simulation parameters.

A SimulationParameters object acts as a container for all simulation parameters. To add a new parameter to the object just call the add() method passing the name and the value of the parameter. The value can be anything as long as the SimulationRunner._run_simulation() method can understand it.

Alternatively, you can create a SimulationParameters object with all the parameters with the static method create(), which receives a dictionary with the parameter names as keys.

Parameters can be marked to be “unpacked”, as long as they are iterable, by calling the set_unpack_parameter() method. Different simulations will be performed for every combination of parameters marked to be unpacked, with the other parameters kept constant.

Examples

  • Create a new empty SimulationParameters object and add the individual parameters to it by calling its add() method.

    params = SimulationParameters()
    params.add('p1', [1,2,3])
    params.add('p2', ['a','b'])
    params.add('p3', 15)
    
  • Creating a new SimulationParameters object with the static create() function.

    p = {'p1':[1,2,3], 'p2':['a','b'],'p3':15}
    params=SimulationParameters.create(p)
    params.set_unpack_parameter('p1')
    params.set_unpack_parameter('p2')
    
  • We can then set some of the parameters to be unpacked with

    params.set_unpack_parameter('p1')
    

See also

SimulationResults

Class to store simulation results.

SimulationRunner

Base class to implement Monte Carlo simulations.

static _create(params_dict, unpack_index=- 1, original_sim_params=None)[source]

Creates a new SimulationParameters object.

This static method provides a different way to create a SimulationParameters object, already containing the parameters in the params_dict dictionary.

Parameters
  • params_dict (dict) – Dictionary containing the parameters. Each dictionary key corresponds to a parameter’s name, while the dictionary value corresponds to the actual parameter value..

  • unpack_index (int) – Index of the created SimulationParameters object when it is part of the unpacked variations of another SimulationParameters object. See get_unpacked_params_list().

  • original_sim_params (SimulationParameters) – The original SimulationParameters object from which the SimulationParameters object that will be created by this method came from.

Returns

sim_params – The corresponding SimulationParameters object.

Return type

SimulationParameters

static _from_dict(d)[source]

Create a new SimulationParameters object from a dictionary.

Parameters

d (dict) – The dictionary with the data.

Returns

The new SimulationParameters object.

Return type

SimulationParameters

_to_dict()[source]

Convert the SimulationParameters object to a dictionary for easier further serialization.

add(name, value)[source]

Adds a new parameter to the SimulationParameters object.

If there is already a parameter with the same name it will be replaced.

Parameters
  • name (str) – Name of the parameter.

  • value (anything) – Value of the parameter.

static create(params_dict)[source]

Creates a new SimulationParameters object.

This static method provides a different way to create a SimulationParameters object, already containing the parameters in the params_dict dictionary.

Parameters

params_dict (dict) – Dictionary containing the parameters. Each dictionary key corresponds to a parameter’s name, while the dictionary value corresponds to the actual parameter value..

Returns

sim_params – The corresponding SimulationParameters object.

Return type

SimulationParameters

property fixed_parameters

Names of the parameters which are NOT marked to be unpacked.

Returns

List with the names of the fixed parameter.

Return type

list[str]

get_num_unpacked_variations()[source]

Get the number of variations when the parameters are unpacked.

If no parameter was marked to be unpacked, then return 1.

If this SimulationParameters object is actually a ‘unpacked variation’ of another SimulationParameters object, return the number of variations of the parent SimulationParameters object instead.

Returns

num – The number of variations when the parameters are unpacked.

Return type

int

get_pack_indexes(fixed_params_dict=None)[source]

When you call the function get_unpacked_params_list you get a list of SimulationParameters objects corresponding to all combinations of the parameters. The function get_pack_indexes allows you to provided all parameters marked to be unpacked except one, and returns the indexes of the list returned by get_unpacked_params_list that you want.

Parameters

fixed_params_dict (dict[str, anything]) – A dictionary with the name of the fixed parameters as keys and the fixed value as value.

Returns

indexes – The desired indexes (1D numpy array or an integer).

Return type

np.ndarray

Examples

Suppose we have

>>> p={'p1':[1,2,3], 'p2':['a','b'],'p3':15}
>>> params=SimulationParameters.create(p)
>>> params.set_unpack_parameter('p1')
>>> params.set_unpack_parameter('p2')

If we call params.get_unpacked_params_list we will get a list of six SimulationParameters objects, one for each combination of the values of p1 and p2. That is,

>>> len(params.get_unpacked_params_list())
6

Likewise, in the simulation the SimulationRunner object will return a list of results in the order corresponding to the order of the list of parameters. The get_pack_indexes is used to get the index of the results corresponding to a specific configuration of parameters. Suppose now you want the results when ‘p2’ is varying, but with the other parameters fixed to some specific value. For this create a dictionary specifying all parameters except ‘p2’ and call get_pack_indexes with this dictionary. You will get an array of indexes that can be used in the results list to get the desired results. For instance

>>> fixed={'p1':3,'p3':15}
>>> indexes = params.get_pack_indexes(fixed)
>>> index0 = indexes[0]
>>> index1 = indexes[1]
>>> unpacked_list = params.get_unpacked_params_list()
>>> unpacked_list[index0]['p1']
3
>>> unpacked_list[index0]['p3']
15
>>> unpacked_list[index1]['p1']
3
>>> unpacked_list[index1]['p3']
15
get_unpacked_params_list()[source]

Get a list of SimulationParameters objects, each one corresponding to a possible combination of (unpacked) parameters.

Returns

A list of SimulationParameters objects.

Return type

list[SimulationParameters]

Examples

Suppose you have a SimulationParameters object with the parameters ‘a’, ‘b’, ‘c’ and ‘d’ as below

>>> simparams = SimulationParameters()
>>> simparams.add('a', 1)
>>> simparams.add('b', 2)
>>> simparams.add('c', [3, 4])
>>> simparams.add('d', [5, 6])

and the parameters ‘c’ and ‘d’ were set to be unpacked.

>>> simparams.set_unpack_parameter('c')
>>> simparams.set_unpack_parameter('d')

Then get_unpacked_params_list would return a list of four SimulationParameters objects as below

>>> len(simparams.get_unpacked_params_list())
4

That is

[{'a': 1, 'c': 3, 'b': 2, 'd': 5},
 {'a': 1, 'c': 3, 'b': 2, 'd': 6},
 {'a': 1, 'c': 4, 'b': 2, 'd': 5},
 {'a': 1, 'c': 4, 'b': 2, 'd': 6}]
static load_from_config_file(filename, spec=None, save_parsed_file=False)[source]

Load the SimulationParameters from a config file using the configobj module.

If the config file has a parameter called unpacked_parameters, which should be a list of strings with the names of other parameters, then these parameters will be set to be unpacked.

Parameters
  • filename (str) – Name of the file from where the results will be loaded.

  • spec (list[str], optional) – A list of strings with the config spec. See “validation” in the configobj module documentation for more info.

  • save_parsed_file (bool) – If save_parsed_file is True, then the parsed config file will be written back to disk. This will add any missing values in the config file whose default values are provided in the spec. This will even create the file if all default values are provided in spec and the file does not exist yet.

Notes

Besides the usual checks that the configobj validation has such as integer, string, option, etc., you can also use real_numpy_array for numpy float arrays. Note that when this validation function is used you can set the array in the config file in several ways such as

SNR=0,5,10,15:20

for instance.

static load_from_pickled_file(filename)[source]

Load the SimulationParameters from the file ‘filename’ previously stored (using pickle) with save_to_pickled_file.

Parameters

filename (str) – Name of the file from where the results will be loaded.

Returns

The loaded SimulationParameters object.

Return type

SimulationParameters

remove(name)[source]

Remove the parameter with name name from the SimulationParameters object

Parameters

name (str) – Name of the parameter to be removed.

Raises

KeyError – If name is not in parameters.

save_to_pickled_file(filename)[source]

Save the SimulationParameters object to the file filename using pickle.

Parameters

filename (str) – Name of the file to save the parameters.

set_unpack_parameter(name, unpack_bool=True)[source]

Set the unpack property of the parameter with name name.

The parameter name must be already added to the SimulationParameters object and be an iterable.

This is used in the SimulationRunner class.

Parameters
  • name (str) – Name of the parameter to be unpacked.

  • unpack_bool (bool, optional) – True activates unpacking for name, False deactivates it.

Raises

ValueError – If name is not in parameters or is not iterable.

property unpack_index

Get method for the unpack_index property.

Returns

The unpack index. Ir this SimulationParameters object is not an unpacked SimulationParameters then -1 is returned.

Return type

int

property unpacked_parameters

Names of the parameters marked to be unpacked.

Returns

Return type

list[str]

pyphysim.simulations.parameters.combine_simulation_parameters(params1, params2)[source]

Combine two SimulationParameters objects and return a new SimulationParameters object corresponding to the union of them.

The union is only valid if both objects have the same parameters and only the values of the unpacked parameters are different.

Parameters
Returns

union – The union of ‘params1’ and ‘params2’.

Return type

SimulationParameters

pyphysim.simulations.results module

Module containing simulation result classes.

class pyphysim.simulations.results.Result(name: str, update_type_code: int, accumulate_values: bool = False, choice_num: Optional[int] = None)[source]

Bases: pyphysim.util.serialize.JsonSerializable

Class to store a single simulation result.

A simulation result can be anything, such as the number of errors, a string, an error rate, etc. When creating a Result object one needs to specify only the name of the stored result and the result type.

The different types indicate how multiple samples (from multiple iterations) of the same Result can be merged (usually to get a result with more statistical reliability). The possible values are SUMTYPE, RATIOTYPE and MISCTYPE.

In the SUMTYPE the new value should be added to current one in update function.

In the RATIOTYPE the new value should be added to current one and total should be also updated in the update function. One caveat is that rates are stored as a number (numerator) and a total (denominator) instead of as a float. For instance, if you need to store a result such as a bit error rate, then you could use the a Result with the RATIOTYPE type and when updating the result, pass the number of bit errors and the number of simulated bits.

The MISCTYPE type can store anything and the update will simple replace the stored value with the current value.

Parameters
  • name (str) – Name of the Result.

  • update_type_code (int) – Type of the result. It must be one of the elements in {Result.SUMTYPE, Result.RATIOTYPE, Result.MISCTYPE, Result.CHOICETYPE}.

  • accumulate_values (bool) – If True, then the values value and total will be accumulated in the update (and merge) method(s). This means that the Result object will use more memory as more and more values are accumulated, but having all values sometimes is useful to perform statistical calculations. This is useful for debugging/testing.

  • choice_num (int) – Number of different choices for the CHOICETYPE type. This is a required parameter for the CHOICETYPE type, but it is ignored for the other types

Examples

  • Example of the SUMTYPE result.

    >>> result1 = Result("name", Result.SUMTYPE)
    >>> result1.update(13)
    >>> result1.update(4)
    >>> result1.get_result()
    17
    >>> result1.num_updates
    2
    >>> result1
    Result -> name: 17
    >>> result1.type_name
    'SUMTYPE'
    >>> result1.type_code
    0
    
  • Example of the RATIOTYPE result.

    >>> result2 = Result("name2", Result.RATIOTYPE)
    >>> result2.update(4,10)
    >>> result2.update(3,4)
    >>> result2.get_result()
    0.5
    >>> result2.type_name
    'RATIOTYPE'
    >>> result2.type_code
    1
    >>> result2_other = Result("name2", Result.RATIOTYPE)
    >>> result2_other.update(3,11)
    >>> result2_other.merge(result2)
    >>> result2_other.get_result()
    0.4
    >>> result2_other.num_updates
    3
    >>> result2_other._value
    10
    >>> result2_other._total
    25
    >>> result2.get_result()
    0.5
    >>> print(result2_other)
    Result -> name2: 10/25 -> 0.4
    
  • Example of the MISCTYPE result.

    The MISCTYPE result ‘merge’ process in fact simple replaces the current stored value with the new value.

CHOICETYPE = 3
MISCTYPE = 2
RATIOTYPE = 1
SUMTYPE = 0
_all_types = {0: 'SUMTYPE', 1: 'RATIOTYPE', 2: 'MISCTYPE', 3: 'CHOICETYPE'}
static _from_dict(d: Dict[str, Any])pyphysim.simulations.results.Result[source]

Convert from a dictionary to a Result object.

Parameters

d (dict) – The dictionary representing the Result.

Returns

The converted object.

Return type

Result

_to_dict() → Dict[str, Any][source]

Convert the Result object to a dictionary representation.

Returns

The dictionary representation of the object.

Return type

dict

property accumulate_values_bool

Property to see if values are accumulated of not during a call to the update method.

static create(name: str, update_type: int, value: Any, total: int = 0, accumulate_values: bool = False)pyphysim.simulations.results.Result[source]

Create a Result object and update it with value and total at the same time.

Equivalent to creating the object and then calling its update() method.

Parameters
  • name (str) – Name of the Result.

  • update_type (int) – Type of the result. It must be one of the elements in {Result.SUMTYPE, Result.RATIOTYPE, Result.MISCTYPE, Result.CHOICETYPE}.

  • value (any) – Value of the result.

  • total (any | int | float) – Total value of the result (used only for the RATIOTYPE and CHOICETYPE). For the CHOICETYPE it is interpreted as the number of different choices if it is an integer or the current value of each choice if it is a list.

  • accumulate_values (bool) – If True, then the values value and total will be accumulated in the update (and merge) method(s). This means that the Result object will use more memory as more and more values are accumulated, but having all values sometimes is useful to perform statistical calculations. This is useful for debugging/testing.

Returns

The new Result object.

Return type

Result

Notes

Even if accumulate_values is True the values will not be accumulated for the MISCTYPE.

See also

update()

get_confidence_interval(P: float = 95.0)numpy.ndarray[source]

Get the confidence interval that contains the true result with a given probability P.

Parameters

P (float) – The desired confidence (probability in %) that true value is inside the calculated interval. The possible values are described in the documentation of the calc_confidence_interval() function`

Returns

Interval – Numpy (float) array with two elements.

Return type

np.ndarray

See also

calc_confidence_interval()

get_result() → Any[source]

Get the result stored in the Result object.

Returns

results – For the RATIOTYPE type get_result will return the value/total, while for the other types it will return value.

Return type

anything, but usually a number

get_result_accumulated_totals() → List[Any][source]

Return the accumulated values.

Note that in case the result if of type RATIOTYPE this you probably want to call the get_result_accumulated_values function to also get the values.

get_result_accumulated_values() → List[Any][source]

Return the accumulated values.

Note that in case the result if of type RATIOTYPE this you probably want to call the get_result_accumulated_totals function to also get the totals.

get_result_mean()float[source]

Get the mean of all the updated results.

Returns

The mean of the result.

Return type

float

get_result_var()float[source]

Get the variance of all updated results.

Returns

The variance of the results.

Return type

float

merge(other: pyphysim.simulations.results.Result)None[source]

Merge the result from other with self.

Parameters

other (Result) – Another Result object.

property type_code

Get the Result type.

Returns

type_code – The returned value is a number corresponding to one of the types SUMTYPE, RATIOTYPE, MISCTYPE or CHOICETYPE.

Return type

int

property type_name

Get the Result type name.

Returns

type_name – The result type string (SUMTYPE, RATIOTYPE, MISCTYPE or CHOICETYPE).

Return type

str

update(value: Any, total: Optional[Any] = None)None[source]

Update the current value.

Parameters
  • value (anything, but usually a number) – Value to be added to (or replaced) the current value

  • total (same type as value) – Value to be added to the current total (only useful for the RATIOTYPE update type)

Notes

The way how this update process depends on the Result type and is described below

  • RATIOTYPE: Add “value” to current value and “total” to current total.

  • SUMTYPE: Add “value” to current value. “total” is ignored.

  • MISCTYPE: Replace the current value with “value”.

  • CHOICETYPE: Update the choice “value” and the total by 1.

See also

create()

class pyphysim.simulations.results.SimulationResults[source]

Bases: pyphysim.util.serialize.JsonSerializable

Store results from simulations.

This class is used in the SimulationRunner class in order to store results from a simulation. It is able to combine the results from multiple iterations (of the SimulationRunner._run_simulation() method in the SimulationRunner class) as well as append results for different simulation parameters configurations.

Note

Each result stored in the SimulationResults object is in fact an object of the Result class. This is required so that multiple SimulationResults objects can be merged together, since the logic to merge each individual result is in the the Result class.

Examples

  • Creating a SimulationResults object and adding a few results to it

    result1 = Result.create(...)  # See the Result class for details
    result2 = Result.create(...)
    result3 = Result.create(...)
    simresults = SimulationResults()
    simresults.add_result(result1)
    simresults.add_result(result2)
    simresults.add_result(result3)
    

    Instead of explicitly create a Result object and add it to the SimulationResults object, we can also create the Result object on-the-fly when adding it to the SimulationResults object by using the add_new_result() method.

    That is

    simresults = SimulationResults()
    simresults.add_new_result(...)
    simresults.add_new_result(...)
    simresults.add_new_result(...)
    
  • Merging multiple SimulationResults objects

    # First SimulationResults object
    simresults = SimulationResults()
    # Create a Result object
    result = Result.create('some_name', Result.SUMTYPE, 4)
    # and add it to the SimulationResults object.
    simresults.add_result(result)
    
    # Second SimulationResults object
    simresults2 = SimulationResults()
    # We can also create the Result object on-the-fly when adding it
    # to the SimulationResults object to save one line.
    simresults2.add_new_result('some_name', Result.SUMTYPE, 6)
    
    # We can merge the results in the second SimulationResults object.
    # Since the update type of the single result stored is SUMTYPE,
    # then the simresults will now have a single Result of SUMTYPE
    # type with a value of 10.
    simresults.merge_all_results(simresults)
    

See also

runner.SimulationRunner

Base class to implement Monte Carlo simulations.

parameters.SimulationParameters

Class to store the simulation parameters.

Result

Class to store a single simulation result.

static _from_dict(d: Dict[str, Any])pyphysim.simulations.results.SimulationResults[source]

Convert from a dictionary to a SimulationResults object.

Parameters

d (dict) – The dictionary representing the SimulationResults.

Returns

The converted object.

Return type

SimulationResults

static _load_from_json_file(filename: str)pyphysim.simulations.results.SimulationResults[source]
static _load_from_pickle_file(filename: str)pyphysim.simulations.results.SimulationResults[source]
_save_to_json(filename: str)None[source]

Save the SimulationResults object to the json file with name filename.

Parameters

filename (src) – Name of the file to save the SimulationResults object.

_save_to_pickle(filename: str)None[source]

Save the SimulationResults object to the pickle file with name filename.

Parameters

filename (src) – Name of the file to save the SimulationResults object.

_to_dict() → Dict[str, Any][source]

Convert the SimulationResults object to a dictionary representation.

Returns

The dictionary representation of the SimulationResults object.

Return type

dict

add_new_result(name: str, update_type: int, value: Any, total: Any = 0)None[source]

Create a new Result object on the fly and add it to the SimulationResults object.

Note

This is Equivalent to the code below,

result = Result.create(name, update_type, value, total)
self.add_result(result)

which in fact is exactly how this method is implemented.

Parameters
  • name (str) – Name of the Result.

  • update_type (int) – Type of the result (SUMTYPE, RATIOTYPE, MISCTYPE or CHOICETYPE).

  • value (any) – Value of the result.

  • total (any | int) – Total value of the result (used only for the RATIOTYPE and ignored for the other types).

add_result(result: pyphysim.simulations.results.Result)None[source]

Add a result object to the SimulationResults object.

Note

If there is already a result stored with the same name, this will replace it.

Parameters

result (Result) – The Result object to add to the simulation results.

append_all_results(other: pyphysim.simulations.results.SimulationResults)None[source]

Append all the results of the other SimulationResults object with self.

Parameters

other (SimulationResults) – Another SimulationResults object

append_result(result: pyphysim.simulations.results.Result)None[source]

Append a result to the SimulationResults object.

This effectively means that the SimulationResults object will now store a list for the given result name. This allow you, for instance, to store multiple bit error rates with the ‘BER’ name such that simulation_results_object[‘BER’] will return a list with the Result objects for each value.

Parameters

result (Result) – The Result object to append to the simulation results.

Notes

If multiple values for some Result are stored, then only the last value can be updated with merge_all_results().

Raises

ValueError – If the result has a different type from the result previously stored.

get_filename_with_replaced_params(filename: str)str[source]

Perform the string replacements in filename with simulation parameters.

Parameters

filename (str) – Name of the file to save the results. This can have string placements for replacements of simulation parameters. For instance, is filename is “somename_{age}.pickle” and the value of an ‘age’ parameter is ‘3’, then the actual name used to save the file will be “somename_3.pickle”

Returns

The name of the file where the results were saved. This will be equivalent to filename after string replacements (with the simulation parameters) are done.

Return type

string

get_result_names() → List[str][source]

Get the names of all results stored in the SimulationResults object.

Returns

names – The names of the results stored in the SimulationResults object.

Return type

list[str]

get_result_values_confidence_intervals(result_name: str, P: float = 95.0, fixed_params: Optional[Dict[str, Any]] = None) → List[numpy.ndarray][source]

Get the values for the results with name result_name.

This method is similar to the get_result_values_list method, but instead of returning a list with the values it will return a list with the confidence intervals for those values.

Parameters
  • result_name (str) – The name of the desired result.

  • P (float) –

  • fixed_params (dict) – A python dictionary containing the fixed parameters. If fixed_params is provided then the returned list will be only a subset of the results that match the fixed values of the parameters in the fixed_params argument, where the key is the parameter’s name and the value is the fixed value. See the notes in the documentation of get_result_values_list() for an example.

Returns

confidence_interval_list – A list of Numpy (float) arrays. Each element in the list is an array with two elements, corresponding to the lower and upper limits of the confidence interval.8

Return type

list[np.ndarray]

See also

calc_confidence_interval()

get_result_values_list(result_name: str, fixed_params: Optional[Dict[str, Any]] = None) → List[Any][source]

Get the values for the results with name result_name.

Returns a list with the values.

Parameters
  • result_name (str) – The name of the desired result.

  • fixed_params (dict) – A python dictionary containing the fixed parameters. If fixed_params is provided then the returned list will be only a subset of the results that match the fixed values of the parameters in the fixed_params argument, where the key is the parameter’s name and the value is the fixed value. See the notes for an example.

Returns

result_list – A list with the stored values for the result with name result_name

Return type

List

Notes

As an example of the usage of the fixed_params argument, suppose the results where obtained in a simulation for three parameters: ‘first’, with value ‘A’, ‘second’ with value ‘[1, 2, 3]’ and ‘third’ with value ‘[B, C]’, where the ‘second’ and ‘third’ were set to be unpacked. In that case the returned result list would have a length of 6 (the number of possible combinations of the parameters to be unpacked). If fixed_params is provided with the value of “{‘second’: 2}” that means that only the subset of results which corresponding to the second parameters having the value of ‘2’ will be provided and the returned list will have a length of 2. If fixed_params is provided with the value of “{‘second’: ‘1’, ‘third’: ‘C’}” then a single result will be provided instead of a list.

static load_from_file(filename: str)pyphysim.simulations.results.SimulationResults[source]

Load the SimulationResults from the file filename.

Parameters

filename (src) – Name of the file from where the results will be loaded.

Returns

The SimulationResults object loaded from the file filename.

Return type

SimulationResults

merge_all_results(other: pyphysim.simulations.results.SimulationResults)None[source]

Merge all the results of the other SimulationResults object with the results in self.

When there is more then one result with the same name stored in self (for instance two bit error rates -> for different parameters) then only the last one will be merged with the one in other. That also means that only one result for that name should be stored in other.

Parameters

other (SimulationResults) – Another SimulationResults object

Notes

This method is used in the SimulationRunner class to combine results of two simulations for the exact same parameters.

property params

Get method for the params property.

save_to_file(filename: str)str[source]

Save the SimulationResults to the file filename.

The string in filename can have placeholders for string replacements with any parameter value.

Parameters

filename (src) – Name of the file to save the results. This can have string placements for replacements of simulation parameters. For instance, is filename is “somename_{age}.pickle” and the value of an ‘age’ parameter is ‘3’, then the actual name used to save the file will be “somename_3.pickle”

Returns

The name of the file where the results were saved. This will be equivalent to filename after string replacements (with the simulation parameters) are done.

Return type

string

set_parameters(params: pyphysim.simulations.parameters.SimulationParameters)None[source]

Set the parameters of the simulation used to generate the simulation results stored in the SimulationResults object.

Parameters

params (SimulationParameters) – A SimulationParameters object containing the simulation parameters.

to_dataframe() → pandas.core.frame.DataFrame[source]

Convert the SimulationResults object to a pandas DataFrame.

pyphysim.simulations.results.combine_simulation_results(simresults1: pyphysim.simulations.results.SimulationResults, simresults2: pyphysim.simulations.results.SimulationResults)pyphysim.simulations.results.SimulationResults[source]

Combine two SimulationResults objects with different parameters values.

For this function to work both simulation objects need to have exact the same parameters and only the values of the parameters set to be unpacked can be different.

Parameters
  • simresults1 (SimulationResults) – The first SimulationResults object to be combined.

  • simresults2 (SimulationResults) – The second SimulationResults object to be combined.

Returns

The combined SimulationResults object.

Return type

SimulationResults

Examples

If the first SimulationResults object was obtained for the parameters “p1 = 10” and “p2 = [1, 2, 3]”, while the second SimulationResults object was obtained for the parameters “p1 = 10” and “p2 = [2, 4, 6]” and p2 was marked to be unpacked in both of them, then the returned combined SimulationResults object will have parameters “p1 = 10” and “p2 = [1, 2, 3, 4, 6]” with p2 marked to be unpacked.

Note that the results for the values of p2 equal to “2” and “4” exist in both objects and will be merged together.

pyphysim.simulations.runner module

Module containing the simulation runner.

class pyphysim.simulations.runner.SimulationRunner(default_config_file: Optional[str] = None, config_spec: Optional[str] = None, read_command_line_args: bool = True, save_parsed_file: bool = False)[source]

Bases: object

Base class to run Monte Carlo simulations.

The main idea of the SimulationRunner class is that in order to implement a Monte Carlo simulation one would subclass SimulationRunner and implement the _run_simulation() method (as well as any of the optional methods). The complete procedure is described in the documentation of the simulations module.

Note: If a given run of _run_simulation cannot finish and save results for some reason then you should raise a SkipThisOne exception. For instance if your _run_simulation implementation inverts a matrix for some reason and in rare cases the matrix you are trying to invert might be singular. You might want too raise a SkipThisOne exception if that occurs to simple “try again”.

The code below illustrates the minimum pseudo code to implement a subclass of SimulationRunner.

class SomeSimulator(SimulationRunner):
def __init__(self):
    super().__init__()
    # Do whatever you need/want

    # Add the simulation parameters to the `params` attribute.
    self.params.add('par1', par1value)
    ...
    self.params.add('parN', parNvalue)
    # Optionally set some parameter(s) to be unpacked
    self.params.set_unpack_parameter('name_of_a_parameter')

def _run_simulation(self, current_parameters):
    # Get the simulation parameters from the current_parameters
    # object. If no parameter was marked to be unpacked, then
    # current_parameters will be equivalent to self.params.
    par1 = current_parameters['par1']
    ...
    parN = current_parameters['parN']

    # Do the simulation of one iteration using the parameters
    # par1,...parN from the current_parameters object.
    ...

    # Save the results of this iteration to a SimulationResults
    # object and return it
    simResults = SimulationResults()
    simResults.add_new_result(...)  # Add one each result you want
    simResults.add_new_result(...)
    return simResults

With that, all there is left to run the simulation is to create a SomeSimulator object and call its simulate() method.

Parameters
  • default_config_file (str) – Name of the config file. This will be parsed with configobj.

  • config_spec (list[str]) – Configuration specification to validate the config file.

  • read_command_line_args (bool) – If True (default), read and parse command line arguments.

  • save_parsed_file (bool) – If True, the config file will be saved after it is loaded. This is useful to add the default parameters to the config file so that they can be easily changed later. Note that if the config file does not exist at all, then it will be saved regardless of the value of save_parsed_file.

See also

SimulationResults

Class to store simulation results.

SimulationParameters

Class to store the simulation parameters.

Result

Class to store a single simulation result.

static _SimulationRunner__create_default_ipyparallel_view()

Create a default view for parallel computation.

This method is run in the simulate_in_parallel method if a “view” is not passed.

_SimulationRunner__run_simulation_and_track_elapsed_time(current_parameters: pyphysim.simulations.parameters.SimulationParameters)pyphysim.simulations.results.SimulationResults

Perform the _run_simulation method and track its execution time. This time will be added as a Result to the returned SimulationResults object from _run_simulation.

Parameters

current_parameters (SimulationParameters) – SimulationParameters object with the parameters for the simulation. The self.params variable is not used directly. It is first unpacked in the simulate function which then calls _run_simulation for each combination of unpacked parameters.

Returns

The current simulation results.

Return type

SimulationResults

Notes

This method is called in the simulate and simulate_in_parallel.

_keep_going(current_params: pyphysim.simulations.parameters.SimulationParameters, current_sim_results: pyphysim.simulations.results.SimulationResults, current_rep: int)bool[source]

Check if the simulation should continue or stop.

This function may be reimplemented in the derived class if a stop condition besides the number of iterations is desired. The idea is that _run_simulation returns a SimulationResults object, which is then passed to _keep_going, which is then in charge of deciding if the simulation should stop or not.

Parameters
  • current_params (SimulationParameters) – SimulationParameters object with the parameters of the simulation.

  • current_sim_results (SimulationResults) – SimulationResults object from the last iteration (merged with all the previous results)

  • current_rep (int) – Number of iterations already run.

Returns

result – True if the simulation should continue or False otherwise.

Return type

bool

Notes

This method should be simple (it will be run many times) and SHOULD NOT modify the object.

_on_simulate_current_params_finish(current_params: pyphysim.simulations.parameters.SimulationParameters, current_params_sim_results: pyphysim.simulations.results.SimulationResults)None[source]

This method is called once for each simulation parameters combination after all iterations of _run_simulation are performed (for that combination of simulation parameters).

Parameters
  • current_params (SimulationParameters) – The current combination of simulation parameters.

  • current_params_sim_results (SimulationResults) – SimulationResults object with the results for the finished simulation with the parameters in current_params.

Notes

Because this method will run inside the _run_simulation method, which is called in a different process when the simulation is performed in parallel, it should only modify member variables that are only used inside _run_simulation.

_on_simulate_current_params_start(current_params: pyphysim.simulations.parameters.SimulationParameters)None[source]

This method is called once for each simulation parameters combination before any iteration of _run_simulation is performed (for that combination of simulation parameters).

Parameters

current_params (SimulationParameters) – The current combination of simulation parameters.

Notes

Because this method will run inside the _run_simulation method, which is called in a different process when the simulation is performed in parallel, it should only modify member variables that are only used inside _run_simulation. If any other variable is modified these changes WILL NOT be carried back to the original process.

_on_simulate_finish()None[source]

This method is called only once at the end of the simulate method.

_on_simulate_start()None[source]

This method is called only once, in the beginning of the the simulate method.

_run_simulation(current_parameters: pyphysim.simulations.parameters.SimulationParameters)pyphysim.simulations.results.SimulationResults[source]

Performs one iteration of the simulation.

This function must be implemented in a subclass. It should take the needed parameters from the params class attribute (which was filled in the constructor of the derived class) and return the results as a SimulationResults object.

Note that _run_simulation will be called self.rep_max times (or less if an early stop criteria is reached, which requires reimplementing the _keep_going function in the derived class) and the results from multiple repetitions will be merged.

Parameters

current_parameters (SimulationParameters) – SimulationParameters object with the parameters for the simulation. The self.params variable is not used directly. It is first unpacked in the simulate function which then calls _run_simulation for each combination of unpacked parameters.

Returns

simulation_results – A SimulationResults object containing the simulation results of the run iteration.

Return type

SimulationResults

_simulate_common_setup()[source]

Common setup code that must run in the beginning of a simulation.

_simulate_for_current_params_common(current_params: pyphysim.simulations.parameters.SimulationParameters, update_progress_func: Callable[[int], None] = <function SimulationRunner.<lambda>>) → Tuple[int, pyphysim.simulations.results.SimulationResults, str][source]
Parameters
  • current_params (SimulationParameters) – The current parameters

  • update_progress_func ((int) -> []) – The function that can be called to update the current progress.

Returns

The value of current_rep, the current results as a SimulationResults object, and the name of the file storing partial results.

Return type

(int, SimulationResults, str)

static _simulate_for_current_params_parallel(obj: pyphysim.simulations.runner.SimulationRunner, current_params: pyphysim.simulations.parameters.SimulationParameters, update_progress_func=None) → Tuple[int, pyphysim.simulations.results.SimulationResults, str][source]

Simulate (parallel) for the current parameters.

Parameters
  • obj (SimulationRunner) – The same as the self parameter in regular methods. The reason that this method is set to static is to allow it to be pickled.

  • current_params (SimulationParameters) – The current parameters

  • update_progress_func ((int) -> []) – The function (or an object with __call__ operator) that can be called to update the current progress.

Returns

The value of current_rep, the current results as a SimulationResults object, and the name of the file storing partial results.

Return type

(int, SimulationResults, str)

_simulate_for_current_params_serial(current_params: pyphysim.simulations.parameters.SimulationParameters) → Tuple[int, pyphysim.simulations.results.SimulationResults, str][source]

Simulate (serial) for the current parameters.

Parameters

current_params (SimulationParameters) – The current parameters

Returns

The value of current_rep, the current results as a SimulationResults object, and the name of the file storing partial results.

Return type

(int, SimulationResults, str)

clear()None[source]

Clear the SimulationRunner.

This will erase any results from previous simulations as well as other internal variables. The SimulationRunner object will then be as if it was just created, except that the simulation parameters will be kept.

property delete_partial_results_bool
property elapsed_time

Get the simulation elapsed time. Do not set this value.

Returns

The elapsed time.

Return type

float

property params
property partial_results_folder
property progress_output_type
property progressbar_message
property results
property results_filename
property runned_reps

Get method for the runned_reps property.

Returns

The value of the runned_reps property, which stores the number of runned repetitions for each unpacked parameters combination.

Return type

list[int]

set_results_filename(filename: Optional[str] = None)None[source]

Set the name of the file where the simulation results will be saved.

This must be done before calling the simulate of the simulate_in_parallel methods.

The filename argument is formatted with the simulation parameters. That is, suppose there are two parameters Nr=2 and Nt=1, then if filename is equal to “results_for_{Nr}x{Nt}” the actual name of the file used to store the simulation results will be “results_for_2x1.pickle”.

The advantage of setting the name of the results file with set_results_filename instead of manually saving the results after the simulation is finished is that partial results will also be saved. Therefore the simulation can be stopped and continued later from these partial results.

Parameters

filename (str) – The name of the file (without extension) where the simulation results will be stored. If not provided the results will not be automatically stored.

simulate(param_variation_index: Optional[int] = None)None[source]

Performs the full Monte Carlo simulation (serially).

Implements the general code for every simulation. Any code specific to a single simulation iteration must be implemented in the _run_simulation method of a subclass of SimulationRunner.

The main idea behind the SimulationRunner class is that the general code in every simulator is implemented in the SimulationRunner class, more specifically in the simulate method, while the specific code of a single iteration is implemented in the _run_simulation method in a subclass.

Parameters

param_variation_index (int, optional) – If not provided, the full simulation will be run. If this is provided the simulation will be run only for the parameters variation with index given by param_variation_index. In that case, calling the set_results_filename method before the simulate method is required since only the partial results will be saved.

simulate_common_cleaning()[source]

Common code that must run in the end of a simulation

simulate_in_parallel(view: Optional[Union[ipyparallel.client.view.LoadBalancedView, ipyparallel.client.view.DirectView]] = None, wait: bool = True)None[source]

Same as the simulate method, but the different parameters configurations are simulated in parallel.

Parameters
  • view (LoadBalancedView | DirectView) – A ´view´ of the IPython engines. The parallel processing will happen by calling the ‘map’ method of the provided view to simulate in parallel the different configurations of transmission parameters.

  • wait (bool) – If True then the self.wait_parallel_simulation method will be automatically called at the end of simulate_in_parallel. If False, the YOU NEED to manually call self.wait_parallel_simulation at some point after calling simulate_in_parallel.

Notes

There is a limitation regarding the partial simulation results. The partial results files will be saved in the folder where the IPython engines are running, since the “saving part” is performed in an IPython engine. However, the deletion of the files is not performed in by the IPython engines, but by the main python program. Therefore, unless the Ipython engines are running in the same folder where the main python program will be run the partial result files won’t be automatically deleted after the simulation is finished.

property update_progress_function_style
wait_parallel_simulation()None[source]

Wait for the parallel simulation to finish and then update the self.results variable (as well as other internal variables).

exception pyphysim.simulations.runner.SkipThisOne(msg: str)[source]

Bases: Exception

Exception that can be raised in the _run_simulation method to skip the current repetition.

The simulate method will not count a run of _run_simulation if it throws a SkipThisOne exception.

Parameters

msg (str) – The message with more information on why the exception was raised.

pyphysim.simulations.runner.get_partial_results_filename(results_base_filename: str, current_params: pyphysim.simulations.parameters.SimulationParameters, partial_results_folder: Optional[str] = None)str[source]

Get the name of the file where the partial result will be saved for the unpacked result with index unpack_index.

Parameters
  • results_base_filename (str) – Base name for partial result file.

  • current_params (SimulationParameters) – The current parameters, which must be a “unpacked variation” of another SimulationParameters object.

  • partial_results_folder (str, optional) – The folder where the partial results will be stored.

Returns

partial_results_filename – The name of the partial results file.

Return type

str

pyphysim.simulations.simulationhelpers module

Module implementing helper functions for simulators.

pyphysim.simulations.simulationhelpers._add_folder_to_ipython_engines_path(client: ipyparallel.client.client.Client, folder: str)None[source]

Add a folder to sys.path of each ipython engine.

The list of engines is get as a direct view from ‘client’.

This will also add the folder to the local python path.

Parameters
  • client (Client) – The client from which we will get a direct view to access the engines.

  • folder (str) – The folder to be added to the python path at each engine.

pyphysim.simulations.simulationhelpers._simulate_do_what_i_mean_multiple_runners(list_of_runners: List[pyphysim.simulations.runner.SimulationRunner], folder: Optional[str] = None)None[source]

This will either call the simulate method or the simulate_in_parallel method as appropriated.

If the ‘parameters variation index’ was specified in the command line, then the simulate method will be called with that index. If not, then the simulate method will be called without any index or, if there is an ipython cluster running, the simulate_in_parallel method will be called.

Parameters
  • list_of_runners (list[SimulationRunner]) – The _simulate_do_what_i_mean_single_runner will be called for each object in the list.

  • folder (str) – Folder to be added to the python path. This should be the main pyphysim folder.

pyphysim.simulations.simulationhelpers._simulate_do_what_i_mean_single_runner(runner: pyphysim.simulations.runner.SimulationRunner, folder: Optional[str] = None, block: bool = True)None[source]

This will either call the simulate method or the simulate_in_parallel method as appropriated.

If the ‘parameters variation index’ was specified in the command line, then the simulate method will be called with that index. If not, then the simulate method will be called without any index or, if there is an ipython cluster running, the simulate_in_parallel method will be called.

Parameters
  • runner (SimulationRunner) – The SimulationRunner object for which either the ‘simulate’ or the ‘simulate_in_parallel’ method will be called.

  • folder (str, optional) – Folder to be added to the python path. This should be the main pyphysim folder

  • block (bool, optional) – Passed to the simulate_in_parallel method when the simulation is performed in parallel. If this is false, you need to call the method ‘wait_parallel_simulation’ of the runner object at some point.

pyphysim.simulations.simulationhelpers.simulate_do_what_i_mean(runner_or_list_of_runners: Union[pyphysim.simulations.runner.SimulationRunner, List[pyphysim.simulations.runner.SimulationRunner]], folder: Optional[str] = None)None[source]

This will either call the simulate method or the simulate_in_parallel method as appropriated.

If the ‘parameters variation index’ was specified in the command line, then the ‘simulate’ method will be called with that index. If not, then the simulate method will be called without any index or, if there is an ipython cluster running, the simulate_in_parallel method will be called.

Parameters
  • runner_or_list_of_runners (SimulationRunner | list[SimulationRunner]) – The SimulationRunner object for which either the ‘simulate’ or the ‘simulate_in_parallel’ method will be called. If this is a list, then we just call this method individually for each member of the list.

  • folder (str) – Folder to be added to the python path. This should be the main pyphysim folder

Module contents

Module containing useful classes to implement Monte Carlo simulations.

The main class for Monte Carlo simulations is the runner.SimulationRunner class, but a few other classes are also implemented to handle simulation parameters and simulation results.

More specifically, the simulations module implements the classes:

For a description of how to implement Monte Carlo simulations using the classes defined in the simulations module see the section Implementing Monte Carlo simulations.