math-spec-mapping 0.3.6__tar.gz → 0.3.8__tar.gz

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.
Files changed (65) hide show
  1. {math_spec_mapping-0.3.6/src/math_spec_mapping.egg-info → math_spec_mapping-0.3.8}/PKG-INFO +4 -3
  2. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/README.md +3 -2
  3. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/pyproject.toml +1 -1
  4. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/MathSpec.py +123 -3
  5. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Convenience/starter.py +25 -11
  6. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8/src/math_spec_mapping.egg-info}/PKG-INFO +4 -3
  7. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/LICENSE +0 -0
  8. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/setup.cfg +0 -0
  9. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/ActionTransmissionChannel.py +0 -0
  10. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Block.py +0 -0
  11. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/BoundaryAction.py +0 -0
  12. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/ControlAction.py +0 -0
  13. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Entity.py +0 -0
  14. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Mechanism.py +0 -0
  15. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Metric.py +0 -0
  16. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Parameter.py +0 -0
  17. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Policy.py +0 -0
  18. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Space.py +0 -0
  19. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/State.py +0 -0
  20. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/StateUpdateTransmissionChannel.py +0 -0
  21. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/StatefulMetric.py +0 -0
  22. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/Type.py +0 -0
  23. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Classes/__init__.py +0 -0
  24. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Convenience/__init__.py +0 -0
  25. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Convenience/documentation.py +0 -0
  26. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/__init__.py +0 -0
  27. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/action_transmission_channel.py +0 -0
  28. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/boundary_actions.py +0 -0
  29. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/control_actions.py +0 -0
  30. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/displays.py +0 -0
  31. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/entities.py +0 -0
  32. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/general.py +0 -0
  33. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/implementations.py +0 -0
  34. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/load.py +0 -0
  35. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/mechanism.py +0 -0
  36. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/metrics.py +0 -0
  37. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/parameters.py +0 -0
  38. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/policy.py +0 -0
  39. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/spaces.py +0 -0
  40. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/state_update_transmission_channels.py +0 -0
  41. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/stateful_metrics.py +0 -0
  42. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/states.py +0 -0
  43. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/type.py +0 -0
  44. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Load/wiring.py +0 -0
  45. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/__init__.py +0 -0
  46. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/boundary_actions.py +0 -0
  47. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/control_actions.py +0 -0
  48. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/general.py +0 -0
  49. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/html.py +0 -0
  50. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/markdown.py +0 -0
  51. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/mechanisms.py +0 -0
  52. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/node_map.py +0 -0
  53. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/parameters.py +0 -0
  54. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/policies.py +0 -0
  55. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/spaces.py +0 -0
  56. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/state.py +0 -0
  57. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/tables.py +0 -0
  58. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/Reports/wiring.py +0 -0
  59. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/__init__.py +0 -0
  60. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/schema.py +0 -0
  61. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping/schema.schema.json +0 -0
  62. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping.egg-info/SOURCES.txt +0 -0
  63. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping.egg-info/dependency_links.txt +0 -0
  64. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping.egg-info/requires.txt +0 -0
  65. {math_spec_mapping-0.3.6 → math_spec_mapping-0.3.8}/src/math_spec_mapping.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: math-spec-mapping
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: A library for easy mapping of mathematical specifications.
5
5
  Author-email: Sean McOwen <Sean@Block.Science>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -45,8 +45,9 @@ Writing mathematical specifications can be a difficult process, especially when
45
45
  ```mermaid
46
46
  graph TD
47
47
  A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to the json specification \n Defines all aspects of the spec including blocks, spaces and actions] -->B[MSML Object \n\n JSON file is parsed, with validations and mappings along the way \n Can show different views on the fly]
48
- B --> C[Report Outputs \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ]
49
-
48
+ B --> C[Report Outputs & Obsidian Directory \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ\n Also builds an entire Obsidian directory of all components as linked notes]
49
+ D[Python Function Implementations \n\n Optional enhancement to actually execute code\n Done for each referenced policy option, mechanism, etc. \n Just needs a function definition for each] --> B
50
+ B --> E[Python Wirings & Simulations \n\n MSML can be used to run blocks \n Wirings automatically work to pass between domain/codomains \n Entire simulations can be built up as composed wirings]
50
51
  ```
51
52
 
52
53
  ## MSML in the Engineering Lifecycle
@@ -30,8 +30,9 @@ Writing mathematical specifications can be a difficult process, especially when
30
30
  ```mermaid
31
31
  graph TD
32
32
  A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to the json specification \n Defines all aspects of the spec including blocks, spaces and actions] -->B[MSML Object \n\n JSON file is parsed, with validations and mappings along the way \n Can show different views on the fly]
33
- B --> C[Report Outputs \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ]
34
-
33
+ B --> C[Report Outputs & Obsidian Directory \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ\n Also builds an entire Obsidian directory of all components as linked notes]
34
+ D[Python Function Implementations \n\n Optional enhancement to actually execute code\n Done for each referenced policy option, mechanism, etc. \n Just needs a function definition for each] --> B
35
+ B --> E[Python Wirings & Simulations \n\n MSML can be used to run blocks \n Wirings automatically work to pass between domain/codomains \n Entire simulations can be built up as composed wirings]
35
36
  ```
36
37
 
37
38
  ## MSML in the Engineering Lifecycle
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
  [project]
5
5
  name = "math-spec-mapping"
6
- version = "0.3.6"
6
+ version = "0.3.8"
7
7
  authors = [
8
8
  { name="Sean McOwen", email="Sean@Block.Science" },
9
9
  ]
@@ -7,6 +7,7 @@ from .BoundaryAction import BoundaryAction
7
7
  import os
8
8
  from copy import deepcopy
9
9
  import shutil
10
+ import pandas as pd
10
11
 
11
12
 
12
13
  class MathSpec:
@@ -469,6 +470,83 @@ class MathSpec:
469
470
  with open(path, "w") as f:
470
471
  f.write(out)
471
472
 
473
+ def run_experiment(
474
+ self,
475
+ experiment,
476
+ params_base,
477
+ state_base,
478
+ post_processing_function,
479
+ state_preperation_functions=None,
480
+ parameter_preperation_functions=None,
481
+ metrics_functions=None,
482
+ ):
483
+ if experiment["Param Modifications"]:
484
+ params_base = deepcopy(params_base)
485
+ for key in experiment["Param Modifications"]:
486
+ params_base[key] = experiment["Param Modifications"][key]
487
+ if experiment["State Modifications"]:
488
+ state_base = deepcopy(state_base)
489
+ for key in experiment["State Modifications"]:
490
+ state_base[key] = experiment["State Modifications"][key]
491
+ msi = self.build_implementation(params_base)
492
+ state, params = msi.prepare_state_and_params(
493
+ state_base,
494
+ params_base,
495
+ state_preperation_functions=state_preperation_functions,
496
+ parameter_preperation_functions=parameter_preperation_functions,
497
+ )
498
+
499
+ state = msi.execute_blocks(state, params, experiment["Blocks"])
500
+ df = post_processing_function(state, params)
501
+
502
+ if metrics_functions:
503
+ metrics = {}
504
+ for metrics_function in metrics_functions:
505
+ metrics_function(metrics, state, params, df)
506
+ metrics = pd.Series(metrics)
507
+ else:
508
+ metrics = None
509
+
510
+ return state, params, msi, df, metrics
511
+
512
+ def run_experiments(
513
+ self,
514
+ experiments,
515
+ params_base,
516
+ state_base,
517
+ post_processing_function,
518
+ state_preperation_functions=None,
519
+ parameter_preperation_functions=None,
520
+ metrics_functions=None,
521
+ ):
522
+ state_l = []
523
+ params_l = []
524
+ df_l = []
525
+ metrics_l = []
526
+ for experiment in experiments:
527
+ for i in range(experiment["Monte Carlo Runs"]):
528
+ state, params, msi, df, metrics = self.run_experiment(
529
+ experiment,
530
+ params_base,
531
+ state_base,
532
+ post_processing_function,
533
+ state_preperation_functions=state_preperation_functions,
534
+ parameter_preperation_functions=parameter_preperation_functions,
535
+ metrics_functions=metrics_functions,
536
+ )
537
+ df["Monte Carlo Run"] = i + 1
538
+ df["Experiment"] = experiment["Name"]
539
+ metrics.loc["Monte Carlo Run"] = i + 1
540
+ metrics.loc["Experiment"] = experiment["Name"]
541
+ metrics.name = "{}-{}".format(experiment["Name"], i + 1)
542
+ state_l.append(state)
543
+ params_l.append(params)
544
+ df_l.append(df)
545
+ metrics_l.append(metrics)
546
+ df = pd.concat(df_l)
547
+ metrics = pd.concat(metrics_l, axis=1).T
548
+ return df, metrics, state_l, params_l
549
+
472
550
  def metaprogramming_python_states(
473
551
  self, model_directory, overwrite=False, default_values=None
474
552
  ):
@@ -698,6 +776,7 @@ class MathSpecImplementation:
698
776
  self.mechanisms = self.load_mechanisms()
699
777
  self.stateful_metrics = self.load_stateful_metrics()
700
778
  self.load_wiring()
779
+ self.load_components()
701
780
 
702
781
  def load_control_actions(self):
703
782
  control_actions = {}
@@ -776,6 +855,9 @@ class MathSpecImplementation:
776
855
 
777
856
  def load_single_wiring(self, wiring):
778
857
  hold = wiring
858
+ domain_sizes = {}
859
+ for x in wiring.components:
860
+ domain_sizes[x.name] = len(x.domain)
779
861
  components = [x.name for x in wiring.components]
780
862
  if wiring.block_type == "Stack Block":
781
863
 
@@ -795,10 +877,17 @@ class MathSpecImplementation:
795
877
  spaces_mapping[x].append(i)
796
878
 
797
879
  def wiring(state, params, spaces):
880
+ spaces_mapping_temp = deepcopy(spaces_mapping)
798
881
  codomain = []
799
882
  for component in components:
800
- if component in spaces_mapping:
801
- spaces_i = [spaces[i] for i in spaces_mapping[component]]
883
+ if component in spaces_mapping_temp:
884
+ spaces_i = [spaces[i] for i in spaces_mapping_temp[component]][
885
+ : domain_sizes[component]
886
+ ]
887
+ # Fix for repeated block names
888
+ spaces_mapping_temp[component] = spaces_mapping_temp[component][
889
+ domain_sizes[component] :
890
+ ]
802
891
  else:
803
892
  assert component in [
804
893
  x.name for x in hold.domain_blocks_empty
@@ -926,9 +1015,40 @@ class MathSpecImplementation:
926
1015
  len(shouldnt_be_in_params) == 0
927
1016
  ), "The following parameters are extra: {}".format(shouldnt_be_in_params)
928
1017
 
929
- def prepare_state_and_params(self, state, params):
1018
+ def prepare_state_and_params(
1019
+ self,
1020
+ state,
1021
+ params,
1022
+ state_preperation_functions=None,
1023
+ parameter_preperation_functions=None,
1024
+ ):
930
1025
  self.validate_state_and_params(state, params)
931
1026
  state = deepcopy(state)
932
1027
  params = deepcopy(params)
933
1028
  state["Stateful Metrics"] = self.stateful_metrics
1029
+ if state_preperation_functions:
1030
+ for f in state_preperation_functions:
1031
+ state = f(state)
1032
+ assert (
1033
+ state is not None
1034
+ ), "A state must be returned from the state preperation functions"
1035
+ if parameter_preperation_functions:
1036
+ for f in parameter_preperation_functions:
1037
+ params = f(params)
1038
+ assert (
1039
+ params is not None
1040
+ ), "A parameter set must be returned from the parameter preperation functions"
934
1041
  return state, params
1042
+
1043
+ def load_components(self):
1044
+ self.components = {}
1045
+ self.components.update(self.control_actions)
1046
+ self.components.update(self.boundary_actions)
1047
+ self.components.update(self.policies)
1048
+ self.components.update(self.mechanisms)
1049
+ self.components.update(self.wiring)
1050
+
1051
+ def execute_blocks(self, state, params, blocks):
1052
+ for block in blocks:
1053
+ self.components[block](state, params, [])
1054
+ return state
@@ -39,19 +39,27 @@ def remove_dummy_repo_components(path):
39
39
  with open(path2 + "/__init__.py", "w") as f:
40
40
  f.write(contents)
41
41
 
42
- """if "Displays" in directory_folders:
42
+ if "Displays" in directory_folders:
43
43
  path2 = path + "/Displays"
44
44
  contents = os.listdir(path2)
45
- if "Dummy.py" in contents:
46
- os.remove(path2 + "/Dummy.py")
47
- if "__init__.py" in contents:
48
- with open(path2 + "/__init__.py", "r") as f:
45
+ if "wiring.py" in contents:
46
+ with open(path2 + "/wiring.py", "r") as f:
49
47
  contents = f.read()
50
- contents = contents.replace("from .Dummy import metrics_x\n", "")
51
- contents = contents.replace("metrics.extend(metrics_x)\n", "")
52
- contents = contents.replace("metrics.extend(metrics_x)", "")
53
- with open(path2 + "/__init__.py", "w") as f:
54
- f.write(contents)"""
48
+
49
+ contents = contents.replace('"Dummy Boundary Wiring 2",\n', "")
50
+ contents = contents.replace('"Dummy Boundary Wiring 2",', "")
51
+ contents = contents.replace('"Dummy Boundary Wiring 2"', "")
52
+
53
+ contents = contents.replace('"Dummy Boundary Wiring",\n', "")
54
+ contents = contents.replace('"Dummy Boundary Wiring",', "")
55
+ contents = contents.replace('"Dummy Boundary Wiring"', "")
56
+
57
+ contents = contents.replace('"Dummy Control Wiring",\n', "")
58
+ contents = contents.replace('"Dummy Control Wiring",', "")
59
+ contents = contents.replace('"Dummy Control Wiring"', "")
60
+
61
+ with open(path2 + "/wiring.py", "w") as f:
62
+ f.write(contents)
55
63
 
56
64
  if "Wiring" in directory_folders:
57
65
  path2 = path + "/Wiring"
@@ -104,8 +112,14 @@ def remove_dummy_repo_components(path):
104
112
  with open(path2 + "/__init__.py", "r") as f:
105
113
  contents = f.read()
106
114
  contents = contents.replace(
107
- "from .Dummy import dummy_boundary_action\n", ""
115
+ "from .Dummy import dummy_boundary_action, dummy_boundary_action2\n",
116
+ "",
108
117
  )
118
+
119
+ contents = contents.replace("dummy_boundary_action2,\n", "")
120
+ contents = contents.replace("dummy_boundary_action2,", "")
121
+ contents = contents.replace("dummy_boundary_action2", "")
122
+
109
123
  contents = contents.replace("dummy_boundary_action,\n", "")
110
124
  contents = contents.replace("dummy_boundary_action,", "")
111
125
  contents = contents.replace("dummy_boundary_action", "")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: math-spec-mapping
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: A library for easy mapping of mathematical specifications.
5
5
  Author-email: Sean McOwen <Sean@Block.Science>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -45,8 +45,9 @@ Writing mathematical specifications can be a difficult process, especially when
45
45
  ```mermaid
46
46
  graph TD
47
47
  A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to the json specification \n Defines all aspects of the spec including blocks, spaces and actions] -->B[MSML Object \n\n JSON file is parsed, with validations and mappings along the way \n Can show different views on the fly]
48
- B --> C[Report Outputs \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ]
49
-
48
+ B --> C[Report Outputs & Obsidian Directory \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ\n Also builds an entire Obsidian directory of all components as linked notes]
49
+ D[Python Function Implementations \n\n Optional enhancement to actually execute code\n Done for each referenced policy option, mechanism, etc. \n Just needs a function definition for each] --> B
50
+ B --> E[Python Wirings & Simulations \n\n MSML can be used to run blocks \n Wirings automatically work to pass between domain/codomains \n Entire simulations can be built up as composed wirings]
50
51
  ```
51
52
 
52
53
  ## MSML in the Engineering Lifecycle