diff --git a/.github/workflows/prod.yml b/.github/workflows/prod.yml index 636238e..19d6248 100644 --- a/.github/workflows/prod.yml +++ b/.github/workflows/prod.yml @@ -43,8 +43,9 @@ jobs: run: | git lfs pull pip install -i https://test.pypi.org/simple/ hadar + pip install jupyter click cd examples - python3 check.py + python3 utils.py --src=./ --check=./ - name: Release pypi.org run: | diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index d9667d9..fcdc359 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -34,8 +34,9 @@ jobs: run: | git lfs pull export PYTHONPATH=$(pwd) + pip install click jupyter cd examples - python3 check.py + python3 utils.py --src=./ --check=./ - name: Release test.pypi.org run: | diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..6e9618f --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,11 @@ +# Contributor Code of Conduct + +As contributors and maintainers of the Hadar project, we pledge to respect everyone who contributes by posting issues, updating documentation, submitting pull requests, providing feedback in comments, and any other activities. + +Communication through any of Hadar's channels (TODO) must be constructive and never resort to personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. + +We promise to extend courtesy and respect to everyone involved in this project regardless of gender, gender identity, sexual orientation, disability, age, race, ethnicity, religion, or level of experience. We expect anyone contributing to the Hadar project to do the same. + +If any member of the community violates this code of conduct, the maintainers of the Hadar project may take action, removing issues, comments, and PRs or blocking accounts as deemed appropriate. + +If you are subject to or witness unacceptable behavior, or have any other concerns, please email us at [contact@hadar-simulator.org](mailto:contact@hadar-simulator.org). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e1db4d5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,4 @@ +# Contributing +We appreciate your helps + +Before fillings issue, please read [Contribution Guide](https://doc.hadar-simulator.org/en/develop/dev-guide/devops.html) diff --git a/docs/source/_static/architecture/analyzer/ulm-index.png b/docs/source/_static/architecture/analyzer/ulm-index.png new file mode 100644 index 0000000..4d8ba4b Binary files /dev/null and b/docs/source/_static/architecture/analyzer/ulm-index.png differ diff --git a/docs/source/_static/architecture/optimizer/lpoptimizer.png b/docs/source/_static/architecture/optimizer/lpoptimizer.png new file mode 100644 index 0000000..9d94f9b Binary files /dev/null and b/docs/source/_static/architecture/optimizer/lpoptimizer.png differ diff --git a/docs/source/_static/architecture/optimizer/ulm-optimizer.png b/docs/source/_static/architecture/optimizer/ulm-optimizer.png new file mode 100644 index 0000000..226893b Binary files /dev/null and b/docs/source/_static/architecture/optimizer/ulm-optimizer.png differ diff --git a/docs/source/_static/architecture/workflow/fault.png b/docs/source/_static/architecture/workflow/fault.png new file mode 100644 index 0000000..77d0579 Binary files /dev/null and b/docs/source/_static/architecture/workflow/fault.png differ diff --git a/docs/source/_static/architecture/workflow/monte-carlo.png b/docs/source/_static/architecture/workflow/monte-carlo.png new file mode 100644 index 0000000..f285348 Binary files /dev/null and b/docs/source/_static/architecture/workflow/monte-carlo.png differ diff --git a/docs/source/_static/architecture/workflow/shuffler.png b/docs/source/_static/architecture/workflow/shuffler.png new file mode 100644 index 0000000..01c9353 Binary files /dev/null and b/docs/source/_static/architecture/workflow/shuffler.png differ diff --git a/docs/source/_static/get-started-1.png b/docs/source/_static/get-started-1.png deleted file mode 100644 index 8f30848..0000000 Binary files a/docs/source/_static/get-started-1.png and /dev/null differ diff --git a/docs/source/_static/get-started-2.png b/docs/source/_static/get-started-2.png deleted file mode 100644 index 5eb6134..0000000 Binary files a/docs/source/_static/get-started-2.png and /dev/null differ diff --git a/docs/source/_static/get-started-3.png b/docs/source/_static/get-started-3.png deleted file mode 100644 index bd5d202..0000000 Binary files a/docs/source/_static/get-started-3.png and /dev/null differ diff --git a/docs/source/architecture/analyzer.rst b/docs/source/architecture/analyzer.rst new file mode 100644 index 0000000..578942d --- /dev/null +++ b/docs/source/architecture/analyzer.rst @@ -0,0 +1,195 @@ +Analyzer +======== + +For a high abstraction and to be agnostic about technology, Hadar uses objects as glue for optimizer. Objects are cool, but are too complicated to manipulated for data analysis. Analyzer contains tools to help analyzing study result. + +Today, there is only :code:`ResultAnalyzer`, with two features level: + +* **high level** user asks directly to compute global cost and global remain capacity, etc. + +* **low level** user asks *raw* data represented inside pandas Dataframe. + +Before speaking about this features, let's see how data are transformed. + +Flatten Data +--------- + +As said above, object is nice to encapsulate data and represent it into agnostic form. Objects can be serialized into JSON or something else to be used by another software maybe in another language. But keep object to analyze data is awful. + +Python has a very efficient tool for data analysis : pandas. Therefore challenge is to transform object into pandas Dataframe. Solution used is to flatten data to fill into table. + +Consumption +*********** + +For example with consumption. Data into :code:`Study` is cost and asked quantity. And in :code:`Result` it's cost (same) and given quantity. This tuple *(cost, asked, given)* is present for each node, each consumption attached on this node, each scenario and each timestep. If we want to flatten data, we need to fill this table + ++------+------+------+------+------+------+------+ +| cost | asked| given| node | name | scn | t | ++------+------+------+------+------+------+------+ +| 10 | 5 | 5 | fr | load | 0 | 0 | ++------+------+------+------+------+------+------+ +| 10 | 7 | 7 | fr | load | 0 | 1 | ++------+------+------+------+------+------+------+ +| 10 | 7 | 5 | fr | load | 1 | 0 | ++------+------+------+------+------+------+------+ +| 10 | 6 | 6 | fr | load | 1 | 1 | ++------+------+------+------+------+------+------+ +| ... | ... | ... | ... | ... | .. | ... | ++------+------+------+------+------+------+------+ + +It is the purpose of :code:`_build_consumption(study: Study, result: Result) -> pd.Dataframe` to build this array + +Production +********** + +Production follow the same pattern. However, they don't have *asked* and *given* but *available* and *used* quantity. Therefore table looks like + ++------+------+------+------+------+------+------+ +| cost | avail| used | node | name | scn | t | ++------+------+------+------+------+------+------+ +| 10 | 100 | 21 | fr | coal | 0 | 0 | ++------+------+------+------+------+------+------+ +| 10 | 100 | 36 | fr | coal | 0 | 1 | ++------+------+------+------+------+------+------+ +| 10 | 100 | 12 | fr | coal | 1 | 0 | ++------+------+------+------+------+------+------+ +| 10 | 100 | 81 | fr | coal | 1 | 1 | ++------+------+------+------+------+------+------+ +| ... | ... | ... | ... | ... | .. | ... | ++------+------+------+------+------+------+------+ + +It's done by :code:`_build_production(study: Study, result: Result) -> pd.Dataframe` method. + + +Link +**** + +Link follow the same pattern. Hierarchical structure naming change. There are not *node* and *name* but *source* and *destination*. Therefore table looks like. + ++------+------+------+------+------+------+------+ +| cost | avail| used | src | dest | scn | t | ++------+------+------+------+------+------+------+ +| 10 | 100 | 21 | fr | uk | 0 | 0 | ++------+------+------+------+------+------+------+ +| 10 | 100 | 36 | fr | uk | 0 | 1 | ++------+------+------+------+------+------+------+ +| 10 | 100 | 12 | fr | uk | 1 | 0 | ++------+------+------+------+------+------+------+ +| 10 | 100 | 81 | fr | uk | 1 | 1 | ++------+------+------+------+------+------+------+ +| ... | ... | ... | ... | ... | .. | ... | ++------+------+------+------+------+------+------+ + +It's done by :code:`_build_link(study: Study, result: Result) -> pd.Dataframe` method. + + +Low level analysis +------------------ + +When you observe flat data, there are two kind of data. *Content* like cost, given, asked and *index* describes by node, name, scn, t. + +Low level API analysis provided by :code:`ResultAnalyzer` lets user to + +#. Organize index level, for example set time, then scenario, then name, then node. +#. Filter index, for example just time from 10 to 150, just 'fr' node, etc + +User can said, *I want 'fr' node productions for first scenario to 50 until 60 timestep.* In this cas :code:`ResultAnalyzer` will return + ++------+------+------+------+------+ +| | | used | cost | avail| ++------+------+------+------+------+ +| t | name | 21 | fr | uk | ++------+------+------+------+------+ +| 50 | oil | 36 | fr | uk | ++ +------+------+------+------+ +| | coal | 12 | fr | uk | ++------+------+------+------+------+ +| 60 | oil | 81 | fr | uk | ++ +------+------+------+------+ +| ... | ... | ... | ... | ... | ++------+------+------+------+------+ + +If first index like node and scenario has only one element, there are removed. + +This result can be done by this line of code. :: + + agg = hd.ResultAnalyzer(study, result) + df = agg.agg_prod(agg.inode['fr'], agg.scn[0], agg.itime[50:60], agg.iname) + +As you can see, user select index hierarchy by sorting :code:`agg.ixxx` . Then user specify filter by :code:`agg.ixxx[yy]`. + +Behind this mechanism, there are :code:`Index` objects. As you can see directly in the code :: + + @property + def inode(self) -> NodeIndex: + """ + Get a node index to specify node slice to aggregate consumption or production. + + :return: new instance of NodeIndex() + """ + return NodeIndex() + + +Each kind of index has to inherent from this class. :code:`Index` object encapsulate column metadata to use and range of filtered elements to keep (accessible by overriding :code:`__getitem__` method). Then, Hadar has child classes with good parameters : :code:`NameIndex` , :code:`NodeIndex` , :code:`ScnIndex` , :code:`TimeIndex` , :code:`SrcIndex` , :code:`DestIndex` . For example you can find below :code:`NodeIndex` implementation :: + + class NodeIndex(Index[str]): + """Index implementation to filter nodes""" + def __init__(self): + Index.__init__(self, column='node') + + +.. image:: /_static/architecture/analyzer/ulm-index.png +Index instantiation are completely hidden for user. It created implicitly when user types :code:`agg.ixxx[yy]`. Then, hadar will + +#. check that mandatory indexes are given with :code:`_assert_index` method. + +#. pivot table to recreate indexing according to filter and sort asked with :code:`_pivot` method. + +#. remove one-size top-level index with :code:`_remove_useless_index_level` method. + +As you can see, low level analyze provides efficient method to extract data from adequacy study result. However data returned remains a kind of *roots* and is not ready for business purposes. + +High Level Analysis +------------------- + +Unlike low level, high level focus on provides ready to use data. Unlike low level, features should be designed one by one for business purpose. Today we have 2 features: + +* :code:`get_cost(self, node: str) -> np.ndarray:` method which according to node given returns a matrix (scenario, horizon) shape with summarize cost. + +* :code:`get_balance(self, node: str) -> np.ndarray` method which according to node given returns a matrix (scenario, horizon) shape with exchange balance (i.e. sum of exportation minus sum of importation) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +j diff --git a/docs/source/architecture/optimizer.rst b/docs/source/architecture/optimizer.rst new file mode 100644 index 0000000..209c4e8 --- /dev/null +++ b/docs/source/architecture/optimizer.rst @@ -0,0 +1,183 @@ +Optimizer +========= + +Optimizer is the heart of Hadar. Behind it, there are : + +#. Input object called :code:`Study`. Output object called :code:`Result`. These two objects encapsulate all data needed to compute adequacy. + +#. Many optimizers. User can chose which will solve study. + +Therefore :code:`Optimizer` is an abstract class build on *Strategy* pattern. User can select optimizer or create their own by implemented :code:`Optimizer.solve(study: Study) -> Result` + +Today, two optimizers are present :code:`LPOptimizer` and :code:`RemoteOptimizer` + +.. image:: /_static/architecture/optimizer/ulm-optimizer.png + :scale: 50% + +RemoteOptimizer +--------------- + +Let's start by the simplest. :code:`RemoteOptimizer` is a client to hadar server. As you may know Hadar exist like a python library, but has also a tiny project to package hadar inside web server. You can find more details on this server in this `repository. `_ + +Client implements :code:`Optimizer` interface. Like that, to deploy compute on a data-center, only one line of code changes. :: + + import hadar as hd + # Normal : optim = hd.LPOptimizer() + optim = hd.RemoteOptimizer(host='example.com') + res = optim.solve(study=study) + + +LPOptimizer +----------- + +Before read this chapter, we kindly advertise you to read :ref:`Linear Model ` + +:code:`LPOptimizer` translate data into optimization problem. Hadar algorithms focus only on modeling problem and uses `or-tools `_ to solve problem. + +To achieve modeling goal, :code:`LPOptimizer` is designed to receive :code:`Study` object, convert data into or-tools :code:`Variables`. Then :code:`Variables` are placed inside objective and constraint equations. Equations are solved by or-tools. Finally :code:`Variables` are converted to :code:`Result` object. + +Analyze that in details. + +InputMapper +************ + +If you look in code, you will see two domains. One at :code:`hadar.optimizer.[input/output]` and another at :code:`hadar.optimizer.lp.domain` . If you look carefully it seems the same :code:`Consumption` , :code:`OutputConsumption` in one hand, :code:`LPConsumption` in other hand. The only change is a new attribute in :code:`LP*` called :code:`variable` . Variables are the parameters of the problem. It's what or-tools has to find, i.e. power used for production, capacity used for border and lost of load for consumption. + +Therefore, :code:`InputMapper` roles are just to create new object with ortools Variables initialized, like we can see in this code snippet. :: + + # hadar.optimizer.lp.mapper.InputMapper.get_var + LPLink(dest=l.dest, + cost=float(l.cost), + src=name, + quantity=l.quantity[scn, t], + variable=self.solver.NumVar(0, float(l.quantity[scn, t]), + 'link on {} to {} at t={} for scn={}'.format(name, l.dest, t, scn) + ) + ) + +OutputMapper +************ + +At the end, :code:`OutputMapper` does the reverse thing. :code:`LP*` objects have computed :code:`Variables`. We need to extract result find by or-tool to :code:`Result` object. + +Mapping of :code:`LPProduction` and :code:`LPLink` are straight forward. I propose you to look at :code:`LPConsumption` code :: + + self.nodes[name].consumptions[i].quantity[scn, t] = + vars.consumptions[i].quantity - vars.consumptions[i].variable.solution_value() + +Line seems strange due to complex indexing. First we select good node *name*, then good consumption *i*, then good scenario *scn* and at the end good timestep *t*. Rewriting without index, this line means : + +.. math:: + Cons_{final} = Cons_{given} - Cons_{var} + +Keep in mind that :math:`Cons_{var}` is the lost of load. So we need to subtract it from initial consumption to get really consumption sustained. + +Modeler +******* + +Hadar has to build problem optimization. These algorithms are encapsulated inside two builders. + +:code:`ObjectiveBuilder` takes node by its method :code:`add_node`. Then for all productions, consumptions, links, it adds :math:`variable * cost` into objective equation. + +:code:`AdequacyBuilder` is a bit more tricky. For each node, it will create a new adequacy constraint equation (c.f. :ref:`Linear Model `). Coefficients, here are 1 or -1 depending of *inner* power or *outer* power. Have you seen these line ? :: + + self.constraints[(t, link.src)].SetCoefficient(link.variable, -1) # Export from src + self.importations[(t, link.src, link.dest)] = link.variable # Import to dest + +Hadar has to set power importation to *dest* node equation. But maybe this node is not yet setup and its constraint equation doesn't exist yet. Therefore it has to store all constraint equations and all link capacities. And at the end :code:`build()` is called, which will add importation terms into all adequacy constraints to finalize equations. :: + + def build(self): + """ + Call when all node are added. Apply all import flow for each node. + + :return: + """ + # Apply import link in adequacy + for (t, src, dest), var in self.importations.items(): + self.constraints[(t, dest)].SetCoefficient(var, 1) + + +:code:`solve_batch` method resolve study for one scenario. It iterates over node and time, calls :code:`InputMapper`, then constructs problem with :code:`*Buidler`, and asks or-tools to solve problem. + +:code:`solve_lp` applies the last iteration over scenarios and it's the entry point for linear programming optimizer. After all scenarios are solved, results are mapped to :code:`Result` object. + +.. image:: /_static/architecture/optimizer/lpoptimizer.png + +Or-tools, multiprocessing & pickle nightmare +............................................ + +Scenarios are distributed over cores by mutliprocessing library. :code:`solve_batch` is the compute method called by multiprocessing. Therefore all input data received by this method and output data returned must be serializable by pickle (used by multiprocessing). However, output has ortools :code:`Variable` object which is not serializable. + +Hadar doesn't need complete :code:`Variable` object. Indeed, it just want value solution found by or-tools. So we will help pickle by creating more simpler object, we carefully recreate same API :code:`solution_value()` to be compliant with downstream code :: + + class SerializableVariable(DTO): + def __init__(self, var: Variable): + self.val = var.solution_value() + + def solution_value(self): + return self.val + +Then specify clearly how to serialize object by implementing :code:`__reduce__` method :: + + # hadar.optimizer.lp.domain.LPConsumption + def __reduce__(self): + """ + Help pickle to serialize object, specially variable object + :return: (constructor, values...) + """ + return self.__class__, (self.quantity, SerializableVariable(self.variable), self.cost, self.name) + +It should work, but in fact not... I don't know why, when multiprocessing want to serialize returned data, or-tools :code:`Variable` are empty, and mutliprocessing failed. Whatever, we just need to handle serialization oneself :: + + # hadar.optimizer.lp.solver._solve_batch + return pickle.dumps(variables) + + +Study +----- + +:code:`Study` is a *API object* I means it encapsulates all data needed to compute adequacy. It's the glue between workflow (or any other preprocessing) and optimizer. Study has an hierarchical structure of 3 levels : + +#. node level with node name as key. + +#. type elements level with *consumption*, *production* and *link* entries. Represented by :code:`InputNode` object. + +#. element with index as key. Represented by :code:`Consumption`, :code:`Production`, :code:`Link` objects + +Most important attribute could be :code:`quantity` which represent quantity of power used in network. For link, is a transfert capacity. For production is a generation capacity. For consumption is a forced load to sustain. + +User can construct Study step by step thanks to a *fluent API* :: + + import hadar as hd + + study = hd.Study(['a', 'b'], horizon=3) \ + .add_on_node('a', data=hd.Consumption(cost=10 ** 6, quantity=[20, 20, 20], name='load')) \ + .add_on_node('a', data=hd.Production(cost=10, quantity=[30, 20, 10], name='prod')) \ + .add_on_node('b', data=hd.Consumption(cost=10 ** 6, quantity=[20, 20, 20], name='load')) \ + .add_on_node('b', data=hd.Production(cost=20, quantity=[10, 20, 30], name='prod')) \ + .add_link(src='a', dest='b', quantity=[10, 10, 10], cost=2) \ + .add_link(src='b', dest='a', quantity=[10, 10, 10], cost=2) \ + + + optim = hd.LPOptimizer() + res = optim.solve(study) + +To help user, quantity field is flexible: + +* lists are converted to numpy array + +* if user give a scalar, hadar extends to create (scenario, horizon) matrix size + +* if user give (horizon, ) matrix or list, hadar copies N time scenario to make (scenario, horizon) matrix size + +* if user give (scenario, 1) matrix or list, hadar copies N time timestep to make (scenario, horizon) matrix size + +Study includes also check mechanism to be sure: node exist, consumption is unique, etc. + +Result +------ + +:code:`Result` look like :code:`Study`, it has the same hierarchical structure, same element, just different naming to respect *Domain Driven Development* . Indeed, :code:`Result` is used as output computation, therefore we can't reuse the same object. +:code:`Result` is the glue between optimizer and analyzer (or any else postprocessing). + +:code:`Result` shouldn't be created by user. User will only read it. So, :code:`Result` has not fluent API to help construction. diff --git a/docs/source/architecture/overview.rst b/docs/source/architecture/overview.rst new file mode 100644 index 0000000..9618217 --- /dev/null +++ b/docs/source/architecture/overview.rst @@ -0,0 +1,91 @@ +Overview +======== + +Welcome to the Hadar Architecture Documentation. + +Hadar purpose is to be *an adequacy library for everyone*. + +#. Term *everyone* is important, Hadar must be such easy that everyone can use it. + +#. And Hadar must be such flexible that everyone business can use it or customize it. + +**Why these goals ?** + +We design Hadar in the same spirit of python libraries like numy or scipy, and moreover like scikit-learn. +Before scikit-learn, people who want to develop machine learning have to had strong skill in mathematics background to develop their own code. +Some *ready to go* codes existed but were not easy to use and flexible. + +Scikit-learn release the power of machine learning by abstract complex algorithms into very straight forward API. +It was designed like a toolbox to handle full machine learning framework, where user can just assemble scikit-learn component or build their own. + +Hadar want to be the next scikit-learn for adequacy. +Hadar has to be easy to use and flexible, which if we translate into architecture terms become **high abstraction level** and **independent modules**. + + +Independent modules +------------------- + +User has the choice : Use only Hadar components, assemble them and create a full solution to generate, solve and analyze adequacy study. Or build their parts. + + +To reach this constraint, we split Hadar into 4 main modules which can be use together or apart : + +- **workflow:** module used to generate data study. Hadar handle deterministic computation like stochastic. For stochastic computation user needs to generate many scenarios. Workflow will help user by providing a highly customizable pipeline framework to transform and generate data. + + +- **optimizer:** more complex and mathematical module. User will use it to describe study adequacy to resolve. No need to understand mathematics, Hadar will handle data input given and translate it to a linear optimization problem before to call a solver. + +- **analyzer:** input data given to optimizer and output date with study result can be heavy to analyze. To avoid that every user build their own toolbox, we develop the most used features once for everyone. + +- **viewer** analyzer output will be numpy matrix or pandas Dataframe, it great but not enough to analyze result. Viewer uses the analyzer feature and API to generate graphics from study data. + +As said, these modules can be used together to handle complete adequacy study lifecycle or used apart. + +TODO graph architecture module + + +High Abstraction API +-------------------- + +Each above modules are like a tiny independent libraries. Therefore each module has a high level API. +High abstraction, is a bit confuse to handle and benchmark. For us a high abstraction is when user doesn't need to know mathematics or technicals stuffs when he uses library. + +Scikit-learn is the best example of high abstraction level API. For example, if we just want to start a complete SVM research :: + + from sklean.svm import SVR + svm = SVR() + svm.fit(X_train, y_train) + y_pred = svm.predict(X_test) + + +How many people using this feature know that scikit-learn tries to project data into higher space to find a linear regression inside. And to accelerate computation, it uses mathematics a feature called *a kernel trick* because problem respect strict requirements ? Perhaps just few people and it's all the beauty of an high level API, it hidden background gear. + + +Hadar tries to keep this high abstraction features. Look at the *Get Started* example :: + + import hadar as hd + + study = hd.Study(['a', 'b'], horizon=3) \ + .add_on_node('a', data=hd.Consumption(cost=10 ** 6, quantity=[20, 20, 20], name='load')) \ + .add_on_node('a', data=hd.Production(cost=10, quantity=[30, 20, 10], name='prod')) \ + .add_on_node('b', data=hd.Consumption(cost=10 ** 6, quantity=[20, 20, 20], name='load')) \ + .add_on_node('b', data=hd.Production(cost=20, quantity=[10, 20, 30], name='prod')) \ + .add_link(src='a', dest='b', quantity=[10, 10, 10], cost=2) \ + .add_link(src='b', dest='a', quantity=[10, 10, 10], cost=2) \ + + + optim = hd.LPOptimizer() + res = optim.solve(study) + + +Create a study like you will draw it on a paper. Put your nodes, attach some production, consumption, link and run optimizer. + + +Go Next +------- + +Now goals are fixed, we can go deeper into specific module documentation. +All architecture focuses on : High Abstraction and Independent module. You can also read the best practices guide to understand more development choice made in Hadar. + + +Let't start code explanation. \ No newline at end of file diff --git a/docs/source/architecture/viewer.rst b/docs/source/architecture/viewer.rst new file mode 100644 index 0000000..cd22ab2 --- /dev/null +++ b/docs/source/architecture/viewer.rst @@ -0,0 +1,8 @@ +Viewer +====== + +Even with the highest level analyzer features. Data remains simple matrix or tables. Viewer is the end of Hadar framework, it will create amazing plot to bring most valuable data for human analysis. + +Viewer use Analyzer API to build plots. It like an extract layer to convert numeric result to visual result. + +There are many viewers, all inherent from :code:`ABCPlotting` abstract class. Available plots are identical between viewers, only technologies used to build these plots change. Today, we have one type of plotting :code:`HTMLPlotting` which is coded upon plotly library to build html interactive plots. diff --git a/docs/source/architecture/workflow.rst b/docs/source/architecture/workflow.rst new file mode 100644 index 0000000..3d4dace --- /dev/null +++ b/docs/source/architecture/workflow.rst @@ -0,0 +1,166 @@ +Workflow +======== + +What is a stochastic study ? +---------------------------- + + +Workflow is the preprocessing module for Hadar. It's a toolbox to create pipelines to transform data for optimizer. + +When you want to simulate a network adequacy, you can perform a *deterministic* computation. That means you believe you won't have too much fluky behavior in the future. If you perform adequacy for the next hour or day, it's a good hypothesis. But if you simulate network for the next week, month or year, it's sound curious. + +Are you sur wind will blow next week or sun will shines ? If not, you eolian or solar production could change. Can you warrant that no failure will occur on your network next month or next year ? + +Of course, we can not predict future with such precision. It's why we use *stochastic* computation. *Stochastic* means there are fluky behavior in the physics we want simulate. Simulation is quiet useless, if result is a unique result. + +The best solution could be to compute a *God function* which tell you for each input variation (solar production, line, consumptions) what is the adequacy result. Like that, Hadar has just to analyze function, its derivatives, min, max, etc to predict future. But this *God function* doesn't exist, we just have an algorithm which tell us adequacy according to one fixed set of input data. + + +It's why we use *Monte Carlo* algorithm. Monte Carlo run many *scenarios* to analyze many different behavior. Scenario with more consumption in cities, less solar production, less coal production or one line deleted due to crash. By this method we recreate *God function* by sampling it with the Monte-Carlo method. + + +.. image:: /_static/architecture/workflow/monte-carlo.png + + +Workflow will help user to generate these scenarios and sample them to create a stochastic study. + +The main issue when we want to *help people generating their scenarios* is they are as many generating process as user. +Therefore workflow is build upon a Stage and Pipeline Architecture. + + +Stages, Pipelines & Plug +------------------------ + +Stage is an atomic process applied on data. In workflow, data is a pandas Dataframe. Index is time. First column level is for scenario, second is for data (it could be anything like mean, max, sigma, ...). Dataframe is represented below: + ++----+-------------------------+-------------------------+ +| | scn 1 | scn n ... | ++----+------+-----+-----+------+------+-----+-----+------+ +| t | mean | max | min | ... | mean | max | min | ... | ++----+------+-----+-----+------+------+-----+-----+------+ +| 0 | 10 | 20 | 2 | ... | 15 | 22 | 8 | ... | ++----+------+-----+-----+------+------+-----+-----+------+ +| 1 | 12 | 20 | 2 | ... | 14 | 22 | 8 | ... | ++----+------+-----+-----+------+------+-----+-----+------+ +|... | ... | ... | ... | ... | ... | ... | ... | ... | ++----+------+-----+-----+------+------+-----+-----+------+ + +A stage will perform compute to this Dataframe. As you assume it, stages can be linked together to create pipeline. +Hadar has its own stages very generic, each user can build these stages and create these pipelines. + +For examples, you have many coal production. Each production plan has 10 generators of 100 MW. That means a coal plan production has 1,000 MW of power. You know that sometime, some generators crash or need shutdown for maintenance. With Hadar you can create a pipeline to generate these fault scenarios. :: + + # In this example, one timestep = one hour + import hadar as hd + import numpy as np + import hadar as hd + import matplotlib.pyplot as plt + + # coal production over 8 weeks with hourly step + coal = pd.DataFrame({'quantity': np.ones(8 * 168) * 1000}) + + # Copy scenarios ten times + copy = hd.RepeatScenario(n=10) + + # Apply on each scenario random fault, such as power drop is 100 MW, there is 0.1% chance of failure each hour + # if failure, it's a least for the whole day and until next week. + fault = hd.Fault(loss=100, occur_freq=0.001, downtime_min=24, downtime_max=168) + + pipe = copy + fault + out = pipe.compute(coal) + + out.plot() + plt.show() + +Output: + +.. image:: /_static/architecture/workflow/fault.png + +Create its own Stage +******************** + +:code:`RepeatScenario`, :code:`Fault` and all other are build upon :code:`Stage` abstract class. A Stage is specified by its :code:`Plug` (we will see sooner) and a :code:`_process_timeline(self, timeline: pd.DataFrame) -> pd.DataFrame` to implement. :code:`timeline` variable inside method is the data passed thought pipeline to transform. + +For example, you need to multiply by 2 during your pipeline. You can create your stage by :: + + class Twice(Stage): + def __init__(self): + Stage.__init__(self, FreePlug()) + + def _process_timeline(self, timelines: pd.DataFrame) -> pd.DataFrame: + return timelines * 2 + + +Implement Stage will work every time. Often, you want to apply function independently for each scenario. +You can of course handle yourself this mechanism to split current :code:`timeline` apply method and rebuild at the end. Or use :code:`FocusStage`, same thing but already coded. In this case, you need to inherent from :code:`FocusStage` and implement :code:`_process_scenarios(self, n_scn: int, scenario: pd.DataFrame) -> pd.DataFrame` method. + +For example, you have thousand of scenarios, your stage has to generate gaussian series according to mean and sigma given. :: + + class Gaussian(FocusStage): + def __init__(self): + FocusStage.__init__(self, plug=RestrictedPlug(input=['mean', 'sigma'], output=['gaussian'])) + + def _process_scenarios(self, n_scn: int, scenario: pd.DataFrame) -> pd.DataFrame: + scenario['gaussian'] = np.random.randn(scenario.shape[0]) + scenario['gaussian'] *= scenario['sigma'] + scenario['gaussian'] += scenario['mean'] + + return scenario.drop(['mean', 'sigma'], axis=1) + + +What's Plug ? +************* + +You are already see :code:`FreePlug` and :code:`RestrictedPlug`, what's it ? + +Stage are linked together to build pipeline. Some Stage accept every thing as input, like :code:`Twice`, but other need specific data like :code:`Gaussian`. How we know that stage can be link together and data given at the beginning of pipeline is correct for all pipeline. + +First solution is saying : *We don't care about. During execution, if data is missing, error will be raised and it's enough.* +Indeed... That's work, but if pipeline job is heavy, takes hour, and failed just due to a misspelling column name, it's ugly. + +:code:`Plug` object describe linkable constraint for Stage and Pipeline. Like Stage, Plug can be added together. In this case, constraint are merged. You can use :code:`FreePlug` telling this Stage is not constraint and doesn't expected any column name to run. Or use :code:`RestrictedPlug(inputs=[], outputs=[])` to specify inputs mandatory columns and new columns generated. + +Plug arithmetic rules are described below (:math:`\emptyset` = :code:`FreePlug`) + +.. math:: + \begin{array}{rcl} + \emptyset & + & \emptyset & = & \emptyset \\ + [a \rightarrow \alpha ] & + & \emptyset & = & [a \rightarrow \alpha ] \\ + [a \rightarrow \alpha ] & + & [\alpha \rightarrow A]& = & [a \rightarrow A] \\ + [a \rightarrow \alpha, \beta ] & + & [\alpha \rightarrow A]& = & [a \rightarrow A, \beta] \\ + \end{array} + + + +Shuffler +-------- + +User can create as many pipeline as he want. At the end, he could have some pipelines and input data or directly input data pre-generated. He needs to sampling this dataset to create study. For example, he could have 10 coal generation, 25 solar, 10 consumptions. He needs to create study with 100 scenarios. + +Of course he can develop sampling algorithm, but he can also use :code:`Shuffler`. Indeed Shuffler does a bit more than just sampling: + +#. It is like a sink where user put pipeline or raw data. Shuffler will homogeneous them to create scenarios. Behind code, we use :code:`Timeline` and :code:`PipelineTimeline` class to homogenize data according to raw data or data from output pipeline. + +#. It will schedule pipelines compute. If shuffler is used with pipeline, it will distribute pipeline running over computer cores. A good tips ! + +#. It samples data to create study scenarios. + +.. image:: /_static/architecture/workflow/shuffler.png + +Below an example how to use Shuffler :: + + shuffler = Shuffler() + # Add raw data as a numpy array + shuffler.add_data(name='solar', data=np.array([[1, 2, 3], [5, 6, 7]])) + + # Add pipeline and its input data + i = pd.DataFrame({(0, 'a'): [3, 4, 5], (1, 'a'): [7, 8, 9]}) + pipe = RepeatScenario(2) + ToShuffler('a') + shuffler.add_pipeline(name='load', data=i, pipeline=pipe) + + # Shuffle to sample 3 scenarios + res = shuffler.shuffle(3) + + # Get result according name given + solar = res['solar'] + load = res['load'] diff --git a/docs/source/dev-guide/contributing.rst b/docs/source/dev-guide/contributing.rst new file mode 100644 index 0000000..412d565 --- /dev/null +++ b/docs/source/dev-guide/contributing.rst @@ -0,0 +1,70 @@ +How to Contribute +================ + + +First off, thank you to considering contributing to Hadar. We believe technology can change the world. But only great community and open source can improve the world. + +Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue, assessing changes, and helping you finalize your pull requests. + +We try to describe most of Hadar behavior and organization to avoid any *shadow part*. Additionally, you can read *Dev Guide* section or *Architecture* to learn hadar purposes and processes. + +What kind of contribution ? +--------------------------- + +You can participate on Hadar from many ways: + +* just use it and spread it ! + +* write plugin and extension for hadar + +* Improve docs, code, examples + +* Add new features + +**Issue tracker are only for features, bug or improvment; not for support. If you have some question please go to TODO . Any support issue will be closed.** + +Feature / Improvement +-------------------- + +Little changes can be directly send into a pull request. Like : + +* Spelling / grammar fixes + +* Typo correction, white space and formatting changes + +* Comment clean up + +* Adding logging messages or debugging output + +For all other, you need first to create an issue. If issue receives good feedback. Then you can fork project, work on your side and send a Pull Request + +Bug +--- + +**If you find a security bug, please DON'T create an issue. Contact use at admin@hadar-simulator.org** + +First be sure it's a bug and not a misuse ! Issues are not for technical support. To speed up bug fixing (and avoid misuse), you need to clearly explain bug, with most simple step by step guide to reproduce bug. Specify us all details like OS, Hadar version and so on. + +Please provide us response to these questions :: + + - What version of Hadar and python are you using ? + - What operating system and processor architecture are you using? + - What did you do? + - What did you expect to see? + - What did you see instead? + + +Best Practices +-------------- + +We try to code the most clear and maintainable software. Your Pull Request has to follow some good practices: + + +- respect `PEP 8 `_ style guide +- name meaningful variables, method, class +- respect `SOLID `_ , `KISS `_ , `DRY `_ , `YAGNI `_ principe +- make code easy testable (use dependencies injection) +- test code (at least 80% UT code coverage) +- Add docstring for each class and method. + +TL;TR: code as Uncle Bob ! diff --git a/docs/source/dev-guide/repository.rst b/docs/source/dev-guide/repository.rst new file mode 100644 index 0000000..cf5081e --- /dev/null +++ b/docs/source/dev-guide/repository.rst @@ -0,0 +1,52 @@ +Repository Organization +======================= + +Hadar `repository `_ is split in many parts. + +* :code:`hadar/` source code + +* :code:`tests/` unit and integration tests perform by unittest + +* :code:`examples/` set of notebooks used like End to End test when executed during CI or like `tutorials `_ when exported to html. + +* :code:`docs/` sphinx documentation hosted by readthedocs at https://docs.hadar-simulator.org . Main website is hosted by Github Pages and source code can be find in `this repository `_ + +* :code:`.github/` github configuration to use Github Action for CI. + +Ticketing +------ + +We use all github features to organize development. We implement a Agile methodology and try to recreate Jira behavior in github. Therefore we swap Jira features to Github such as : + ++----------------------+---------------------+ +| Jira | github swap | ++======================+=====================+ +| User Story / Bug | Issue | ++----------------------+---------------------+ +| Version = Sprint | Project | ++----------------------+---------------------+ +| task | check list in issue | ++----------------------+---------------------+ +| Epic | Milestone | ++----------------------+---------------------+ + +Devops +------ + +We respect *git flow* pattern. Main developments are on :code:`develop` branch. We accept :code:`feature/**` branch but is not mandatory. + +CI pipelines are backed on *git flow*, actions are sum up in table below : + + ++----------+----------------+--------------------+----------------------+ +| action | develop | release/** | master | ++==========+================+====================+======================+ +| TU + IT |3.6, 3.7, 3.8 / | linux-3.7 | linux-3.7 | +| |linux, mac, win | | | ++----------+----------------+--------------------+----------------------+ +| E2E | | from source code | from test.pypip.org | ++----------+----------------+--------------------+----------------------+ +| Sonar | yes | yes | yes | ++----------+----------------+--------------------+----------------------+ +| package | | to test.pypip.org | to pypip.org | ++----------+----------------+--------------------+----------------------+ diff --git a/docs/source/graphics.drawio b/docs/source/graphics.drawio new file mode 100644 index 0000000..c3c20d7 --- /dev/null +++ b/docs/source/graphics.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index dc7d9dc..35e61a8 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -14,66 +14,55 @@ Welcome to Hadar! Hadar is a adequacy python library for deterministic and stochastic computation -Adequacy problem -^^^^^^^^^^^^^^^^ +You are in the technical documentation. -Each kind of network has a needs of adequacy. On one side, some network nodes need to consume -items such as watt, litter, package. And other side, some network nodes produce items. -Applying adequacy on network, is tring to find the best available exchanges to avoid any lack at the best cost. +* If you want to discover Hadar and the project, please go to https://www.hadar-simulator.org for an overview -For example, a electric grid can have some nodes wich produce too more power and some nodes wich produce not enough power. +* If you want to start using Hadar, you can begin with `tutorials `_ -.. image:: https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggTFJcblx0QVtBPGJyLz5sb2FkPTIwPGJyLz5wcm9kPTMwXSAtLT5CW0I8YnIvPmxvYWQ9MjA8YnIvPnByb2Q9MTBdXG5cdFx0XHRcdFx0IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifSwidXBkYXRlRWRpdG9yIjpmYWxzZX0 +* If you want to understand Hadar engine, see **Architecture** -In this case, A produce 10 more and B need 10 more. Perform adequecy is quiet easy : A will share 10 to B +* If you want to look at a method or object behavior search inside **References** -.. image:: https://mermaid.ink/img/eyJjb2RlIjoiZ3JhcGggTFJcblx0QVtBPGJyLz5sb2FkPTIwPGJyLz5wcm9kPTMwXSAtLT4gfHNoYXJlIDEwfCBCW0I8YnIvPmxvYWQ9MjA8YnIvPnByb2Q9MTBdXG5cdFx0XHRcdFx0IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0) +* If you want to help us coding Hadar, please read **Dev Guide** before. -Hadar compute adequacy from simple to complex network. For example, to compute above network, just few line need:: +* If you want to see Mathematics model used in Hadar, go to **Mathematics**. - from hadar.solver.input import * - from hadar.solver.study import solve - study = Study(['a', 'b']) \ - .add_on_node('a', data=Consumption(cost=10 ** 6, quantity=[20, 20], type='load')) \ - .add_on_node('a', data=Production(cost=10, quantity=[30, 30], type='prod')) \ - .add_on_node('b', data=Consumption(cost=10 ** 6, quantity=[20, 20], type='load')) \ - .add_on_node('b', data=Production(cost=20, quantity=[10, 10], type='prod')) \ - .add_border(src='a', dest='b', quantity=[10, 10], cost=2) \ - - res = solve(study) - -Then you can analyze by yourself result or use hadar aggragator and plotting:: - - from hadar.aggregator.result import ResultAggregator - from hadar.viewer.jupyter import JupyterPlotting - plot = JupyterPlotting(agg=ResultAggregator(study, res), - node_coord={'a': [2.33, 48.86], 'b': [4.38, 50.83]}) - plot.stack(node='a') +.. toctree:: + :maxdepth: 1 + :caption: Architecture: -.. image:: /_static/get-started-1.png + architecture/overview.rst + architecture/workflow.rst + architecture/optimizer.rst + architecture/analyzer.rst + architecture/viewer.rst -Or :: +.. toctree:: + :maxdepth: 1 + :caption: Mathematics: - plot.stack(node='b') -.. image:: /_static/get-started-2.png + mathematics/linear-model.rst -Or :: +.. toctree:: + :maxdepth: 1 + :caption: Dev Guide: - plot.exchanges_map(t=0) -.. image:: /_static/get-started-3.png + dev-guide/repository.rst + dev-guide/contributing.rst .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :caption: Reference: - reference/hadar.analyzer.rst + reference/hadar.workflow.rst reference/hadar.optimizer.rst reference/hadar.analyzer.rst reference/hadar.viewer.rst .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :caption: Legal Terms - terms/terms.rst \ No newline at end of file + terms/terms.rst diff --git a/docs/source/mathematics/linear-model.rst b/docs/source/mathematics/linear-model.rst new file mode 100644 index 0000000..1a1a961 --- /dev/null +++ b/docs/source/mathematics/linear-model.rst @@ -0,0 +1,137 @@ +.. _linear-model: + +Linear Model +============ + +The main optimizer is :code:`LPOptimizer`. It creates linear programming problem representing network adequacy. We will see mathematics problem, step by step + +#. Basic adequacy equations +#. Add lack of adequacy terms (lost of load and spillage) + + As you will see, :math:`\Gamma_x` represents a quantity in network, :math:`\overline{\Gamma_x}` is the maximum, :math:`\underline{\Gamma_x}` is the minimum, :math:`\overline{\underline{\Gamma_x}}` is the maximum and minimum a.k.a it's a forced quantity. Upper case grec letter is for quantity, and lower case grec letter is for cost :math:`\gamma_x` associated to this quantity. + +Basic adequacy +-------------- + +Let's begin by the first adequacy behavior. We have a graph :math:`G(N, L)` with :math:`N` nodes on the graph and :math:`L` unidirectional edges on this graph. + +Variables +********* + +* :math:`n \in N` a node belongs to graph + +* :math:`T \in \mathbb{Z}_+` time horizon + +Edge variables + +* :math:`l \in L` an unidirectional edge belongs to graphs + +* :math:`\overline{\Gamma_l} \in \mathbb{R}^T_+` maximum power transfert capacity for :math:`l` + +* :math:`\Gamma_l \in \mathbb{R}^T_+` power transfered inside :math:`l` + +* :math:`\gamma_l \in \mathbb{R}^T_+` proportional cost when :math:`\Gamma_l` is used + +* :math:`L^n_\uparrow \subset L` set of edges with direction to node :math:`n` (i.e. importation for :math:`n`) + +* :math:`L^n_\downarrow \subset L` set of edges with direction from node :math:`n` (i.e. exportation for :math:`n`) + + +Productions variables + +* :math:`P^n` set of productions attached to node :math:`n` + +* :math:`p \in P^n` a production inside set of productions attached to node :math:`n` + +* :math:`\overline{\Gamma_p} \in \mathbb{R}^T_+` maximum power capacity available for :math:`p` production. + +* :math:`\Gamma_p \in \mathbb{R}^T_+` power capacity of :math:`p` used during adequacy + +* :math:`\gamma_p \in \mathbb{R}^T_+` proportional cost when :math:`\Gamma_p` is used + +Consumptions variables + +* :math:`C^n` set of consumptions attached to node :math:`n` + +* :math:`c \in C^n` a consumption inside set of consumptions attached to node :math:`n` + +* :math:`\underline{\overline{\Gamma_c}} \in \mathbb{R}^T_+` forced consumptions of :math:`c` to sustain. + +Objective +********* + +.. math:: + \begin{array}{rcl} + objective & = & \min{\Omega_{transmission} + \Omega_{production}} \\ + \Omega_{transmission} &=& \sum^{L}_{l}{\Gamma_l*{\gamma_l}} \\ + \Omega_{production} & = & \sum^N_n \sum^{P^n}_{p}{\Gamma_p * {\gamma_p}} + \end{array} + +Constraint +********** + +First constraint is from Kirschhoff law and describes balance between productions and consumptions + +.. math:: + \begin{array}{rcl} + \Pi_{kirschhoff} &:& \forall n &,& \sum^{C^n}_{c}{\underline{\overline{\Gamma_c}}} + \sum^{L^n_{\downarrow}}_{l}{ \Gamma_l } = \sum^{P^n}_{p}{ \Gamma_p } + \sum^{L^n_{\uparrow}}_{l}{ \Gamma_l } + \end{array} + +Then productions and edges need to be bounded + +.. math:: + \begin{array}{rcl} + \Pi_{Edge\ bound} &:& \forall l \in L &,& 0 \le \Gamma_{l} \le \overline{\Gamma_l} \\ + \Pi_{Prod\ bound} &:& + \left\{ \begin{array}{cl} + \forall n \in N \\ + \forall p \in P^n + \end{array} \right. &,& 0 \le \Gamma_p \le \overline{\Gamma_p} + \end{array} + + +Lack of adequacy +-------------- + +Variables +********* + +Sometime, there are a lack of adequacy because there are not enough production, called *lost of load*. + + Like :math:`\Gamma_x` means quantity present in network, :math:`\Lambda_x` represents a lack in network (consumption or production) to reach adequacy. Like for :math:`\Gamma_x`, lower case grec letter :math:`\lambda_x` is for cost associated to this lack. + +* :math:`\Lambda_c \in \mathbb{R}^T_+` lost of load for :math:`c` consumption + +* :math:`\lambda_c \in \mathbb{R}^T_+` proportional cost when :math:`\Lambda_c` is used + +Objective +********* + +Objective has a new term + +.. math:: + \begin{array}{rcl} + objective & = & \min{\Omega_{transmission} + \Omega_{production}} + \underbrace{\Omega_{lol}}\\ + \Omega_{lol} & = & \sum^N_n \sum^{C^n}_{c}{\Lambda_c * {\lambda_c}} + \end{array} + +Constraints +********** + +Kirschhoff law needs an update too. Lost of Load is represented like a *fantom* import of energy to reach adequacy. + +.. math:: + \begin{array}{rcl} + \Pi_{kirschhoff} &:& \forall n &,& \sum^{C^n}_{c}{\underline{\overline{\Gamma_c}}} + \sum^{L^n_{\downarrow}}_{l}{ \Gamma_l } = \sum^{P^n}_{p}{ \Gamma_p } + \sum^{L^n_{\uparrow}}_{l}{ \Gamma_l } + \underbrace{\sum^{C^n}_{c}{ \Lambda_c }} + \end{array} + +Lost of load must be bounded + +.. math:: + \begin{array}{rcl} + \Pi_{Lol\ bound} &:& + \left\{ \begin{array}{cl} + \forall n \in N \\ + \forall c \in C^n + \end{array} \right. &,& 0 \le \Lambda_c \le \overline{\underline{\Gamma_c}} + \end{array} diff --git a/examples/Analyze Result/Analyze Result.ipynb b/examples/Analyze Result/Analyze Result.ipynb new file mode 100644 index 0000000..645e2eb --- /dev/null +++ b/examples/Analyze Result/Analyze Result.ipynb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bad3790f9fda89268daf171c407712f66a5d4e75cd9ed5645046602e2068cdd8 +size 165584 diff --git a/examples/Begin Stochastic/Begin Stochastic.ipynb b/examples/Begin Stochastic/Begin Stochastic.ipynb new file mode 100644 index 0000000..810f723 --- /dev/null +++ b/examples/Begin Stochastic/Begin Stochastic.ipynb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63dac9e2a0f7595429880c88b4c100e5b2895a7d7a2894f99e7fdc52037da054 +size 785660 diff --git a/examples/Begin Stochastic/eolien.csv b/examples/Begin Stochastic/eolien.csv new file mode 100644 index 0000000..2bf8061 --- /dev/null +++ b/examples/Begin Stochastic/eolien.csv @@ -0,0 +1,168 @@ +264.71 264.71 264.71 566.64 878.89 878.89 566.64 566.64 878.89 878.89 +971.26 971.26 971.26 352.33 598.43 598.43 352.33 352.33 598.43 598.43 +504.60 504.60 504.60 939.58 614.61 614.61 939.58 939.58 614.61 614.61 +737.68 737.68 737.68 697.15 492.77 492.77 697.15 697.15 492.77 492.77 +50.23 50.23 50.23 611.89 57.34 57.34 611.89 611.89 57.34 57.34 +601.41 601.41 601.41 722.90 552.38 552.38 722.90 722.90 552.38 552.38 +688.73 688.73 688.73 203.78 388.51 388.51 203.78 203.78 388.51 388.51 +379.93 379.93 379.93 369.24 78.25 78.25 369.24 369.24 78.25 78.25 +68.91 68.91 68.91 275.18 603.95 603.95 275.18 275.18 603.95 603.95 +870.19 870.19 870.19 235.93 631.62 631.62 235.93 235.93 631.62 631.62 +69.67 69.67 69.67 126.75 645.57 645.57 126.75 126.75 645.57 645.57 +896.09 896.09 896.09 572.73 620.71 620.71 572.73 572.73 620.71 620.71 +679.82 679.82 679.82 819.46 586.93 586.93 819.46 819.46 586.93 586.93 +182.57 182.57 182.57 983.99 46.59 46.59 983.99 983.99 46.59 46.59 +368.87 368.87 368.87 824.20 252.54 252.54 824.20 824.20 252.54 252.54 +786.31 786.31 786.31 74.14 996.90 996.90 74.14 74.14 996.90 996.90 +660.25 660.25 660.25 185.20 880.61 880.61 185.20 185.20 880.61 880.61 +759.76 759.76 759.76 715.18 234.91 234.91 715.18 715.18 234.91 234.91 +711.72 711.72 711.72 567.51 348.54 348.54 567.51 567.51 348.54 348.54 +125.85 125.85 125.85 399.16 820.54 820.54 399.16 399.16 820.54 820.54 +492.97 492.97 492.97 111.50 350.69 350.69 111.50 111.50 350.69 350.69 +106.60 106.60 106.60 308.35 281.62 281.62 308.35 308.35 281.62 281.62 +883.76 883.76 883.76 391.17 174.96 174.96 391.17 391.17 174.96 174.96 +493.97 493.97 493.97 159.35 964.44 964.44 159.35 159.35 964.44 964.44 +80.62 80.62 80.62 19.13 906.95 906.95 19.13 19.13 906.95 906.95 +402.81 402.81 402.81 973.02 82.18 82.18 973.02 973.02 82.18 82.18 +273.53 273.53 273.53 452.96 736.84 736.84 452.96 452.96 736.84 736.84 +711.05 711.05 711.05 931.52 607.82 607.82 931.52 931.52 607.82 607.82 +768.64 768.64 768.64 898.76 236.46 236.46 898.76 898.76 236.46 236.46 +518.88 518.88 518.88 15.66 282.06 282.06 15.66 15.66 282.06 282.06 +106.83 106.83 106.83 381.46 331.69 331.69 381.46 381.46 331.69 331.69 +316.95 316.95 316.95 701.88 600.10 600.10 701.88 701.88 600.10 600.10 +361.23 361.23 361.23 57.27 160.27 160.27 57.27 57.27 160.27 160.27 +465.02 465.02 465.02 462.95 527.01 527.01 462.95 462.95 527.01 527.01 +388.99 388.99 388.99 574.06 286.74 286.74 574.06 574.06 286.74 286.74 +752.84 752.84 752.84 170.92 854.34 854.34 170.92 170.92 854.34 854.34 +539.28 539.28 539.28 857.39 125.62 125.62 857.39 857.39 125.62 125.62 +823.67 823.67 823.67 59.28 682.14 682.14 59.28 59.28 682.14 682.14 +469.29 469.29 469.29 72.35 803.10 803.10 72.35 72.35 803.10 803.10 +694.13 694.13 694.13 524.98 646.37 646.37 524.98 524.98 646.37 646.37 +931.65 931.65 931.65 897.16 296.06 296.06 897.16 897.16 296.06 296.06 +532.88 532.88 532.88 375.26 297.38 297.38 375.26 375.26 297.38 297.38 +163.70 163.70 163.70 870.02 663.03 663.03 870.02 870.02 663.03 663.03 +827.21 827.21 827.21 701.10 464.22 464.22 701.10 701.10 464.22 464.22 +841.35 841.35 841.35 888.47 590.47 590.47 888.47 888.47 590.47 590.47 +687.23 687.23 687.23 174.11 102.13 102.13 174.11 174.11 102.13 102.13 +607.50 607.50 607.50 38.72 824.93 824.93 38.72 38.72 824.93 824.93 +992.25 992.25 992.25 60.09 986.76 986.76 60.09 60.09 986.76 986.76 +908.36 908.36 908.36 355.30 541.77 541.77 355.30 355.30 541.77 541.77 +519.25 519.25 519.25 843.53 254.46 254.46 843.53 843.53 254.46 254.46 +105.86 105.86 105.86 182.72 868.60 868.60 182.72 182.72 868.60 868.60 +368.98 368.98 368.98 877.84 506.68 506.68 877.84 877.84 506.68 506.68 +673.38 673.38 673.38 714.30 199.00 199.00 714.30 714.30 199.00 199.00 +412.97 412.97 412.97 637.80 537.33 537.33 637.80 637.80 537.33 537.33 +607.16 607.16 607.16 728.29 475.63 475.63 728.29 728.29 475.63 475.63 +219.12 219.12 219.12 586.52 896.52 896.52 586.52 586.52 896.52 896.52 +206.13 206.13 206.13 388.52 291.19 291.19 388.52 388.52 291.19 291.19 +956.88 956.88 956.88 837.87 472.84 472.84 837.87 837.87 472.84 472.84 +501.00 501.00 501.00 154.89 701.31 701.31 154.89 154.89 701.31 701.31 +621.34 621.34 621.34 768.86 46.37 46.37 768.86 768.86 46.37 46.37 +776.35 776.35 776.35 733.08 137.23 137.23 733.08 733.08 137.23 137.23 +835.96 835.96 835.96 387.43 120.99 120.99 387.43 387.43 120.99 120.99 +652.95 652.95 652.95 860.53 453.16 453.16 860.53 860.53 453.16 453.16 +876.58 876.58 876.58 737.98 892.18 892.18 737.98 737.98 892.18 892.18 +329.44 329.44 329.44 503.65 530.28 530.28 503.65 503.65 530.28 530.28 +638.42 638.42 638.42 183.84 583.72 583.72 183.84 183.84 583.72 583.72 +449.83 449.83 449.83 792.36 593.44 593.44 792.36 792.36 593.44 593.44 +72.32 72.32 72.32 381.23 66.19 66.19 381.23 381.23 66.19 66.19 +77.54 77.54 77.54 879.93 191.53 191.53 879.93 879.93 191.53 191.53 +397.13 397.13 397.13 260.53 539.48 539.48 260.53 260.53 539.48 539.48 +736.18 736.18 736.18 884.81 677.45 677.45 884.81 884.81 677.45 677.45 +899.73 899.73 899.73 741.07 818.38 818.38 741.07 741.07 818.38 818.38 +583.79 583.79 583.79 251.54 238.86 238.86 251.54 251.54 238.86 238.86 +177.14 177.14 177.14 156.66 3.31 3.31 156.66 156.66 3.31 3.31 +341.89 341.89 341.89 275.04 642.86 642.86 275.04 275.04 642.86 642.86 +84.82 84.82 84.82 443.91 376.13 376.13 443.91 443.91 376.13 376.13 +459.31 459.31 459.31 746.24 361.17 361.17 746.24 746.24 361.17 361.17 +467.72 467.72 467.72 379.34 799.38 799.38 379.34 379.34 799.38 799.38 +291.40 291.40 291.40 700.85 260.03 260.03 700.85 700.85 260.03 260.03 +593.67 593.67 593.67 135.04 459.93 459.93 135.04 135.04 459.93 459.93 +31.92 31.92 31.92 275.61 524.96 524.96 275.61 275.61 524.96 524.96 +607.94 607.94 607.94 704.60 601.17 601.17 704.60 704.60 601.17 601.17 +10.44 10.44 10.44 3.55 956.57 956.57 3.55 3.55 956.57 956.57 +539.89 539.89 539.89 611.15 487.26 487.26 611.15 611.15 487.26 487.26 +284.33 284.33 284.33 18.53 803.06 803.06 18.53 18.53 803.06 803.06 +241.25 241.25 241.25 381.83 168.26 168.26 381.83 381.83 168.26 168.26 +243.90 243.90 243.90 794.91 210.80 210.80 794.91 794.91 210.80 210.80 +839.33 839.33 839.33 572.80 447.99 447.99 572.80 572.80 447.99 447.99 +92.40 92.40 92.40 259.43 561.34 561.34 259.43 259.43 561.34 561.34 +850.73 850.73 850.73 441.06 152.72 152.72 441.06 441.06 152.72 152.72 +952.64 952.64 952.64 873.21 190.73 190.73 873.21 873.21 190.73 190.73 +27.20 27.20 27.20 183.75 37.92 37.92 183.75 183.75 37.92 37.92 +354.09 354.09 354.09 630.51 99.11 99.11 630.51 630.51 99.11 99.11 +582.75 582.75 582.75 663.76 485.43 485.43 663.76 663.76 485.43 485.43 +954.38 954.38 954.38 706.85 989.44 989.44 706.85 706.85 989.44 989.44 +926.25 926.25 926.25 621.43 96.83 96.83 621.43 621.43 96.83 96.83 +298.74 298.74 298.74 762.59 921.54 921.54 762.59 762.59 921.54 921.54 +137.02 137.02 137.02 21.89 841.89 841.89 21.89 21.89 841.89 841.89 +634.01 634.01 634.01 315.06 936.70 936.70 315.06 315.06 936.70 936.70 +675.62 675.62 675.62 475.66 98.70 98.70 475.66 475.66 98.70 98.70 +613.95 613.95 613.95 405.72 113.07 113.07 405.72 405.72 113.07 113.07 +84.21 84.21 84.21 914.49 356.39 356.39 914.49 914.49 356.39 356.39 +225.27 225.27 225.27 216.13 137.15 137.15 216.13 216.13 137.15 137.15 +693.53 693.53 693.53 514.87 266.36 266.36 514.87 514.87 266.36 266.36 +985.51 985.51 985.51 883.18 823.14 823.14 883.18 883.18 823.14 823.14 +132.96 132.96 132.96 220.58 65.46 65.46 220.58 220.58 65.46 65.46 +664.28 664.28 664.28 323.64 636.67 636.67 323.64 323.64 636.67 636.67 +92.79 92.79 92.79 980.85 777.64 777.64 980.85 980.85 777.64 777.64 +875.92 875.92 875.92 213.63 534.22 534.22 213.63 213.63 534.22 534.22 +250.34 250.34 250.34 822.62 501.89 501.89 822.62 822.62 501.89 501.89 +444.33 444.33 444.33 170.25 609.89 609.89 170.25 170.25 609.89 609.89 +864.45 864.45 864.45 949.71 3.70 3.70 949.71 949.71 3.70 3.70 +804.47 804.47 804.47 697.79 901.56 901.56 697.79 697.79 901.56 901.56 +229.44 229.44 229.44 9.62 931.54 931.54 9.62 9.62 931.54 931.54 +725.94 725.94 725.94 989.96 338.07 338.07 989.96 989.96 338.07 338.07 +137.09 137.09 137.09 375.54 442.46 442.46 375.54 375.54 442.46 442.46 +469.32 469.32 469.32 72.32 909.20 909.20 72.32 72.32 909.20 909.20 +604.65 604.65 604.65 572.65 421.37 421.37 572.65 572.65 421.37 421.37 +522.67 522.67 522.67 234.62 814.20 814.20 234.62 234.62 814.20 814.20 +997.87 997.87 997.87 290.65 223.30 223.30 290.65 290.65 223.30 223.30 +155.41 155.41 155.41 502.64 973.09 973.09 502.64 502.64 973.09 973.09 +492.74 492.74 492.74 269.19 379.74 379.74 269.19 269.19 379.74 379.74 +1.24 1.24 1.24 388.32 876.67 876.67 388.32 388.32 876.67 876.67 +777.61 777.61 777.61 707.87 694.20 694.20 707.87 707.87 694.20 694.20 +755.52 755.52 755.52 715.97 447.65 447.65 715.97 715.97 447.65 447.65 +71.29 71.29 71.29 895.08 46.14 46.14 895.08 895.08 46.14 46.14 +521.86 521.86 521.86 750.76 405.05 405.05 750.76 750.76 405.05 405.05 +649.79 649.79 649.79 110.07 925.57 925.57 110.07 110.07 925.57 925.57 +755.08 755.08 755.08 883.66 602.46 602.46 883.66 883.66 602.46 602.46 +922.27 922.27 922.27 775.86 678.65 678.65 775.86 775.86 678.65 678.65 +338.96 338.96 338.96 654.60 716.29 716.29 654.60 654.60 716.29 716.29 +74.31 74.31 74.31 444.02 949.31 949.31 444.02 444.02 949.31 949.31 +655.65 655.65 655.65 39.72 498.44 498.44 39.72 39.72 498.44 498.44 +542.56 542.56 542.56 58.94 208.86 208.86 58.94 58.94 208.86 208.86 +62.06 62.06 62.06 141.98 999.21 999.21 141.98 141.98 999.21 999.21 +700.95 700.95 700.95 302.52 368.15 368.15 302.52 302.52 368.15 368.15 +415.43 415.43 415.43 27.65 718.62 718.62 27.65 27.65 718.62 718.62 +728.81 728.81 728.81 729.98 25.21 25.21 729.98 729.98 25.21 25.21 +776.95 776.95 776.95 500.71 711.01 711.01 500.71 500.71 711.01 711.01 +533.61 533.61 533.61 751.34 593.97 593.97 751.34 751.34 593.97 593.97 +196.53 196.53 196.53 42.53 714.44 714.44 42.53 42.53 714.44 714.44 +30.32 30.32 30.32 652.23 828.39 828.39 652.23 652.23 828.39 828.39 +818.60 818.60 818.60 412.52 596.17 596.17 412.52 412.52 596.17 596.17 +499.12 499.12 499.12 402.12 764.05 764.05 402.12 402.12 764.05 764.05 +173.14 173.14 173.14 431.13 382.21 382.21 431.13 431.13 382.21 382.21 +111.40 111.40 111.40 275.46 286.42 286.42 275.46 275.46 286.42 286.42 +988.69 988.69 988.69 590.53 178.77 178.77 590.53 590.53 178.77 178.77 +867.89 867.89 867.89 389.35 984.91 984.91 389.35 389.35 984.91 984.91 +28.29 28.29 28.29 926.46 477.54 477.54 926.46 926.46 477.54 477.54 +884.65 884.65 884.65 467.30 176.01 176.01 467.30 467.30 176.01 176.01 +522.79 522.79 522.79 669.83 354.69 354.69 669.83 669.83 354.69 354.69 +625.01 625.01 625.01 696.87 568.69 568.69 696.87 696.87 568.69 568.69 +728.65 728.65 728.65 806.26 780.83 780.83 806.26 806.26 780.83 780.83 +944.84 944.84 944.84 332.17 810.43 810.43 332.17 332.17 810.43 810.43 +134.29 134.29 134.29 341.59 871.49 871.49 341.59 341.59 871.49 871.49 +606.31 606.31 606.31 327.20 703.86 703.86 327.20 327.20 703.86 703.86 +969.75 969.75 969.75 985.28 989.78 989.78 985.28 985.28 989.78 989.78 +188.24 188.24 188.24 734.37 149.33 149.33 734.37 734.37 149.33 149.33 +397.67 397.67 397.67 954.67 623.73 623.73 954.67 954.67 623.73 623.73 +254.66 254.66 254.66 564.56 363.43 363.43 564.56 564.56 363.43 363.43 +565.94 565.94 565.94 823.34 878.93 878.93 823.34 823.34 878.93 878.93 +289.32 289.32 289.32 142.06 771.63 771.63 142.06 142.06 771.63 771.63 +196.78 196.78 196.78 952.03 926.53 926.53 952.03 952.03 926.53 926.53 +616.10 616.10 616.10 576.41 715.36 715.36 576.41 576.41 715.36 715.36 +113.07 113.07 113.07 942.40 989.13 989.13 942.40 942.40 989.13 989.13 +950.04 950.04 950.04 983.63 860.33 860.33 983.63 983.63 860.33 860.33 +668.23 668.23 668.23 738.31 30.80 30.80 738.31 738.31 30.80 30.80 +452.46 452.46 452.46 725.22 934.62 934.62 725.22 725.22 934.62 934.62 diff --git a/examples/Begin Stochastic/figure.png b/examples/Begin Stochastic/figure.png new file mode 100644 index 0000000..999ac05 Binary files /dev/null and b/examples/Begin Stochastic/figure.png differ diff --git a/examples/Begin Stochastic/gas.csv b/examples/Begin Stochastic/gas.csv new file mode 100644 index 0000000..2255530 --- /dev/null +++ b/examples/Begin Stochastic/gas.csv @@ -0,0 +1,168 @@ +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 700.00 1000.00 1000.00 1000.00 1000.00 700.00 1000.00 +1000.00 1000.00 1000.00 700.00 1000.00 1000.00 1000.00 1000.00 700.00 1000.00 +1000.00 1000.00 1000.00 700.00 1000.00 1000.00 1000.00 1000.00 700.00 1000.00 +1000.00 1000.00 1000.00 700.00 1000.00 1000.00 1000.00 1000.00 700.00 1000.00 +1000.00 1000.00 1000.00 700.00 1000.00 1000.00 1000.00 1000.00 700.00 1000.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 1000.00 700.00 1000.00 700.00 1000.00 1000.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 700.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 700.00 1000.00 700.00 1000.00 700.00 700.00 +1000.00 1000.00 1000.00 700.00 1000.00 1000.00 1000.00 1000.00 700.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 +1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 1000.00 diff --git a/examples/Begin Stochastic/load_A.csv b/examples/Begin Stochastic/load_A.csv new file mode 100644 index 0000000..4f20fe7 --- /dev/null +++ b/examples/Begin Stochastic/load_A.csv @@ -0,0 +1,168 @@ +1283.00 1283.00 1283.00 1259.73 1268.47 1268.47 1259.73 1259.73 1268.47 1268.47 +1362.92 1362.92 1362.92 1313.33 1335.04 1335.04 1313.33 1313.33 1335.04 1335.04 +1455.13 1455.13 1455.13 1402.83 1411.73 1411.73 1402.83 1402.83 1411.73 1411.73 +1543.69 1543.69 1543.69 1504.38 1492.16 1492.16 1504.38 1504.38 1492.16 1492.16 +1657.68 1657.68 1657.68 1609.54 1591.95 1591.95 1609.54 1609.54 1591.95 1591.95 +1757.45 1757.45 1757.45 1729.74 1693.40 1693.40 1729.74 1729.74 1693.40 1693.40 +1844.81 1844.81 1844.81 1817.79 1794.01 1794.01 1817.79 1817.79 1794.01 1794.01 +1934.25 1934.25 1934.25 1905.08 1875.42 1875.42 1905.08 1905.08 1875.42 1875.42 +2004.99 2004.99 2004.99 1987.68 1934.84 1934.84 1987.68 1987.68 1934.84 1934.84 +2046.30 2046.30 2046.30 2037.43 1970.88 1970.88 2037.43 2037.43 1970.88 1970.88 +2052.57 2052.57 2052.57 2058.16 1964.26 1964.26 2058.16 2058.16 1964.26 1964.26 +2021.62 2021.62 2021.62 2037.96 1954.37 1954.37 2037.96 2037.96 1954.37 1954.37 +1984.13 1984.13 1984.13 1976.78 1904.34 1904.34 1976.78 1976.78 1904.34 1904.34 +1911.65 1911.65 1911.65 1903.37 1834.34 1834.34 1903.37 1903.37 1834.34 1834.34 +1821.80 1821.80 1821.80 1831.21 1744.73 1744.73 1831.21 1831.21 1744.73 1744.73 +1716.51 1716.51 1716.51 1728.92 1670.60 1670.60 1728.92 1728.92 1670.60 1670.60 +1594.94 1594.94 1594.94 1638.64 1573.95 1573.95 1638.64 1638.64 1573.95 1573.95 +1489.55 1489.55 1489.55 1532.12 1477.95 1477.95 1532.12 1532.12 1477.95 1477.95 +1400.63 1400.63 1400.63 1428.54 1369.37 1369.37 1428.54 1428.54 1369.37 1369.37 +1324.66 1324.66 1324.66 1349.83 1289.71 1289.71 1349.83 1349.83 1289.71 1289.71 +1269.28 1269.28 1269.28 1274.16 1246.11 1246.11 1274.16 1274.16 1246.11 1246.11 +1261.24 1261.24 1261.24 1234.33 1217.80 1217.80 1234.33 1234.33 1217.80 1217.80 +1257.07 1257.07 1257.07 1228.27 1199.43 1199.43 1228.27 1228.27 1199.43 1199.43 +1265.90 1265.90 1265.90 1265.84 1220.76 1220.76 1265.84 1265.84 1220.76 1220.76 +1308.56 1308.56 1308.56 1310.93 1274.13 1274.13 1310.93 1310.93 1274.13 1274.13 +1385.19 1385.19 1385.19 1379.37 1336.50 1336.50 1379.37 1379.37 1336.50 1336.50 +1484.59 1484.59 1484.59 1483.55 1425.80 1425.80 1483.55 1483.55 1425.80 1425.80 +1578.05 1578.05 1578.05 1585.69 1532.97 1532.97 1585.69 1585.69 1532.97 1532.97 +1695.61 1695.61 1695.61 1680.06 1628.78 1628.78 1680.06 1680.06 1628.78 1628.78 +1812.79 1812.79 1812.79 1785.81 1734.41 1734.41 1785.81 1785.81 1734.41 1734.41 +1894.35 1894.35 1894.35 1877.86 1833.88 1833.88 1877.86 1877.86 1833.88 1833.88 +1963.36 1963.36 1963.36 1981.05 1917.00 1917.00 1981.05 1981.05 1917.00 1917.00 +2015.08 2015.08 2015.08 2050.32 1988.14 1988.14 2050.32 2050.32 1988.14 1988.14 +2035.79 2035.79 2035.79 2096.99 2019.23 2019.23 2096.99 2096.99 2019.23 2019.23 +2039.58 2039.58 2039.58 2111.94 2041.35 2041.35 2111.94 2111.94 2041.35 2041.35 +2009.84 2009.84 2009.84 2094.88 2008.82 2008.82 2094.88 2094.88 2008.82 2008.82 +1955.03 1955.03 1955.03 2028.65 1963.31 1963.31 2028.65 2028.65 1963.31 1963.31 +1903.89 1903.89 1903.89 1960.20 1894.38 1894.38 1960.20 1960.20 1894.38 1894.38 +1829.72 1829.72 1829.72 1872.04 1810.20 1810.20 1872.04 1872.04 1810.20 1810.20 +1725.06 1725.06 1725.06 1770.93 1691.71 1691.71 1770.93 1770.93 1691.71 1691.71 +1607.94 1607.94 1607.94 1644.11 1579.58 1579.58 1644.11 1644.11 1579.58 1579.58 +1525.53 1525.53 1525.53 1537.73 1472.58 1472.58 1537.73 1537.73 1472.58 1472.58 +1444.73 1444.73 1444.73 1442.43 1378.78 1378.78 1442.43 1442.43 1378.78 1378.78 +1381.29 1381.29 1381.29 1379.57 1299.52 1299.52 1379.57 1379.57 1299.52 1299.52 +1314.31 1314.31 1314.31 1318.97 1239.04 1239.04 1318.97 1318.97 1239.04 1239.04 +1288.46 1288.46 1288.46 1300.70 1203.63 1203.63 1300.70 1300.70 1203.63 1203.63 +1269.61 1269.61 1269.61 1300.31 1200.90 1200.90 1300.31 1300.31 1200.90 1200.90 +1311.16 1311.16 1311.16 1322.25 1223.83 1223.83 1322.25 1322.25 1223.83 1223.83 +1354.28 1354.28 1354.28 1378.41 1273.49 1273.49 1378.41 1378.41 1273.49 1273.49 +1427.95 1427.95 1427.95 1467.98 1354.98 1354.98 1467.98 1467.98 1354.98 1354.98 +1537.34 1537.34 1537.34 1557.46 1440.37 1440.37 1557.46 1557.46 1440.37 1440.37 +1650.59 1650.59 1650.59 1654.24 1525.96 1525.96 1654.24 1654.24 1525.96 1525.96 +1731.68 1731.68 1731.68 1754.18 1629.65 1629.65 1754.18 1754.18 1629.65 1629.65 +1831.87 1831.87 1831.87 1861.43 1723.46 1723.46 1861.43 1861.43 1723.46 1723.46 +1918.41 1918.41 1918.41 1939.44 1792.85 1792.85 1939.44 1939.44 1792.85 1792.85 +2011.48 2011.48 2011.48 2016.34 1856.56 1856.56 2016.34 2016.34 1856.56 1856.56 +2037.45 2037.45 2037.45 2063.00 1909.19 1909.19 2063.00 2063.00 1909.19 1909.19 +2067.10 2067.10 2067.10 2085.86 1945.05 1945.05 2085.86 2085.86 1945.05 1945.05 +2068.94 2068.94 2068.94 2091.63 1945.44 1945.44 2091.63 2091.63 1945.44 1945.44 +2032.22 2032.22 2032.22 2081.35 1917.70 1917.70 2081.35 2081.35 1917.70 1917.70 +1976.04 1976.04 1976.04 2029.71 1883.10 1883.10 2029.71 2029.71 1883.10 1883.10 +1913.98 1913.98 1913.98 1949.89 1823.57 1823.57 1949.89 1949.89 1823.57 1823.57 +1807.69 1807.69 1807.69 1838.19 1745.48 1745.48 1838.19 1838.19 1745.48 1745.48 +1710.49 1710.49 1710.49 1754.91 1647.96 1647.96 1754.91 1754.91 1647.96 1647.96 +1607.98 1607.98 1607.98 1650.58 1547.69 1547.69 1650.58 1650.58 1547.69 1547.69 +1508.20 1508.20 1508.20 1540.28 1457.56 1457.56 1540.28 1540.28 1457.56 1457.56 +1427.66 1427.66 1427.66 1437.75 1372.61 1372.61 1437.75 1437.75 1372.61 1372.61 +1343.24 1343.24 1343.24 1364.90 1302.23 1302.23 1364.90 1364.90 1302.23 1302.23 +1299.87 1299.87 1299.87 1310.94 1256.24 1256.24 1310.94 1310.94 1256.24 1256.24 +1282.91 1282.91 1282.91 1279.67 1245.83 1245.83 1279.67 1279.67 1245.83 1245.83 +1295.34 1295.34 1295.34 1278.55 1262.89 1262.89 1278.55 1278.55 1262.89 1262.89 +1316.22 1316.22 1316.22 1300.23 1281.37 1281.37 1300.23 1300.23 1281.37 1281.37 +1359.18 1359.18 1359.18 1359.37 1335.14 1335.14 1359.37 1359.37 1335.14 1335.14 +1431.67 1431.67 1431.67 1426.67 1413.74 1413.74 1426.67 1426.67 1413.74 1413.74 +1518.81 1518.81 1518.81 1516.72 1499.97 1499.97 1516.72 1516.72 1499.97 1499.97 +1624.01 1624.01 1624.01 1608.47 1601.74 1601.74 1608.47 1608.47 1601.74 1601.74 +1716.65 1716.65 1716.65 1711.84 1718.91 1718.91 1711.84 1711.84 1718.91 1718.91 +1801.41 1801.41 1801.41 1803.09 1829.63 1829.63 1803.09 1803.09 1829.63 1829.63 +1886.27 1886.27 1886.27 1883.56 1917.45 1917.45 1883.56 1883.56 1917.45 1917.45 +1945.07 1945.07 1945.07 1955.58 1981.67 1981.67 1955.58 1955.58 1981.67 1981.67 +2015.15 2015.15 2015.15 2000.90 2027.24 2027.24 2000.90 2000.90 2027.24 2027.24 +2037.64 2037.64 2037.64 2027.73 2052.82 2052.82 2027.73 2027.73 2052.82 2052.82 +2045.48 2045.48 2045.48 2020.38 2067.99 2067.99 2020.38 2020.38 2067.99 2067.99 +2028.04 2028.04 2028.04 1991.14 2064.25 2064.25 1991.14 1991.14 2064.25 2064.25 +1949.95 1949.95 1949.95 1920.97 2018.71 2018.71 1920.97 1920.97 2018.71 2018.71 +1860.46 1860.46 1860.46 1832.29 1956.72 1956.72 1832.29 1832.29 1956.72 1956.72 +1777.82 1777.82 1777.82 1734.06 1856.25 1856.25 1734.06 1734.06 1856.25 1856.25 +1672.35 1672.35 1672.35 1632.91 1747.50 1747.50 1632.91 1632.91 1747.50 1747.50 +1570.70 1570.70 1570.70 1526.69 1628.06 1628.06 1526.69 1526.69 1628.06 1628.06 +1467.55 1467.55 1467.55 1450.58 1524.69 1524.69 1450.58 1450.58 1524.69 1524.69 +1406.92 1406.92 1406.92 1360.74 1439.32 1439.32 1360.74 1360.74 1439.32 1439.32 +1338.98 1338.98 1338.98 1295.04 1366.14 1366.14 1295.04 1295.04 1366.14 1366.14 +1306.89 1306.89 1306.89 1236.06 1327.16 1327.16 1236.06 1236.06 1327.16 1327.16 +1278.33 1278.33 1278.33 1226.16 1318.27 1318.27 1226.16 1226.16 1318.27 1318.27 +1291.57 1291.57 1291.57 1236.87 1325.68 1325.68 1236.87 1236.87 1325.68 1325.68 +1318.60 1318.60 1318.60 1265.43 1349.83 1349.83 1265.43 1265.43 1349.83 1349.83 +1378.77 1378.77 1378.77 1341.74 1413.60 1413.60 1341.74 1341.74 1413.60 1413.60 +1471.02 1471.02 1471.02 1436.40 1498.28 1498.28 1436.40 1436.40 1498.28 1498.28 +1573.78 1573.78 1573.78 1530.29 1589.63 1589.63 1530.29 1530.29 1589.63 1589.63 +1674.84 1674.84 1674.84 1636.19 1673.26 1673.26 1636.19 1636.19 1673.26 1673.26 +1775.98 1775.98 1775.98 1726.56 1775.04 1775.04 1726.56 1726.56 1775.04 1775.04 +1874.90 1874.90 1874.90 1851.83 1884.25 1884.25 1851.83 1851.83 1884.25 1884.25 +1963.16 1963.16 1963.16 1936.19 1971.80 1971.80 1936.19 1936.19 1971.80 1971.80 +2022.49 2022.49 2022.49 2004.19 2029.08 2029.08 2004.19 2004.19 2029.08 2029.08 +2071.55 2071.55 2071.55 2039.21 2085.25 2085.25 2039.21 2039.21 2085.25 2085.25 +2084.05 2084.05 2084.05 2067.42 2087.28 2087.28 2067.42 2067.42 2087.28 2087.28 +2060.55 2060.55 2060.55 2044.59 2074.33 2074.33 2044.59 2044.59 2074.33 2074.33 +2023.52 2023.52 2023.52 2006.92 2043.87 2043.87 2006.92 2006.92 2043.87 2043.87 +1979.37 1979.37 1979.37 1938.53 1993.03 1993.03 1938.53 1938.53 1993.03 1993.03 +1902.71 1902.71 1902.71 1854.67 1887.37 1887.37 1854.67 1854.67 1887.37 1887.37 +1812.29 1812.29 1812.29 1773.68 1822.92 1822.92 1773.68 1773.68 1822.92 1822.92 +1708.91 1708.91 1708.91 1667.81 1722.67 1722.67 1667.81 1667.81 1722.67 1722.67 +1593.59 1593.59 1593.59 1589.23 1600.09 1600.09 1589.23 1589.23 1600.09 1600.09 +1495.19 1495.19 1495.19 1487.71 1505.33 1505.33 1487.71 1487.71 1505.33 1505.33 +1406.51 1406.51 1406.51 1390.03 1439.70 1439.70 1390.03 1390.03 1439.70 1439.70 +1329.66 1329.66 1329.66 1320.80 1372.72 1372.72 1320.80 1320.80 1372.72 1372.72 +1282.22 1282.22 1282.22 1265.00 1332.06 1332.06 1265.00 1265.00 1332.06 1332.06 +1272.08 1272.08 1272.08 1254.86 1310.61 1310.61 1254.86 1254.86 1310.61 1310.61 +1261.54 1261.54 1261.54 1279.96 1329.16 1329.16 1279.96 1279.96 1329.16 1329.16 +1305.16 1305.16 1305.16 1318.92 1360.42 1360.42 1318.92 1318.92 1360.42 1360.42 +1372.62 1372.62 1372.62 1377.60 1420.15 1420.15 1377.60 1377.60 1420.15 1420.15 +1451.54 1451.54 1451.54 1467.35 1504.60 1504.60 1467.35 1467.35 1504.60 1504.60 +1561.62 1561.62 1561.62 1562.44 1591.61 1591.61 1562.44 1562.44 1591.61 1591.61 +1666.50 1666.50 1666.50 1673.60 1677.34 1677.34 1673.60 1673.60 1677.34 1677.34 +1784.89 1784.89 1784.89 1770.84 1775.00 1775.00 1770.84 1770.84 1775.00 1775.00 +1897.53 1897.53 1897.53 1864.32 1871.15 1871.15 1864.32 1864.32 1871.15 1871.15 +1996.62 1996.62 1996.62 1951.59 1957.70 1957.70 1951.59 1951.59 1957.70 1957.70 +2057.40 2057.40 2057.40 2027.62 2009.50 2009.50 2027.62 2027.62 2009.50 2009.50 +2088.87 2088.87 2088.87 2050.46 2046.78 2046.78 2050.46 2050.46 2046.78 2046.78 +2125.43 2125.43 2125.43 2050.88 2067.27 2067.27 2050.88 2050.88 2067.27 2067.27 +2125.11 2125.11 2125.11 2025.46 2059.07 2059.07 2025.46 2025.46 2059.07 2059.07 +2100.54 2100.54 2100.54 1973.92 2013.81 2013.81 1973.92 1973.92 2013.81 2013.81 +2038.18 2038.18 2038.18 1899.37 1956.10 1956.10 1899.37 1899.37 1956.10 1956.10 +1943.05 1943.05 1943.05 1819.70 1858.06 1858.06 1819.70 1819.70 1858.06 1858.06 +1853.32 1853.32 1853.32 1722.54 1769.34 1769.34 1722.54 1722.54 1769.34 1769.34 +1743.10 1743.10 1743.10 1619.32 1658.77 1658.77 1619.32 1619.32 1658.77 1658.77 +1648.40 1648.40 1648.40 1516.50 1557.74 1557.74 1516.50 1516.50 1557.74 1557.74 +1558.64 1558.64 1558.64 1421.20 1463.96 1463.96 1421.20 1421.20 1463.96 1463.96 +1479.03 1479.03 1479.03 1338.70 1376.94 1376.94 1338.70 1338.70 1376.94 1376.94 +1433.48 1433.48 1433.48 1271.76 1311.84 1311.84 1271.76 1271.76 1311.84 1311.84 +1391.14 1391.14 1391.14 1240.47 1277.95 1277.95 1240.47 1240.47 1277.95 1277.95 +1377.66 1377.66 1377.66 1214.57 1266.38 1266.38 1214.57 1214.57 1266.38 1266.38 +1396.86 1396.86 1396.86 1220.98 1277.55 1277.55 1220.98 1220.98 1277.55 1277.55 +1436.57 1436.57 1436.57 1272.82 1319.35 1319.35 1272.82 1272.82 1319.35 1319.35 +1501.82 1501.82 1501.82 1336.11 1404.83 1404.83 1336.11 1336.11 1404.83 1404.83 +1578.67 1578.67 1578.67 1429.94 1499.59 1499.59 1429.94 1429.94 1499.59 1499.59 +1698.65 1698.65 1698.65 1540.52 1584.00 1584.00 1540.52 1540.52 1584.00 1584.00 +1806.32 1806.32 1806.32 1640.92 1658.71 1658.71 1640.92 1640.92 1658.71 1658.71 +1912.29 1912.29 1912.29 1749.06 1781.86 1781.86 1749.06 1749.06 1781.86 1781.86 +2010.53 2010.53 2010.53 1843.04 1867.72 1867.72 1843.04 1843.04 1867.72 1867.72 +2089.97 2089.97 2089.97 1928.28 1952.90 1952.90 1928.28 1928.28 1952.90 1952.90 +2170.91 2170.91 2170.91 1972.25 2019.57 2019.57 1972.25 1972.25 2019.57 2019.57 +2209.19 2209.19 2209.19 2021.65 2059.84 2059.84 2021.65 2021.65 2059.84 2059.84 +2214.11 2214.11 2214.11 2035.97 2062.39 2062.39 2035.97 2035.97 2062.39 2062.39 +2190.41 2190.41 2190.41 2024.30 2043.31 2043.31 2024.30 2024.30 2043.31 2043.31 +2150.72 2150.72 2150.72 1982.00 2005.70 2005.70 1982.00 1982.00 2005.70 2005.70 +2088.07 2088.07 2088.07 1907.98 1946.25 1946.25 1907.98 1907.98 1946.25 1946.25 +2014.13 2014.13 2014.13 1826.71 1863.48 1863.48 1826.71 1826.71 1863.48 1863.48 +1918.91 1918.91 1918.91 1725.16 1760.74 1760.74 1725.16 1725.16 1760.74 1760.74 +1824.71 1824.71 1824.71 1631.35 1639.70 1639.70 1631.35 1631.35 1639.70 1639.70 +1726.02 1726.02 1726.02 1534.06 1534.50 1534.50 1534.06 1534.06 1534.50 1534.50 +1624.54 1624.54 1624.54 1442.05 1447.72 1447.72 1442.05 1442.05 1447.72 1447.72 +1541.59 1541.59 1541.59 1369.66 1372.85 1372.85 1369.66 1369.66 1372.85 1372.85 +1480.90 1480.90 1480.90 1318.90 1319.27 1319.27 1318.90 1318.90 1319.27 1319.27 +1455.04 1455.04 1455.04 1283.24 1277.25 1277.25 1283.24 1283.24 1277.25 1277.25 +1451.61 1451.61 1451.61 1285.70 1253.32 1253.32 1285.70 1285.70 1253.32 1253.32 +1480.17 1480.17 1480.17 1305.42 1286.52 1286.52 1305.42 1305.42 1286.52 1286.52 +1510.54 1510.54 1510.54 1354.29 1331.85 1331.85 1354.29 1354.29 1331.85 1331.85 diff --git a/examples/Begin Stochastic/load_B.csv b/examples/Begin Stochastic/load_B.csv new file mode 100644 index 0000000..065eb86 --- /dev/null +++ b/examples/Begin Stochastic/load_B.csv @@ -0,0 +1,168 @@ +1908.05 1908.05 1908.05 1870.54 1892.77 1892.77 1870.54 1870.54 1892.77 1892.77 +2012.52 2012.52 2012.52 1961.25 1997.24 1997.24 1961.25 1961.25 1997.24 1997.24 +2133.51 2133.51 2133.51 2090.88 2120.16 2120.16 2090.88 2090.88 2120.16 2120.16 +2285.14 2285.14 2285.14 2233.14 2272.44 2272.44 2233.14 2233.14 2272.44 2272.44 +2444.00 2444.00 2444.00 2402.52 2431.04 2431.04 2402.52 2402.52 2431.04 2431.04 +2600.96 2600.96 2600.96 2568.98 2591.21 2591.21 2568.98 2568.98 2591.21 2591.21 +2737.59 2737.59 2737.59 2709.74 2735.44 2735.44 2709.74 2709.74 2735.44 2735.44 +2858.64 2858.64 2858.64 2828.35 2869.90 2869.90 2828.35 2828.35 2869.90 2869.90 +2963.10 2963.10 2963.10 2917.84 2972.34 2972.34 2917.84 2917.84 2972.34 2972.34 +3013.65 3013.65 3013.65 2953.83 3017.28 3017.28 2953.83 2953.83 3017.28 3017.28 +3029.79 3029.79 3029.79 2939.92 3031.78 3031.78 2939.92 2939.92 3031.78 3031.78 +2993.99 2993.99 2993.99 2921.50 3002.03 3002.03 2921.50 2921.50 3002.03 3002.03 +2921.57 2921.57 2921.57 2842.98 2923.02 2923.02 2842.98 2842.98 2923.02 2923.02 +2819.41 2819.41 2819.41 2747.39 2804.22 2804.22 2747.39 2747.39 2804.22 2804.22 +2676.43 2676.43 2676.43 2631.25 2671.87 2671.87 2631.25 2631.25 2671.87 2671.87 +2510.71 2510.71 2510.71 2479.39 2501.44 2501.44 2479.39 2479.39 2501.44 2501.44 +2349.13 2349.13 2349.13 2327.08 2339.45 2339.45 2327.08 2327.08 2339.45 2339.45 +2207.88 2207.88 2207.88 2162.28 2166.25 2166.25 2162.28 2162.28 2166.25 2166.25 +2084.78 2084.78 2084.78 2005.61 2015.97 2015.97 2005.61 2005.61 2015.97 2015.97 +1943.89 1943.89 1943.89 1893.71 1902.55 1902.55 1893.71 1893.71 1902.55 1902.55 +1891.72 1891.72 1891.72 1812.48 1828.83 1828.83 1812.48 1812.48 1828.83 1828.83 +1841.02 1841.02 1841.02 1770.39 1785.39 1785.39 1770.39 1770.39 1785.39 1785.39 +1824.47 1824.47 1824.47 1757.92 1770.07 1770.07 1757.92 1757.92 1770.07 1770.07 +1836.77 1836.77 1836.77 1782.36 1815.20 1815.20 1782.36 1782.36 1815.20 1815.20 +1930.39 1930.39 1930.39 1846.49 1886.00 1886.00 1846.49 1846.49 1886.00 1886.00 +2049.40 2049.40 2049.40 1939.19 1992.21 1992.21 1939.19 1939.19 1992.21 1992.21 +2193.46 2193.46 2193.46 2093.11 2120.59 2120.59 2093.11 2093.11 2120.59 2120.59 +2335.41 2335.41 2335.41 2247.79 2276.43 2276.43 2247.79 2247.79 2276.43 2276.43 +2492.27 2492.27 2492.27 2408.73 2437.89 2437.89 2408.73 2408.73 2437.89 2437.89 +2644.85 2644.85 2644.85 2552.64 2597.32 2597.32 2552.64 2552.64 2597.32 2597.32 +2784.04 2784.04 2784.04 2691.13 2715.05 2715.05 2691.13 2691.13 2715.05 2715.05 +2899.15 2899.15 2899.15 2812.87 2850.51 2850.51 2812.87 2812.87 2850.51 2850.51 +2999.86 2999.86 2999.86 2892.42 2927.95 2927.95 2892.42 2892.42 2927.95 2927.95 +3046.08 3046.08 3046.08 2919.92 3001.70 3001.70 2919.92 2919.92 3001.70 3001.70 +3054.29 3054.29 3054.29 2926.85 3004.76 3004.76 2926.85 2926.85 3004.76 3004.76 +3022.87 3022.87 3022.87 2901.21 2975.62 2975.62 2901.21 2901.21 2975.62 2975.62 +2959.15 2959.15 2959.15 2850.80 2896.69 2896.69 2850.80 2850.80 2896.69 2896.69 +2861.23 2861.23 2861.23 2761.16 2792.88 2792.88 2761.16 2761.16 2792.88 2792.88 +2726.70 2726.70 2726.70 2614.33 2675.09 2675.09 2614.33 2614.33 2675.09 2675.09 +2563.16 2563.16 2563.16 2439.90 2513.62 2513.62 2439.90 2439.90 2513.62 2513.62 +2395.17 2395.17 2395.17 2264.74 2359.81 2359.81 2264.74 2264.74 2359.81 2359.81 +2232.18 2232.18 2232.18 2091.16 2209.69 2209.69 2091.16 2091.16 2209.69 2209.69 +2078.31 2078.31 2078.31 1945.26 2067.89 2067.89 1945.26 1945.26 2067.89 2067.89 +1978.77 1978.77 1978.77 1838.90 1953.38 1953.38 1838.90 1838.90 1953.38 1953.38 +1905.31 1905.31 1905.31 1749.40 1880.70 1880.70 1749.40 1749.40 1880.70 1880.70 +1857.46 1857.46 1857.46 1713.01 1860.72 1860.72 1713.01 1713.01 1860.72 1860.72 +1859.25 1859.25 1859.25 1704.93 1845.70 1845.70 1704.93 1704.93 1845.70 1845.70 +1894.57 1894.57 1894.57 1741.38 1882.53 1882.53 1741.38 1741.38 1882.53 1882.53 +1964.08 1964.08 1964.08 1838.33 1972.65 1972.65 1838.33 1838.33 1972.65 1972.65 +2072.80 2072.80 2072.80 1947.21 2092.02 2092.02 1947.21 1947.21 2092.02 2092.02 +2199.69 2199.69 2199.69 2073.72 2228.45 2228.45 2073.72 2073.72 2228.45 2228.45 +2372.75 2372.75 2372.75 2221.77 2384.52 2384.52 2221.77 2221.77 2384.52 2384.52 +2522.68 2522.68 2522.68 2381.96 2543.62 2543.62 2381.96 2381.96 2543.62 2543.62 +2679.24 2679.24 2679.24 2543.70 2698.85 2698.85 2543.70 2543.70 2698.85 2698.85 +2810.15 2810.15 2810.15 2668.90 2833.08 2833.08 2668.90 2668.90 2833.08 2833.08 +2936.81 2936.81 2936.81 2773.16 2942.97 2942.97 2773.16 2773.16 2942.97 2942.97 +3012.89 3012.89 3012.89 2855.24 3020.97 3020.97 2855.24 2855.24 3020.97 3020.97 +3055.09 3055.09 3055.09 2899.04 3062.67 3062.67 2899.04 2899.04 3062.67 3062.67 +3064.05 3064.05 3064.05 2916.91 3063.46 3063.46 2916.91 2916.91 3063.46 3063.46 +3001.11 3001.11 3001.11 2885.09 3012.39 3012.39 2885.09 2885.09 3012.39 3012.39 +2923.14 2923.14 2923.14 2814.79 2938.38 2938.38 2814.79 2814.79 2938.38 2938.38 +2814.20 2814.20 2814.20 2701.74 2823.22 2823.22 2701.74 2701.74 2823.22 2823.22 +2684.86 2684.86 2684.86 2574.39 2670.75 2670.75 2574.39 2574.39 2670.75 2670.75 +2519.30 2519.30 2519.30 2426.07 2501.89 2501.89 2426.07 2426.07 2501.89 2501.89 +2360.65 2360.65 2360.65 2285.79 2322.11 2322.11 2285.79 2285.79 2322.11 2322.11 +2203.31 2203.31 2203.31 2144.22 2158.13 2158.13 2144.22 2144.22 2158.13 2158.13 +2067.24 2067.24 2067.24 1986.96 2016.30 2016.30 1986.96 1986.96 2016.30 2016.30 +1956.10 1956.10 1956.10 1883.36 1912.03 1912.03 1883.36 1883.36 1912.03 1912.03 +1882.82 1882.82 1882.82 1824.41 1832.60 1832.60 1824.41 1824.41 1832.60 1832.60 +1858.20 1858.20 1858.20 1777.72 1794.19 1794.19 1777.72 1777.72 1794.19 1794.19 +1859.87 1859.87 1859.87 1789.68 1808.15 1808.15 1789.68 1789.68 1808.15 1808.15 +1894.69 1894.69 1894.69 1845.15 1855.51 1855.51 1845.15 1845.15 1855.51 1855.51 +1977.73 1977.73 1977.73 1942.70 1956.10 1956.10 1942.70 1942.70 1956.10 1956.10 +2102.27 2102.27 2102.27 2054.45 2077.69 2077.69 2054.45 2054.45 2077.69 2077.69 +2222.90 2222.90 2222.90 2190.98 2210.99 2210.99 2190.98 2190.98 2210.99 2210.99 +2379.26 2379.26 2379.26 2341.59 2347.62 2347.62 2341.59 2341.59 2347.62 2347.62 +2535.73 2535.73 2535.73 2480.75 2509.67 2509.67 2480.75 2480.75 2509.67 2509.67 +2690.52 2690.52 2690.52 2626.09 2671.42 2671.42 2626.09 2626.09 2671.42 2671.42 +2832.66 2832.66 2832.66 2764.84 2815.14 2815.14 2764.84 2764.84 2815.14 2815.14 +2949.88 2949.88 2949.88 2875.68 2900.13 2900.13 2875.68 2875.68 2900.13 2900.13 +3019.84 3019.84 3019.84 2942.42 2971.13 2971.13 2942.42 2942.42 2971.13 2971.13 +3046.67 3046.67 3046.67 2991.28 3006.18 3006.18 2991.28 2991.28 3006.18 3006.18 +3043.58 3043.58 3043.58 2968.43 3010.01 3010.01 2968.43 2968.43 3010.01 3010.01 +3000.04 3000.04 3000.04 2919.63 2954.25 2954.25 2919.63 2919.63 2954.25 2954.25 +2909.18 2909.18 2909.18 2863.42 2874.74 2874.74 2863.42 2863.42 2874.74 2874.74 +2800.70 2800.70 2800.70 2759.28 2758.96 2758.96 2759.28 2759.28 2758.96 2758.96 +2645.23 2645.23 2645.23 2634.87 2630.35 2630.35 2634.87 2634.87 2630.35 2630.35 +2495.73 2495.73 2495.73 2476.47 2458.90 2458.90 2476.47 2476.47 2458.90 2458.90 +2333.89 2333.89 2333.89 2318.83 2295.85 2295.85 2318.83 2318.83 2295.85 2295.85 +2192.51 2192.51 2192.51 2183.04 2156.16 2156.16 2183.04 2183.04 2156.16 2156.16 +2080.81 2080.81 2080.81 2052.24 2016.16 2016.16 2052.24 2052.24 2016.16 2016.16 +1977.03 1977.03 1977.03 1950.10 1916.95 1916.95 1950.10 1950.10 1916.95 1916.95 +1924.10 1924.10 1924.10 1887.52 1836.62 1836.62 1887.52 1887.52 1836.62 1836.62 +1895.67 1895.67 1895.67 1862.32 1789.03 1789.03 1862.32 1862.32 1789.03 1789.03 +1909.62 1909.62 1909.62 1864.17 1827.11 1827.11 1864.17 1864.17 1827.11 1827.11 +1964.41 1964.41 1964.41 1910.25 1878.72 1878.72 1910.25 1910.25 1878.72 1878.72 +2045.32 2045.32 2045.32 2002.67 1961.72 1961.72 2002.67 2002.67 1961.72 1961.72 +2165.86 2165.86 2165.86 2135.69 2063.29 2063.29 2135.69 2135.69 2063.29 2063.29 +2334.40 2334.40 2334.40 2272.76 2201.11 2201.11 2272.76 2272.76 2201.11 2201.11 +2476.26 2476.26 2476.26 2420.83 2363.33 2363.33 2420.83 2420.83 2363.33 2363.33 +2623.99 2623.99 2623.99 2579.58 2495.70 2495.70 2579.58 2579.58 2495.70 2495.70 +2803.36 2803.36 2803.36 2734.40 2631.18 2631.18 2734.40 2734.40 2631.18 2631.18 +2931.59 2931.59 2931.59 2869.07 2761.26 2761.26 2869.07 2869.07 2761.26 2761.26 +3042.64 3042.64 3042.64 2980.04 2858.77 2858.77 2980.04 2980.04 2858.77 2858.77 +3123.06 3123.06 3123.06 3044.12 2936.28 2936.28 3044.12 3044.12 2936.28 2936.28 +3136.83 3136.83 3136.83 3082.07 2967.14 2967.14 3082.07 3082.07 2967.14 2967.14 +3124.21 3124.21 3124.21 3075.30 2954.96 2954.96 3075.30 3075.30 2954.96 2954.96 +3078.40 3078.40 3078.40 3028.11 2890.30 2890.30 3028.11 3028.11 2890.30 2890.30 +2981.82 2981.82 2981.82 2938.48 2808.43 2808.43 2938.48 2938.48 2808.43 2808.43 +2855.72 2855.72 2855.72 2814.85 2678.33 2678.33 2814.85 2814.85 2678.33 2678.33 +2706.56 2706.56 2706.56 2672.21 2525.66 2525.66 2672.21 2672.21 2525.66 2525.66 +2533.76 2533.76 2533.76 2513.78 2368.72 2368.72 2513.78 2513.78 2368.72 2368.72 +2358.44 2358.44 2358.44 2353.45 2218.73 2218.73 2353.45 2353.45 2218.73 2218.73 +2202.22 2202.22 2202.22 2204.23 2057.80 2057.80 2204.23 2204.23 2057.80 2057.80 +2095.41 2095.41 2095.41 2068.71 1912.40 1912.40 2068.71 2068.71 1912.40 1912.40 +2007.11 2007.11 2007.11 1959.86 1824.09 1824.09 1959.86 1959.86 1824.09 1824.09 +1938.62 1938.62 1938.62 1894.81 1766.48 1766.48 1894.81 1894.81 1766.48 1766.48 +1903.92 1903.92 1903.92 1874.52 1747.94 1747.94 1874.52 1874.52 1747.94 1747.94 +1909.84 1909.84 1909.84 1878.54 1772.56 1772.56 1878.54 1878.54 1772.56 1772.56 +1988.40 1988.40 1988.40 1930.77 1833.43 1833.43 1930.77 1930.77 1833.43 1833.43 +2079.40 2079.40 2079.40 2006.52 1907.07 1907.07 2006.52 2006.52 1907.07 1907.07 +2205.74 2205.74 2205.74 2140.45 2016.19 2016.19 2140.45 2140.45 2016.19 2016.19 +2346.21 2346.21 2346.21 2301.01 2149.52 2149.52 2301.01 2301.01 2149.52 2149.52 +2516.46 2516.46 2516.46 2462.34 2299.97 2299.97 2462.34 2462.34 2299.97 2299.97 +2671.67 2671.67 2671.67 2629.76 2463.45 2463.45 2629.76 2629.76 2463.45 2463.45 +2830.99 2830.99 2830.99 2770.23 2608.80 2608.80 2770.23 2770.23 2608.80 2608.80 +2954.04 2954.04 2954.04 2899.93 2731.90 2731.90 2899.93 2899.93 2731.90 2731.90 +3059.85 3059.85 3059.85 3008.33 2824.24 2824.24 3008.33 3008.33 2824.24 2824.24 +3133.31 3133.31 3133.31 3069.95 2891.06 2891.06 3069.95 3069.95 2891.06 2891.06 +3158.83 3158.83 3158.83 3101.11 2910.90 2910.90 3101.11 3101.11 2910.90 2910.90 +3146.50 3146.50 3146.50 3084.59 2892.89 2892.89 3084.59 3084.59 2892.89 2892.89 +3086.11 3086.11 3086.11 3016.66 2830.61 2830.61 3016.66 3016.66 2830.61 2830.61 +2980.57 2980.57 2980.57 2922.83 2736.31 2736.31 2922.83 2922.83 2736.31 2736.31 +2859.46 2859.46 2859.46 2807.30 2626.39 2626.39 2807.30 2807.30 2626.39 2626.39 +2715.46 2715.46 2715.46 2670.65 2479.95 2479.95 2670.65 2670.65 2479.95 2479.95 +2556.59 2556.59 2556.59 2523.13 2341.82 2341.82 2523.13 2523.13 2341.82 2341.82 +2396.24 2396.24 2396.24 2352.06 2172.33 2172.33 2352.06 2352.06 2172.33 2172.33 +2260.00 2260.00 2260.00 2200.68 2027.15 2027.15 2200.68 2200.68 2027.15 2027.15 +2126.80 2126.80 2126.80 2091.81 1887.84 1887.84 2091.81 2091.81 1887.84 1887.84 +2026.29 2026.29 2026.29 1997.22 1817.55 1817.55 1997.22 1997.22 1817.55 1817.55 +1972.18 1972.18 1972.18 1929.53 1761.80 1761.80 1929.53 1929.53 1761.80 1761.80 +1941.33 1941.33 1941.33 1913.59 1730.68 1730.68 1913.59 1913.59 1730.68 1730.68 +1955.04 1955.04 1955.04 1929.60 1753.14 1753.14 1929.60 1929.60 1753.14 1753.14 +2011.43 2011.43 2011.43 1998.06 1816.15 1816.15 1998.06 1998.06 1816.15 1816.15 +2101.48 2101.48 2101.48 2100.49 1920.50 1920.50 2100.49 2100.49 1920.50 1920.50 +2225.10 2225.10 2225.10 2219.76 2043.41 2043.41 2219.76 2219.76 2043.41 2043.41 +2355.80 2355.80 2355.80 2367.78 2186.10 2186.10 2367.78 2367.78 2186.10 2186.10 +2533.89 2533.89 2533.89 2542.87 2357.13 2357.13 2542.87 2542.87 2357.13 2357.13 +2682.52 2682.52 2682.52 2714.59 2517.78 2517.78 2714.59 2714.59 2517.78 2517.78 +2832.54 2832.54 2832.54 2864.43 2665.78 2665.78 2864.43 2864.43 2665.78 2665.78 +2958.71 2958.71 2958.71 2979.44 2782.88 2782.88 2979.44 2979.44 2782.88 2782.88 +3054.75 3054.75 3054.75 3060.66 2869.50 2869.50 3060.66 3060.66 2869.50 2869.50 +3116.92 3116.92 3116.92 3120.95 2937.56 2937.56 3120.95 3120.95 2937.56 2937.56 +3143.27 3143.27 3143.27 3141.30 2947.73 2947.73 3141.30 3141.30 2947.73 2947.73 +3103.98 3103.98 3103.98 3122.57 2920.77 2920.77 3122.57 3122.57 2920.77 2920.77 +3046.62 3046.62 3046.62 3032.37 2871.91 2871.91 3032.37 3032.37 2871.91 2871.91 +2941.35 2941.35 2941.35 2944.06 2773.36 2773.36 2944.06 2944.06 2773.36 2773.36 +2809.82 2809.82 2809.82 2820.26 2653.49 2653.49 2820.26 2820.26 2653.49 2653.49 +2658.20 2658.20 2658.20 2669.85 2515.29 2515.29 2669.85 2669.85 2515.29 2515.29 +2486.86 2486.86 2486.86 2529.41 2356.68 2356.68 2529.41 2529.41 2356.68 2356.68 +2340.10 2340.10 2340.10 2372.87 2185.73 2185.73 2372.87 2372.87 2185.73 2185.73 +2205.78 2205.78 2205.78 2221.26 2045.99 2045.99 2221.26 2221.26 2045.99 2045.99 +2100.55 2100.55 2100.55 2091.65 1925.09 1925.09 2091.65 2091.65 1925.09 1925.09 +2012.14 2012.14 2012.14 1991.29 1831.25 1831.25 1991.29 1991.29 1831.25 1831.25 +1957.65 1957.65 1957.65 1941.86 1788.00 1788.00 1941.86 1941.86 1788.00 1788.00 +1926.33 1926.33 1926.33 1940.33 1777.90 1777.90 1940.33 1940.33 1777.90 1777.90 +1949.91 1949.91 1949.91 1972.04 1808.61 1808.61 1972.04 1972.04 1808.61 1808.61 +2007.24 2007.24 2007.24 2038.24 1866.28 1866.28 2038.24 2038.24 1866.28 1866.28 diff --git a/examples/Begin Stochastic/load_D.csv b/examples/Begin Stochastic/load_D.csv new file mode 100644 index 0000000..154cb57 --- /dev/null +++ b/examples/Begin Stochastic/load_D.csv @@ -0,0 +1,168 @@ +623.62 623.62 623.62 630.74 634.13 634.13 630.74 630.74 634.13 634.13 +666.03 666.03 666.03 653.74 676.24 676.24 653.74 653.74 676.24 676.24 +706.48 706.48 706.48 686.22 722.52 722.52 686.22 686.22 722.52 722.52 +772.20 772.20 772.20 729.87 787.19 787.19 729.87 729.87 787.19 787.19 +810.78 810.78 810.78 752.79 846.23 846.23 752.79 752.79 846.23 846.23 +875.00 875.00 875.00 795.93 886.45 886.45 795.93 795.93 886.45 886.45 +919.00 919.00 919.00 843.97 937.85 937.85 843.97 843.97 937.85 937.85 +968.56 968.56 968.56 877.46 961.31 961.31 877.46 877.46 961.31 961.31 +998.39 998.39 998.39 936.21 994.44 994.44 936.21 936.21 994.44 994.44 +1017.65 1017.65 1017.65 957.53 987.14 987.14 957.53 957.53 987.14 987.14 +1012.87 1012.87 1012.87 964.00 971.54 971.54 964.00 964.00 971.54 971.54 +987.31 987.31 987.31 948.08 976.08 976.08 948.08 948.08 976.08 976.08 +957.52 957.52 957.52 908.18 956.40 956.40 908.18 908.18 956.40 956.40 +919.71 919.71 919.71 864.74 923.15 923.15 864.74 864.74 923.15 923.15 +877.30 877.30 877.30 827.34 885.60 885.60 827.34 827.34 885.60 885.60 +826.43 826.43 826.43 770.24 835.99 835.99 770.24 770.24 835.99 835.99 +793.19 793.19 793.19 710.40 795.75 795.75 710.40 710.40 795.75 795.75 +743.62 743.62 743.62 650.33 742.82 742.82 650.33 650.33 742.82 742.82 +689.06 689.06 689.06 614.04 717.27 717.27 614.04 614.04 717.27 717.27 +662.08 662.08 662.08 583.22 679.75 679.75 583.22 583.22 679.75 679.75 +631.88 631.88 631.88 549.92 652.43 652.43 549.92 549.92 652.43 652.43 +606.91 606.91 606.91 546.14 629.30 629.30 546.14 546.14 629.30 629.30 +602.71 602.71 602.71 552.93 619.83 619.83 552.93 552.93 619.83 619.83 +597.39 597.39 597.39 553.37 625.65 625.65 553.37 553.37 625.65 625.65 +639.97 639.97 639.97 559.88 662.33 662.33 559.88 559.88 662.33 662.33 +665.81 665.81 665.81 584.58 688.48 688.48 584.58 584.58 688.48 688.48 +703.24 703.24 703.24 632.19 737.68 737.68 632.19 632.19 737.68 737.68 +754.63 754.63 754.63 704.65 787.57 787.57 704.65 704.65 787.57 787.57 +812.24 812.24 812.24 757.51 857.12 857.12 757.51 757.51 857.12 857.12 +863.41 863.41 863.41 810.19 898.44 898.44 810.19 810.19 898.44 898.44 +903.87 903.87 903.87 864.92 938.08 938.08 864.92 864.92 938.08 938.08 +956.11 956.11 956.11 909.59 971.29 971.29 909.59 909.59 971.29 971.29 +996.88 996.88 996.88 946.72 994.63 994.63 946.72 946.72 994.63 994.63 +995.47 995.47 995.47 972.18 1016.34 1016.34 972.18 972.18 1016.34 1016.34 +1007.34 1007.34 1007.34 964.83 1006.90 1006.90 964.83 964.83 1006.90 1006.90 +1016.34 1016.34 1016.34 950.08 999.09 999.09 950.08 950.08 999.09 999.09 +976.79 976.79 976.79 920.47 982.17 982.17 920.47 920.47 982.17 982.17 +942.63 942.63 942.63 890.54 938.86 938.86 890.54 890.54 938.86 938.86 +898.83 898.83 898.83 865.10 877.88 877.88 865.10 865.10 877.88 877.88 +846.99 846.99 846.99 812.22 835.09 835.09 812.22 812.22 835.09 835.09 +795.73 795.73 795.73 758.07 778.32 778.32 758.07 758.07 778.32 778.32 +741.27 741.27 741.27 707.93 725.89 725.89 707.93 707.93 725.89 725.89 +692.89 692.89 692.89 669.38 694.08 694.08 669.38 669.38 694.08 694.08 +661.19 661.19 661.19 626.19 655.12 655.12 626.19 626.19 655.12 655.12 +635.07 635.07 635.07 601.24 612.25 612.25 601.24 601.24 612.25 612.25 +624.65 624.65 624.65 581.24 594.70 594.70 581.24 581.24 594.70 594.70 +623.82 623.82 623.82 571.48 588.04 588.04 571.48 571.48 588.04 588.04 +643.72 643.72 643.72 587.45 609.44 609.44 587.45 587.45 609.44 609.44 +670.95 670.95 670.95 616.04 638.65 638.65 616.04 616.04 638.65 638.65 +708.56 708.56 708.56 649.09 656.63 656.63 649.09 649.09 656.63 656.63 +748.43 748.43 748.43 696.78 725.09 725.09 696.78 696.78 725.09 725.09 +787.77 787.77 787.77 759.41 776.96 776.96 759.41 759.41 776.96 776.96 +819.54 819.54 819.54 804.85 825.45 825.45 804.85 804.85 825.45 825.45 +878.07 878.07 878.07 859.23 875.08 875.08 859.23 859.23 875.08 875.08 +917.81 917.81 917.81 920.15 909.41 909.41 920.15 920.15 909.41 909.41 +954.87 954.87 954.87 946.29 946.92 946.92 946.29 946.29 946.92 946.92 +968.34 968.34 968.34 980.20 969.02 969.02 980.20 980.20 969.02 969.02 +997.66 997.66 997.66 974.45 964.50 964.50 974.45 974.45 964.50 964.50 +979.95 979.95 979.95 979.87 967.11 967.11 979.87 979.87 967.11 967.11 +952.86 952.86 952.86 969.75 960.51 960.51 969.75 969.75 960.51 960.51 +918.57 918.57 918.57 945.83 928.41 928.41 945.83 945.83 928.41 928.41 +873.23 873.23 873.23 901.61 882.36 882.36 901.61 901.61 882.36 882.36 +825.50 825.50 825.50 866.36 829.64 829.64 866.36 866.36 829.64 829.64 +787.28 787.28 787.28 827.65 785.79 785.79 827.65 827.65 785.79 785.79 +742.14 742.14 742.14 752.99 733.81 733.81 752.99 752.99 733.81 733.81 +689.14 689.14 689.14 705.16 668.63 668.63 705.16 705.16 668.63 668.63 +643.76 643.76 643.76 662.34 614.34 614.34 662.34 662.34 614.34 614.34 +588.48 588.48 588.48 610.00 578.93 578.93 610.00 610.00 578.93 578.93 +571.05 571.05 571.05 576.51 530.17 530.17 576.51 576.51 530.17 530.17 +574.85 574.85 574.85 554.32 508.14 508.14 554.32 554.32 508.14 508.14 +568.74 568.74 568.74 558.97 510.23 510.23 558.97 558.97 510.23 510.23 +581.70 581.70 581.70 568.86 512.80 512.80 568.86 568.86 512.80 512.80 +623.05 623.05 623.05 603.20 561.24 561.24 603.20 603.20 561.24 561.24 +663.47 663.47 663.47 649.36 590.15 590.15 649.36 649.36 590.15 590.15 +707.47 707.47 707.47 703.86 644.48 644.48 703.86 703.86 644.48 644.48 +766.59 766.59 766.59 779.02 701.20 701.20 779.02 779.02 701.20 701.20 +799.28 799.28 799.28 848.32 755.85 755.85 848.32 848.32 755.85 755.85 +862.05 862.05 862.05 904.88 786.72 786.72 904.88 904.88 786.72 786.72 +907.74 907.74 907.74 937.81 840.95 840.95 937.81 937.81 840.95 840.95 +939.53 939.53 939.53 949.73 867.49 867.49 949.73 949.73 867.49 867.49 +959.92 959.92 959.92 960.74 892.86 892.86 960.74 960.74 892.86 892.86 +963.58 963.58 963.58 977.74 901.87 901.87 977.74 977.74 901.87 901.87 +952.67 952.67 952.67 985.29 884.71 884.71 985.29 985.29 884.71 884.71 +941.50 941.50 941.50 969.58 881.33 881.33 969.58 969.58 881.33 881.33 +902.83 902.83 902.83 951.84 846.61 846.61 951.84 951.84 846.61 846.61 +847.71 847.71 847.71 918.52 812.76 812.76 918.52 918.52 812.76 812.76 +810.54 810.54 810.54 866.48 784.11 784.11 866.48 866.48 784.11 784.11 +755.70 755.70 755.70 808.37 720.49 720.49 808.37 808.37 720.49 720.49 +690.78 690.78 690.78 752.61 669.61 669.61 752.61 752.61 669.61 669.61 +626.95 626.95 626.95 695.79 620.24 620.24 695.79 695.79 620.24 620.24 +581.86 581.86 581.86 646.56 579.51 579.51 646.56 646.56 579.51 579.51 +566.61 566.61 566.61 610.52 542.83 542.83 610.52 610.52 542.83 542.83 +531.96 531.96 531.96 576.68 516.87 516.87 576.68 576.68 516.87 516.87 +512.81 512.81 512.81 569.72 513.70 513.70 569.72 569.72 513.70 513.70 +523.64 523.64 523.64 567.76 516.26 516.26 567.76 567.76 516.26 516.26 +548.83 548.83 548.83 571.14 550.21 550.21 571.14 571.14 550.21 550.21 +569.92 569.92 569.92 594.04 574.93 574.93 594.04 594.04 574.93 574.93 +620.07 620.07 620.07 645.13 608.41 608.41 645.13 645.13 608.41 608.41 +671.38 671.38 671.38 699.43 652.80 652.80 699.43 699.43 652.80 652.80 +728.82 728.82 728.82 736.58 712.71 712.71 736.58 736.58 712.71 712.71 +784.53 784.53 784.53 786.81 767.96 767.96 786.81 786.81 767.96 767.96 +847.24 847.24 847.24 819.52 829.79 829.79 819.52 819.52 829.79 829.79 +886.23 886.23 886.23 865.49 884.90 884.90 865.49 865.49 884.90 884.90 +913.70 913.70 913.70 894.17 923.98 923.98 894.17 894.17 923.98 923.98 +933.05 933.05 933.05 919.64 961.98 961.98 919.64 919.64 961.98 961.98 +946.60 946.60 946.60 940.28 980.46 980.46 940.28 940.28 980.46 980.46 +948.25 948.25 948.25 932.20 981.61 981.61 932.20 932.20 981.61 981.61 +939.73 939.73 939.73 909.46 951.15 951.15 909.46 909.46 951.15 951.15 +908.30 908.30 908.30 883.00 932.05 932.05 883.00 883.00 932.05 932.05 +862.80 862.80 862.80 850.93 893.12 893.12 850.93 850.93 893.12 893.12 +818.61 818.61 818.61 814.96 869.79 869.79 814.96 814.96 869.79 869.79 +758.62 758.62 758.62 760.83 829.59 829.59 760.83 760.83 829.59 829.59 +704.35 704.35 704.35 715.37 774.26 774.26 715.37 715.37 774.26 774.26 +654.97 654.97 654.97 651.93 736.62 736.62 651.93 651.93 736.62 736.62 +622.20 622.20 622.20 622.01 681.30 681.30 622.01 622.01 681.30 681.30 +594.33 594.33 594.33 575.94 638.76 638.76 575.94 575.94 638.76 638.76 +562.40 562.40 562.40 552.39 616.25 616.25 552.39 552.39 616.25 616.25 +555.64 555.64 555.64 557.68 612.46 612.46 557.68 557.68 612.46 612.46 +563.89 563.89 563.89 564.76 618.17 618.17 564.76 564.76 618.17 618.17 +564.91 564.91 564.91 582.89 641.17 641.17 582.89 582.89 641.17 641.17 +592.70 592.70 592.70 626.43 656.00 656.00 626.43 626.43 656.00 656.00 +638.00 638.00 638.00 662.92 693.57 693.57 662.92 662.92 693.57 693.57 +680.51 680.51 680.51 717.27 748.33 748.33 717.27 717.27 748.33 748.33 +734.53 734.53 734.53 758.50 818.97 818.97 758.50 758.50 818.97 818.97 +801.78 801.78 801.78 818.75 865.80 865.80 818.75 818.75 865.80 865.80 +863.21 863.21 863.21 877.49 890.84 890.84 877.49 877.49 890.84 890.84 +901.22 901.22 901.22 923.37 916.69 916.69 923.37 923.37 916.69 916.69 +923.85 923.85 923.85 946.17 964.37 964.37 946.17 946.17 964.37 964.37 +958.11 958.11 958.11 988.48 984.70 984.70 988.48 988.48 984.70 984.70 +964.73 964.73 964.73 994.98 996.00 996.00 994.98 994.98 996.00 996.00 +956.75 956.75 956.75 1006.10 981.21 981.21 1006.10 1006.10 981.21 981.21 +914.74 914.74 914.74 988.09 976.06 976.06 988.09 988.09 976.06 976.06 +867.86 867.86 867.86 948.33 958.01 958.01 948.33 948.33 958.01 958.01 +833.26 833.26 833.26 893.81 920.04 920.04 893.81 893.81 920.04 920.04 +770.47 770.47 770.47 866.33 865.42 865.42 866.33 866.33 865.42 865.42 +749.76 749.76 749.76 802.65 824.62 824.62 802.65 802.65 824.62 824.62 +692.32 692.32 692.32 755.66 784.63 784.63 755.66 755.66 784.63 784.63 +630.36 630.36 630.36 708.53 724.93 724.93 708.53 708.53 724.93 724.93 +586.52 586.52 586.52 673.73 657.81 657.81 673.73 673.73 657.81 657.81 +558.17 558.17 558.17 631.15 617.89 617.89 631.15 631.15 617.89 617.89 +559.96 559.96 559.96 608.20 594.54 594.54 608.20 608.20 594.54 594.54 +558.93 558.93 558.93 581.55 584.27 584.27 581.55 581.55 584.27 584.27 +569.63 569.63 569.63 572.28 588.96 588.96 572.28 572.28 588.96 588.96 +592.12 592.12 592.12 584.21 605.72 605.72 584.21 584.21 605.72 605.72 +612.46 612.46 612.46 619.65 644.08 644.08 619.65 619.65 644.08 644.08 +654.46 654.46 654.46 654.39 681.08 681.08 654.39 654.39 681.08 681.08 +708.22 708.22 708.22 690.22 713.72 713.72 690.22 690.22 713.72 713.72 +767.72 767.72 767.72 752.23 770.49 770.49 752.23 752.23 770.49 770.49 +814.89 814.89 814.89 834.15 810.51 810.51 834.15 834.15 810.51 810.51 +855.40 855.40 855.40 902.67 865.89 865.89 902.67 902.67 865.89 865.89 +878.26 878.26 878.26 932.50 909.85 909.85 932.50 932.50 909.85 909.85 +904.84 904.84 904.84 963.70 936.62 936.62 963.70 963.70 936.62 936.62 +921.16 921.16 921.16 994.48 954.21 954.21 994.48 994.48 954.21 954.21 +932.34 932.34 932.34 999.35 956.88 956.88 999.35 999.35 956.88 956.88 +919.31 919.31 919.31 995.02 940.79 940.79 995.02 995.02 940.79 940.79 +888.97 888.97 888.97 961.47 925.79 925.79 961.47 961.47 925.79 925.79 +861.87 861.87 861.87 913.87 888.33 888.33 913.87 913.87 888.33 888.33 +819.89 819.89 819.89 866.91 832.03 832.03 866.91 866.91 832.03 832.03 +777.43 777.43 777.43 820.16 787.37 787.37 820.16 820.16 787.37 787.37 +706.45 706.45 706.45 780.91 735.12 735.12 780.91 780.91 735.12 735.12 +654.99 654.99 654.99 737.34 679.43 679.43 737.34 737.34 679.43 679.43 +603.18 603.18 603.18 700.01 631.68 631.68 700.01 700.01 631.68 631.68 +561.13 561.13 561.13 650.36 576.27 576.27 650.36 650.36 576.27 576.27 +550.30 550.30 550.30 603.12 551.00 551.00 603.12 603.12 551.00 551.00 +551.96 551.96 551.96 583.11 521.93 521.93 583.11 583.11 521.93 521.93 +547.61 547.61 547.61 569.66 529.63 529.63 569.66 569.66 529.63 529.63 +553.79 553.79 553.79 584.26 520.73 520.73 584.26 584.26 520.73 520.73 +568.64 568.64 568.64 607.46 532.98 532.98 607.46 607.46 532.98 532.98 diff --git a/examples/Begin Stochastic/monte-carlo.png b/examples/Begin Stochastic/monte-carlo.png new file mode 100644 index 0000000..f285348 Binary files /dev/null and b/examples/Begin Stochastic/monte-carlo.png differ diff --git a/examples/Begin Stochastic/nuclear.csv b/examples/Begin Stochastic/nuclear.csv new file mode 100644 index 0000000..f18bb9d --- /dev/null +++ b/examples/Begin Stochastic/nuclear.csv @@ -0,0 +1,168 @@ +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 4700.00 4700.00 4700.00 5000.00 5000.00 4700.00 +5000.00 5000.00 5000.00 5000.00 4700.00 4700.00 4700.00 5000.00 5000.00 4700.00 +5000.00 5000.00 5000.00 5000.00 4700.00 4700.00 4700.00 5000.00 5000.00 4700.00 +5000.00 5000.00 5000.00 5000.00 4400.00 4700.00 4400.00 5000.00 5000.00 4400.00 +5000.00 5000.00 5000.00 5000.00 4400.00 4700.00 4400.00 5000.00 5000.00 4400.00 +5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 +5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 +5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +4700.00 4700.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 4700.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 4700.00 5000.00 5000.00 5000.00 5000.00 4700.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 +5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 5000.00 diff --git a/examples/Cost and Prioritization/Cost and Prioritization.ipynb b/examples/Cost and Prioritization/Cost and Prioritization.ipynb index 21fe3bf..6cdc28f 100644 --- a/examples/Cost and Prioritization/Cost and Prioritization.ipynb +++ b/examples/Cost and Prioritization/Cost and Prioritization.ipynb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9cf3b838ec6dff2468bf17b2b0dad08c8cde2bfbc0b7032a65be0910ae6be2af -size 3632689 +oid sha256:04b6a888975fdc18c8975e110c00232dc30cfdb5981d546328ace3fe0a0c7f39 +size 3720900 diff --git a/examples/FR-DE Adequacy/FR-DE Adequacy.ipynb b/examples/FR-DE Adequacy/FR-DE Adequacy.ipynb index d170858..ac5d78d 100644 --- a/examples/FR-DE Adequacy/FR-DE Adequacy.ipynb +++ b/examples/FR-DE Adequacy/FR-DE Adequacy.ipynb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e274f7e5b8a6f32804b55bead564198e8a1b23c06fd40227c87d2dc8e45eb2c -size 6995428 +oid sha256:09fcd23634252ed9a8af5d462bde6407f15ec0a0d04e3584f3d70a2355a628c4 +size 7210221 diff --git a/examples/Get Started/Get Started.ipynb b/examples/Get Started/Get Started.ipynb index d905370..f5a0d90 100644 --- a/examples/Get Started/Get Started.ipynb +++ b/examples/Get Started/Get Started.ipynb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b68ea3107fbc6c8ea23fbaae2b514c88150d35b5199d89f3605f1f3f0eeb2b82 -size 3620364 +oid sha256:1709763186983ae7e53e63623559f7385f95805f98215004664d261e73672fb9 +size 3705974 diff --git a/examples/Worflow Advenced/Workflow Advenced.ipynb b/examples/Worflow Advenced/Workflow Advenced.ipynb new file mode 100644 index 0000000..4166eda --- /dev/null +++ b/examples/Worflow Advenced/Workflow Advenced.ipynb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:babc67b4bf395c458cc78c0b8e228f46e821a7b6bc414766be74d17478eaa1ea +size 3679100 diff --git a/examples/Workflow/Workflow.ipynb b/examples/Workflow/Workflow.ipynb new file mode 100644 index 0000000..d9d9d8a --- /dev/null +++ b/examples/Workflow/Workflow.ipynb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84a58202970a1bf1dc3aab2bb70fd64c3ea0264adb69dc76c9dae98b259a734d +size 4046391 diff --git a/examples/Workflow/shuffler.png b/examples/Workflow/shuffler.png new file mode 100644 index 0000000..01c9353 Binary files /dev/null and b/examples/Workflow/shuffler.png differ diff --git a/examples/check.py b/examples/check.py deleted file mode 100644 index eebbea3..0000000 --- a/examples/check.py +++ /dev/null @@ -1,47 +0,0 @@ -import sys -from typing import List - -import nbformat -import os -from nbconvert import HTMLExporter -from nbconvert.preprocessors import ExecutePreprocessor - -exporter = HTMLExporter() -ep = ExecutePreprocessor(timeout=600, kernel_name='python3', store_widget_state=True) - - -def read(name: str) -> nbformat: - print('Reading...', end=' ') - nb = nbformat.read('{name}/{name}.ipynb'.format(name=name), as_version=4) - print('OK', end=' ') - return nb - - -def execute(nb: nbformat, name: str) -> nbformat: - print('Executing...', end=' ') - ep.preprocess(nb, {'metadata': {'path': '%s/' % name}}) - print('OK', end=' ') - return nb - - -def export(nb: nbformat, name: str): - print('Exporting...', end=' ') - html, _ = exporter.from_notebook_node(nb) - with open('../public/%s/index.html' % name, 'w') as f: - f.write(html) - print('OK', end=' ') - - -def list_notebook() -> List[str]: - dirs = os.listdir('.') - return [d for d in dirs if os.path.isfile('{name}/{name}.ipynb'.format(name=d))] - - -if __name__ == '__main__': - for name in list_notebook(): - print(name, ':', end='') - nb = read(name) - nb = execute(nb, name) - if len(sys.argv) > 1 and sys.argv[1] == 'export': - export(nb, name) - print('') diff --git a/examples/requirements.txt b/examples/requirements.txt index f257e10..37f0d78 100644 --- a/examples/requirements.txt +++ b/examples/requirements.txt @@ -1,4 +1,6 @@ numpy pandas hadar +plotly jupyter +click diff --git a/examples/utils.py b/examples/utils.py new file mode 100644 index 0000000..8b466e0 --- /dev/null +++ b/examples/utils.py @@ -0,0 +1,116 @@ +# Copyright (c) 2019-2020, RTE (https://www.rte-france.com) +# See AUTHORS.txt +# This Source Code Form is subject to the terms of the Apache License, version 2.0. +# If a copy of the Apache License, version 2.0 was not distributed with this file, you can obtain one at http://www.apache.org/licenses/LICENSE-2.0. +# SPDX-License-Identifier: Apache-2.0 +# This file is part of hadar-simulator, a python adequacy library for everyone. + +import sys +import click +from typing import List + +import nbformat +import os +from nbconvert import HTMLExporter +from nbconvert.preprocessors import ExecutePreprocessor + +exporter = HTMLExporter() +ep = ExecutePreprocessor(timeout=600, kernel_name='python3', store_widget_state=True) + + +def open_nb(name: str, src: str) -> nbformat: + """ + Open notebook file + + :param name: name of notebook to open + :param src: source directory + :return: notebook object + """ + print('Reading...', end=' ') + nb = nbformat.read('{src}/{name}/{name}.ipynb'.format(name=name, src=src), as_version=4) + print('OK', end=' ') + return nb + + +def execute(nb: nbformat, name: str, src: str) -> nbformat: + """ + Execute notebook and store widget state. + + :param nb: notebook object to execute + :param name: notebook name (for setup directory context purpose) + :param src: notebook source directory (for setup context) + :return: notebook object with computed and stored output widget state + """ + print('Executing...', end=' ') + ep.preprocess(nb, {'metadata': {'path': '%s/%s/' % (src, name)}}) + print('OK', end=' ') + return nb + + +def copy_image(name: str, export: str, src: str): + """ + Copy images present next to notebook file to exported folder. + + :param name: notebook name + :param export: export directory + :param src: source directory + :return: None + """ + src = '%s/%s' % (src, name) + dest = '%s/%s' % (export, name) + images = [f for f in os.listdir(src) if f.split('.')[-1] in ['png']] + for img in images: + os.rename('%s/%s' % (src, img), '%s/%s' % (dest, img)) + + +def to_export(nb: nbformat, name: str, export: str): + """ + Export notebook into HTML format. + + :param nb: notebook with result state + :param name: notebook name + :param export: directory to export + :return: None + """ + print('Exporting...', end=' ') + html, _ = exporter.from_notebook_node(nb) + + path = '%s/%s' % (export, name) + if not os.path.exists(path): + os.makedirs(path) + + with open('%s/index.html' % path, 'w') as f: + f.write(html) + + print('OK', end=' ') + + +def list_notebook(src: str) -> List[str]: + """ + List available notebook in directory. + + :return: + """ + dirs = os.listdir(src) + return [d for d in dirs if os.path.isfile('{src}/{name}/{name}.ipynb'.format(name=d, src=src))] + + +@click.command('Check and export notebooks') +@click.option('--src', nargs=1, help='Notebook directory') +@click.option('--check', nargs=1, help='check notebook according to result file given') +@click.option('--export', nargs=1, help='export notebooks to directory given') +def main(src: str, check: str, export: str): + for name in list_notebook(src): + print(name, ':', end='') + nb = open_nb(name, src) + nb = execute(nb, name, src) + if check: + pass # Implement check + if export: + to_export(nb, name, export) + copy_image(name, export, src) + print('') + + +if __name__ == '__main__': + main() diff --git a/hadar/__init__.py b/hadar/__init__.py index bfc0345..41a51b0 100644 --- a/hadar/__init__.py +++ b/hadar/__init__.py @@ -9,16 +9,15 @@ import os import sys -from .workflow.pipeline import RestrictedPlug, FreePlug, Stage, FocusStage, Drop, Rename, Fault, RepeatScenario, ToShuffler +from .workflow.pipeline import RestrictedPlug, FreePlug, Stage, FocusStage, Drop, Rename, Fault, RepeatScenario, ToShuffler, Clip from .workflow.shuffler import Shuffler from .optimizer.input import Consumption, Link, Production, InputNode, Study from .optimizer.output import OutputProduction, OutputNode, OutputLink, OutputConsumption, Result from .optimizer.optimizer import LPOptimizer, RemoteOptimizer from .viewer.html import HTMLPlotting -from .viewer.jupyter import JupyterPlotting from .analyzer.result import ResultAnalyzer -__version__ = '0.2.0' +__version__ = '0.3.0' level = os.getenv('HADAR_LOG', 'WARNING') diff --git a/hadar/analyzer/result.py b/hadar/analyzer/result.py index 278bb91..a474d34 100644 --- a/hadar/analyzer/result.py +++ b/hadar/analyzer/result.py @@ -57,7 +57,7 @@ def filter(self, df: pd.DataFrame) -> pd.Series: return df[self.column].notnull() return df[self.column].isin(self.index) - def is_alone(self): + def is_alone(self) -> bool: """ Ask if index filter element is alone. @@ -374,6 +374,31 @@ def get_cost(self, node: str) -> np.ndarray: return cost + def get_rac(self) -> np.ndarray: + prod_used = self.production\ + .drop(['avail', 'cost'], axis=1)\ + .pivot_table(index='scn', columns='t', aggfunc=np.sum)\ + .values + + prod_avail = self.production\ + .drop(['used', 'cost'], axis=1)\ + .pivot_table(index='scn', columns='t', aggfunc=np.sum)\ + .values + + cons_asked = self.consumption\ + .drop(['given', 'cost'], axis=1)\ + .pivot_table(index='scn', columns='t', aggfunc=np.sum)\ + .values + + cons_given = self.consumption\ + .drop(['asked', 'cost'], axis=1)\ + .pivot_table(index='scn', columns='t', aggfunc=np.sum)\ + .values + + rac = (prod_avail - prod_used) - (cons_asked - cons_given) + + return rac + @property def horizon(self) -> int: """ diff --git a/hadar/optimizer/lp/mapper.py b/hadar/optimizer/lp/mapper.py index c68b601..746ada2 100644 --- a/hadar/optimizer/lp/mapper.py +++ b/hadar/optimizer/lp/mapper.py @@ -36,16 +36,16 @@ def get_var(self, name: str, t: int, scn: int) -> LPNode: :param scn: scenario index :return: LPNode according to node name at t in study """ - consumptions = [LPConsumption(name=c.name, cost=float(c.cost), quantity=c.quantity[scn][t], - variable=self.solver.NumVar(0, float(c.quantity[scn][t]), name='lol {} on {} at t={} for scn={}'.format(c.name, name, t, scn))) + consumptions = [LPConsumption(name=c.name, cost=float(c.cost), quantity=c.quantity[scn, t], + variable=self.solver.NumVar(0, float(c.quantity[scn, t]), name='lol {} on {} at t={} for scn={}'.format(c.name, name, t, scn))) for c in self.study.nodes[name].consumptions] - productions = [LPProduction(name=p.name, cost=float(p.cost), quantity=p.quantity[scn][t], - variable=self.solver.NumVar(0, float(p.quantity[scn][t]), 'prod {} on {} at t={} for scn={}'.format(p.name, name, t, scn))) + productions = [LPProduction(name=p.name, cost=float(p.cost), quantity=p.quantity[scn, t], + variable=self.solver.NumVar(0, float(p.quantity[scn, t]), 'prod {} on {} at t={} for scn={}'.format(p.name, name, t, scn))) for p in self.study.nodes[name].productions] - links = [LPLink(dest=l.dest, cost=float(l.cost), src=name, quantity=l.quantity[scn][t], - variable=self.solver.NumVar(0, float(l.quantity[scn][t]), 'link on {} to {} at t={} for scn={}'.format(name, l.dest, t, scn))) + links = [LPLink(dest=l.dest, cost=float(l.cost), src=name, quantity=l.quantity[scn, t], + variable=self.solver.NumVar(0, float(l.quantity[scn, t]), 'link on {} to {} at t={} for scn={}'.format(name, l.dest, t, scn))) for l in self.study.nodes[name].links] return LPNode(consumptions=consumptions, productions=productions, links=links) diff --git a/hadar/viewer/abc.py b/hadar/viewer/abc.py index f7ac153..d3774ee 100644 --- a/hadar/viewer/abc.py +++ b/hadar/viewer/abc.py @@ -4,19 +4,331 @@ # If a copy of the Apache License, version 2.0 was not distributed with this file, you can obtain one at http://www.apache.org/licenses/LICENSE-2.0. # SPDX-License-Identifier: Apache-2.0 # This file is part of hadar-simulator, a python adequacy library for everyone. +from typing import List, Tuple, Dict +import numpy as np +import pandas as pd from abc import ABC, abstractmethod +from hadar.analyzer.result import ResultAnalyzer -class ABCPlotting(ABC): - """ - Abstract method to plot optimizer result. - """ + +class ABCElementPlotting(ABC): + @abstractmethod + def timeline(self, df: pd.DataFrame, title: str): + pass + + @abstractmethod + def monotone(self, y: np.ndarray, title: str): + pass + + @abstractmethod + def gaussian(self, rac: np.ndarray, qt: np.ndarray, title: str): + pass @abstractmethod - def stack(self, node: str): + def stack(self, areas: List[Tuple[str, np.ndarray]], lines: List[Tuple[str, np.ndarray]], title: str): pass @abstractmethod - def exchanges_map(self, t: int, limit: int): - pass \ No newline at end of file + def matrix(self, data: np.ndarray, title): + pass + + def map_exchange(self, nodes, lines, limit, title, zoom): + pass + + +class Element(ABC): + def __init__(self, plotting: ABCElementPlotting, agg: ResultAnalyzer): + self.plotting = plotting + self.agg = agg + + @staticmethod + def not_both(t: int, scn: int): + if t is not None and scn is not None: + raise ValueError('you have to specify time or scenario index but not both') + + +class ConsumptionElement(Element): + def __init__(self, plotting: ABCElementPlotting, agg: ResultAnalyzer, name: str, node: str, kind: str): + Element.__init__(self, plotting, agg) + self.name = name + self.node = node + self.kind = kind + + def timeline(self): + cons = self.agg.agg_cons(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.iscn, self.agg.itime)[self.kind] + title = 'Consumptions %s for %s on node %s' % (self.kind, self.name, self.node) + return self.plotting.timeline(cons, title) + + def monotone(self, t: int = None, scn: int = None): + Element.not_both(t, scn) + + if t is not None: + y = self.agg.agg_cons(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.itime[t], self.agg.iscn)[self.kind].values + title = 'Monotone consumption of %s on node %s at t=%0d' % (self.name, self.node, t) + elif scn is not None: + y = self.agg.agg_cons(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.iscn[scn], self.agg.itime)[self.kind].values + title = 'Monotone consumption of %s on node %s at scn=%0d' % (self.name, self.node, scn) + + return self.plotting.monotone(y, title) + + def gaussian(self, t: int = None, scn: int = None): + Element.not_both(t, scn) + + if t is None: + cons = self.agg.agg_cons(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.iscn[scn], self.agg.itime)[self.kind].values + rac = self.agg.get_rac()[scn, :] + title = 'Gaussian consumption of %s on node %s at scn=%0d' % (self.name, self.node, scn) + elif scn is None: + cons = self.agg.agg_cons(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.itime[t], self.agg.iscn)[self.kind].values + rac = self.agg.get_rac()[:, t] + title = 'Gaussian consumption of %s on node %s at t=%0d' % (self.name, self.node, t) + + return self.plotting.gaussian(rac=rac, qt=cons, title=title) + + +class ProductionElement(Element): + def __init__(self, plotting: ABCElementPlotting, agg: ResultAnalyzer, name: str, node: str, kind: str): + Element.__init__(self, plotting, agg) + self.name = name + self.node = node + self.kind = kind + + def timeline(self): + prod = self.agg.agg_prod(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.iscn, self.agg.itime)[self.kind] + title = 'Production %s for %s on node %s' % (self.kind, self.name, self.node) + return self.plotting.timeline(prod, title) + + def monotone(self, t: int = None, scn: int = None): + Element.not_both(t, scn) + + if t is not None: + y = self.agg.agg_prod(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.itime[t], self.agg.iscn)[self.kind].values + title = 'Monotone production of %s on node %s at t=%0d' % (self.name, self.node, t) + elif scn is not None: + y = self.agg.agg_prod(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.iscn[scn], self.agg.itime)[self.kind].values + title = 'Monotone production of %s on node %s at scn=%0d' % (self.name, self.node, scn) + + return self.plotting.monotone(y, title) + + def gaussian(self, t: int = None, scn: int = None): + Element.not_both(t, scn) + + if t is None: + prod = self.agg.agg_prod(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.iscn[scn], self.agg.itime)[self.kind].values + rac = self.agg.get_rac()[scn, :] + title = 'Gaussian production of %s on node %s at scn=%0d' % (self.name, self.node, scn) + elif scn is None: + prod = self.agg.agg_prod(self.agg.inode[self.node], self.agg.iname[self.name], + self.agg.itime[t], self.agg.iscn)[self.kind].values + rac = self.agg.get_rac()[:, t] + title = 'Gaussian production of %s on node %s at t=%0d' % (self.name, self.node, t) + + return self.plotting.gaussian(rac=rac, qt=prod, title=title) + + +class LinkElement(Element): + def __init__(self, plotting: ABCElementPlotting, agg: ResultAnalyzer, src: str, dest: str, kind: str): + Element.__init__(self, plotting, agg) + self.src = src + self.dest = dest + self.kind = kind + + def timeline(self): + links = self.agg.agg_link(self.agg.isrc[self.src], self.agg.idest[self.dest], self.agg.iscn, + self.agg.itime)[self.kind] + title = 'Link %s from %s to %s' % (self.kind, self.src, self.dest) + return self.plotting.timeline(links, title) + + def monotone(self, t: int = None, scn: int = None): + Element.not_both(t, scn) + + if t is not None: + y = self.agg.agg_link(self.agg.isrc[self.src], self.agg.idest[self.dest], + self.agg.itime[t], self.agg.iscn)[self.kind].values + title = 'Monotone link from %s to %s at t=%0d' % (self.src, self.dest, t) + elif scn is not None: + y = self.agg.agg_link(self.agg.isrc[self.src], self.agg.idest[self.dest], + self.agg.iscn[scn], self.agg.itime)[self.kind].values + title = 'Monotone link from %s to %s at scn=%0d' % (self.src, self.dest, scn) + + return self.plotting.monotone(y, title) + + def gaussian(self, t: int = None, scn: int = None): + Element.not_both(t, scn) + + if t is None: + prod = self.agg.agg_link(self.agg.isrc[self.src], self.agg.idest[self.dest], + self.agg.iscn[scn], self.agg.itime)[self.kind].values + rac = self.agg.get_rac()[scn, :] + title = 'Gaussian link from %s to %s at t=%0d' % (self.src, self.dest, scn) + elif scn is None: + prod = self.agg.agg_prod(self.agg.isrc[self.src], self.agg.idest[self.dest], + self.agg.itime[t], self.agg.iscn)[self.kind].values + rac = self.agg.get_rac()[:, t] + title = 'Gaussian link from %s to %s at t=%0d' % (self.src, self.dest, t) + + return self.plotting.gaussian(rac=rac, qt=prod, title=title) + + +class NodeElement(Element): + def __init__(self, plotting: ABCElementPlotting, agg: ResultAnalyzer, node: str): + Element.__init__(self, plotting, agg) + self.node = node + + def stack(self, scn: int = 0, prod_kind: str = 'used', cons_kind: str = 'asked'): + """ + Plot with production stacked with area and consumptions stacked by dashed lines. + + :param node: select node to plot. + :param scn: scenario index to plot. + :param prod_kind: select which prod to stack : available ('avail') or 'used' + :param cons_kind: select which cons to stack : 'asked' or 'given' + :return: plotly figure or jupyter widget to plot + """ + c, p, b = self.agg.get_elements_inside(node=self.node) + + areas = [] + # stack production with area + if p > 0: + prod = self.agg.agg_prod(self.agg.iscn[scn], self.agg.inode[self.node], self.agg.iname, self.agg.itime) \ + .sort_values('cost', ascending=True) + for i, name in enumerate(prod.index.get_level_values('name').unique()): + areas.append((name, prod.loc[name][prod_kind].sort_index().values)) + + # add import in production stack + balance = self.agg.get_balance(node=self.node)[scn] + im = -np.clip(balance, None, 0) + if not (im == 0).all(): + areas.append(('import', im)) + + lines = [] + # Stack consumptions with line + if c > 0: + cons = self.agg.agg_cons(self.agg.iscn[scn], self.agg.inode[self.node], self.agg.iname, self.agg.itime) \ + .sort_values('cost', ascending=False) + for i, name in enumerate(cons.index.get_level_values('name').unique()): + lines.append((name, cons.loc[name][cons_kind].sort_index().values)) + + # Add export in consumption stack + exp = np.clip(balance, 0, None) + if not (exp == 0).all(): + lines.append(('export', exp)) + + title = 'Stack for node %s' % self.node + + return self.plotting.stack(areas, lines, title) + + +class NetworkElement(Element): + def rac_matrix(self): + rac = self.agg.get_rac() + pct = (rac >= 0).sum() / rac.size * 100 + title = "RAC Matrix %0d %% passed" % pct + + return self.plotting.matrix(data=rac, title=title) + + def map(self, t: int, zoom: int, scn: int = 0, limit: int = None): + nodes = {node: self.agg.get_balance(node=node)[scn, t] for node in self.agg.nodes} + + if limit is None: + limit = max(max(nodes.values()), -min(nodes.values())) + + lines = {} + # Compute lines + links = self.agg.agg_link(self.agg.iscn[scn], self.agg.itime[t], self.agg.isrc, self.agg.idest) + for src in links.index.get_level_values('src').unique(): + for dest in links.loc[src].index.get_level_values('dest').unique(): + exchange = links.loc[src, dest]['used'] # forward + exchange -= links.loc[dest, src]['used'] if (dest, src) in links.index else 0 # backward + + if exchange >= 0: + lines[(src, dest)] = exchange + else: + lines[(dest, src)] = -exchange + + title = 'Exchange map at t=%0d scn=%0d' % (t, scn) + return self.plotting.map_exchange(nodes, lines, limit, title, zoom) + + +class Plotting(ABC): + """ + Abstract method to plot optimizer result. + """ + + def __init__(self, agg: ResultAnalyzer, + unit_symbol: str = '', + time_start=None, time_end=None, + node_coord: Dict[str, List[float]] = None): + """ + Create instance. + + :param agg: ResultAggragator instence to use + :param unit_symbol: symbol on quantity unit used. ex. MW, litter, Go, ... + :param time_start: time to use as the start of study horizon + :param time_end: time to use as the end of study horizon + :param node_coord: nodes coordinates to use for map plotting + :param map_element_size: size on element draw on map. default as 1. + """ + self.plotting = None + self.agg = agg + self.unit = '(%s)' % unit_symbol if unit_symbol != '' else '' + self.coord = node_coord + + # Create time_index + time = [time_start is None, time_end is None] + if time == [True, False] or time == [False, True]: + raise ValueError('You have to give both time_start and time_end') + elif time == [False, False]: + self.time_index = pd.date_range(start=time_start, end=time_end, periods=self.agg.horizon) + else: + self.time_index = np.arange(self.agg.horizon) + + def node(self, node: str): + return NodeElement(plotting=self.plotting, agg=self.agg, node=node) + + def consumption(self, node: str, name: str, kind: str = 'given') -> ConsumptionElement: + """ + Plot all timelines consumption scenario. + + :param node: selected node name + :param name: select consumption name + :param kind: kind of data 'asked' or 'given' + :return: + """ + return ConsumptionElement(plotting=self.plotting, agg=self.agg, node=node, name=name, kind=kind) + + def production(self, node: str, name: str, kind: str = 'used') -> ProductionElement: + """ + Plot all timelines production scenario. + + :param node: selected node name + :param name: select production name + :param kind: kind of data available ('avail') or 'used' + :return: + """ + return ProductionElement(plotting=self.plotting, agg=self.agg, node=node, name=name, kind=kind) + + def link(self, src: str, dest: str, kind: str = 'used'): + """ + Plot all timelines links scenario. + + :param src: selected source node name + :param dest: select destination node name + :param kind: kind of data available ('avail') or 'used' + :return: + """ + return LinkElement(plotting=self.plotting, agg=self.agg, src=src, dest=dest, kind=kind) + + def network(self): + return NetworkElement(plotting=self.plotting, agg=self.agg) diff --git a/hadar/viewer/html.py b/hadar/viewer/html.py index 17243e8..8f011ad 100644 --- a/hadar/viewer/html.py +++ b/hadar/viewer/html.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: Apache-2.0 # This file is part of hadar-simulator, a python adequacy library for everyone. -from typing import Dict, List +from typing import Dict, List, Tuple import numpy as np import pandas as pd @@ -13,49 +13,20 @@ from matplotlib.cm import coolwarm from hadar.analyzer.result import ResultAnalyzer, NodeIndex, SrcIndex, TimeIndex, DestIndex, NameIndex -from hadar.viewer.abc import ABCPlotting - +from hadar.viewer.abc import Plotting, ConsumptionElement, ABCElementPlotting, ProductionElement, LinkElement, \ + NodeElement, NetworkElement __all__ = ['HTMLPlotting'] -class HTMLPlotting(ABCPlotting): - """ - Plotting implementation interactive html graphics. (Use plotly) - """ - def __init__(self, agg: ResultAnalyzer, unit_symbol: str = '', - time_start=None, time_end=None, - cmap=coolwarm, - node_coord: Dict[str, List[float]] = None, - map_element_size: int = 1): - """ - Create instance. - - :param agg: ResultAggragator instence to use - :param unit_symbol: symbol on quantity unit used. ex. MW, litter, Go, ... - :param time_start: time to use as the start of study horizon - :param time_end: time to use as the end of study horizon - :param cmap: matplotlib color map to use (coolwarm as default) - :param node_coord: nodes coordinates to use for map plotting - :param map_element_size: size on element draw on map. default as 1. - """ - self.agg = agg - self.unit = '(%s)' % unit_symbol if unit_symbol != '' else '' +class HTMLElementPlotting(ABCElementPlotting): + def __init__(self, unit: str, time_index, node_coord: Dict[str, List[float]] = None): + self.unit = unit + self.time_index = time_index self.coord = node_coord - self.size = map_element_size - # Create time_index - time = [time_start is None, time_end is None] - if time == [True, False] or time == [False, True]: - raise ValueError('You have to give both time_start and time_end') - elif time == [False, False]: - self.time_index = pd.date_range(start=time_start, end=time_end, periods=self.agg.horizon) - else: - self.time_index = np.arange(self.agg.horizon) - - # Create colors scale - self.cmap = cmap - self.cmap_plotly = HTMLPlotting.matplotlib_to_plotly(cmap, 255) + self.cmap = coolwarm + self.cmap_plotly = HTMLElementPlotting.matplotlib_to_plotly(self.cmap, 255) self.cmap_cons = ['brown', 'blue', 'darkgoldenrod', 'darkmagenta', 'darkorange', 'cadetblue', 'forestgreen', 'indigo', 'olive', 'darkred'] @@ -76,63 +47,136 @@ def matplotlib_to_plotly(cls, cmap, res: int): pl_colorscale.append([k * h, 'rgb' + str((C[0], C[1], C[2]))]) return pl_colorscale - def stack(self, node: str, scn: int = 0, prod_kind: str = 'used', cons_kind: str = 'asked'): - """ - Plot with production stacked with area and consumptions stacked by dashed lines. + def timeline(self, df: pd.DataFrame, title: str): + scenarios = df.index.get_level_values('scn').unique() + alpha = max(0.01, 1 / scenarios.size) + color = 'rgba(0, 0, 0, %.2f)' % alpha - :param node: select node to plot. - :param scn: scenario index to plot. - :param prod_kind: select which prod to stack : available ('avail') or 'used' - :param cons_kind: select which cons to stacl : 'asked' or 'given' - :return: plotly figure or jupyter widget to plot - """ fig = go.Figure() - c, p, b = self.agg.get_elements_inside(node=node) - stack = np.zeros(self.agg.horizon) - - # stack production with area - if p > 0: - prod = self.agg.agg_prod(self.agg.iscn[scn], self.agg.inode[node], self.agg.iname, self.agg.itime)\ - .sort_values('cost', ascending=True) - for i, name in enumerate(prod.index.get_level_values('name').unique()): - stack += prod.loc[name][prod_kind].sort_index().values - fig.add_trace(go.Scatter(x=self.time_index, y=stack.copy(), name=name, mode='none', - fill='tozeroy' if i == 0 else 'tonexty')) - - # add import in production stack - balance = self.agg.get_balance(node=node)[scn] - im = -np.clip(balance, None, 0) - if not (im == 0).all(): - stack += im - fig.add_trace(go.Scatter(x=self.time_index, y=stack.copy(), name='import', mode='none', fill='tonexty')) - - # Reset stack - stack = np.zeros_like(stack) - cons_lines = [] - # Stack consumptions with line - if c > 0: - cons = self.agg.agg_cons(self.agg.iscn[scn], self.agg.inode[node], self.agg.iname, self.agg.itime)\ - .sort_values('cost', ascending=False) - for i, name in enumerate(cons.index.get_level_values('name').unique()): - stack += cons.loc[name][cons_kind].sort_index().values - cons_lines.append([name, stack.copy()]) - - # Add export in consumption stack - exp = np.clip(balance, 0, None) - if not (exp == 0).all(): - stack += exp - cons_lines.append(['export', stack.copy()]) - - # Plot line in the reverse sens to avoid misunderstood during graphics analyze - for i, (name, stack) in enumerate(cons_lines[::-1]): - fig.add_trace(go.Scatter(x=self.time_index, y=stack.copy(), line_color=self.cmap_cons[i % 10], - name= name, line=dict(width=2))) - - fig.update_layout(title_text='Stack for node %s' % node, - yaxis_title="Quantity %s" % self.unit, xaxis_title="time") + for scn in scenarios: + fig.add_trace(go.Scatter(x=self.time_index, y=df.loc[scn], mode='lines', hoverinfo='name', + name='scn %0d' % scn, line=dict(color=color))) + + fig.update_layout(title_text=title, + yaxis_title="Quantity %s" % self.unit, xaxis_title="time", showlegend=False) + + return fig + + def monotone(self, y: np.ndarray, title: str): + y.sort() + y = y[::-1] + x = np.linspace(0, 100, y.size) + + fig = go.Figure() + fig.add_trace(go.Scatter(x=x, y=y, mode='markers')) + fig.update_layout(title_text=title, + yaxis_title="Quantity %s" % self.unit, xaxis_title="%", showlegend=False) + + return fig + + def gaussian(self, rac: np.ndarray, qt: np.ndarray, title: str): + # 1 / x - m \ 2 + # --------- * exp -0.5 * | -------- | + # o * √2*Pi \ o / + def _gaussian(x, m, o): + return np.exp(-0.5 * np.power((x - m) / o, 2)) / o / 1.772454 + + x = np.linspace(np.min(qt) * 0, np.max(qt) * 1.2, 100) + m = np.mean(qt) + o = np.std(qt) + + green = qt[rac >= 0] + red = qt[rac < 0] + + fig = go.Figure() + fig.add_trace(go.Scatter(x=x, y=_gaussian(x, m, o), mode='lines', hoverinfo='none', line=dict(color='grey'))) + fig.add_trace(go.Scatter(x=green, y=_gaussian(green, m, o), hovertemplate='%{x:.2f} ' + self.unit, + name='passed', mode='markers', marker=dict(color='green', size=10))) + fig.add_trace(go.Scatter(x=red, y=_gaussian(red, m, o), hovertemplate='%{x:.2f} ' + self.unit, + name='failed', mode='markers', marker=dict(color='red', size=10))) + fig.update_layout(title_text=title, yaxis=dict(visible=False), + yaxis_title='', xaxis_title="Quantity %s" % self.unit, showlegend=False) + + return fig + + def stack(self, areas: List[Tuple[str, np.ndarray]], lines: List[Tuple[str, np.ndarray]], title: str): + fig = go.Figure() + + # Stack areas + stack = np.zeros_like(self.time_index, dtype=float) + for i, (name, data) in enumerate(areas): + stack += data + fig.add_trace(go.Scatter(x=self.time_index, y=stack.copy(), name=name, mode='none', + fill='tozeroy' if i == 0 else 'tonexty')) + + # Stack lines. + # Bottom line have to be top frontward. So we firstly stack lines then plot in reverse set. + stack = np.zeros_like(self.time_index, dtype=float) + stacked_lines = [] + for i, (name, data) in enumerate(lines): + stack += data + stacked_lines.append((name, stack.copy())) + + for i, (name, data) in enumerate(stacked_lines[::-1]): + fig.add_trace(go.Scatter(x=self.time_index, y=data, line_color=self.cmap_cons[i % 10], + name=name, line=dict(width=2))) + + fig.update_layout(title_text=title, yaxis_title="Quantity %s" % self.unit, xaxis_title="time") + return fig + + def matrix(self, data: np.ndarray, title): + def sdt(x): + x[x > 0] /= np.max(x[x > 0]) + x[x < 0] /= -np.min(x[x < 0]) + return x + + fig = go.Figure(data=go.Heatmap( + z=sdt(data.copy()), + x=self.time_index, + y=np.arange(data.shape[0]), + hoverinfo='text', + text=data, + colorscale='RdBu', zmid=0, + showscale=False)) + + fig.update_layout(title_text=title, yaxis_title="scenarios", xaxis_title="time", showlegend=False) + return fig - def _plot_links(self, fig: go.Figure, start: str, end: str, color: str, qt: float): + def map_exchange(self, nodes, lines, limit, title, size): + if self.coord is None: + raise ValueError('Please provide node coordinate by setting param node_coord in Plotting constructor') + + fig = go.Figure() + # Add node circle + keys = nodes.keys() + node_qt = [nodes[k] for k in keys] + node_coords = np.array([self.coord[n] for n in keys]) + center = np.mean(node_coords, axis=0) + + # Plot arrows + for (src, dest), qt in lines.items(): + color = 'rgb' + str(self.cmap(abs(qt) / 2 / limit + 0.5)[:-1]) + self._plot_links(fig, src, dest, color, qt, size) + + # Plot nodes + fig.add_trace(go.Scattermapbox( + mode="markers", + lon=node_coords[:, 0], + lat=node_coords[:, 1], + hoverinfo='text', text=node_qt, + marker=dict(size=20, colorscale=self.cmap_plotly, cmin=-limit, color=node_qt, + cmax=limit, colorbar_title="Net Position %s" % self.unit))) + + fig.update_layout(showlegend=False, + title_text=title, + mapbox=dict( + style="carto-positron", + center={'lon': center[0], 'lat': center[1]}, + zoom=1 / size / 0.07)) + return fig + + def _plot_links(self, fig: go.Figure, start: str, end: str, color: str, qt: float, size: float): """ Plot line with arrow to a figure. @@ -147,68 +191,45 @@ def _plot_links(self, fig: go.Figure, start: str, end: str, color: str, qt: floa E = np.array([self.coord[end][0], self.coord[end][1]]) # plot line - fig.add_trace(go.Scattergeo(lat=[S[1], E[1]], hoverinfo='skip', - lon=[S[0], E[0]], mode='lines', - line=dict(width=4 * self.size, color=color))) + fig.add_trace(go.Scattermapbox(lat=[S[1], E[1]], hoverinfo='skip', + lon=[S[0], E[0]], mode='lines', + line=dict(width=2 * size, color=color))) # vector flow direction v = E - S n = np.linalg.norm(v) # Get orthogonal vector w = np.array([v[1], -v[0]]) # Compute triangle points - A = E - v * 0.5 - B = A - v / n * self.size * 0.5 - w / n * self.size * 0.25 - C = A - v / n * self.size * 0.5 + w / n * self.size * 0.25 + A = E - v * 0.1 + B = A - v / 10 - w / 10 + C = A - v / 10 + w / 10 # plot arrow - fig.add_trace(go.Scattergeo(lat=[B[1], A[1], C[1]], hoverinfo='text', - lon=[B[0], A[0], C[0]], text=str(qt), mode='lines', - line=dict(width=4 * self.size, color=color))) + fig.add_trace(go.Scattermapbox(lat=[B[1], A[1], C[1], B[1], None], hoverinfo='text', fill='toself', + lon=[B[0], A[0], C[0], B[0], None], text=str(qt), mode='lines', + line=dict(width=2 * size, color=color))) - def exchanges_map(self, t: int, scn: int = 0, limit: int = None): - """ - Plot a map with node (color are balance) and arrow between nodes (color for quantity). - :param t: timestep to plot - :param scn: scenario index to plot - :param limit: limite to use as min/max for color scale. If not provided we use min/max from dataset. - :return: plotly figure or jupyter widget to plot +class HTMLPlotting(Plotting): + """ + Plotting implementation interactive html graphics. (Use plotly) + """ + + def __init__(self, agg: ResultAnalyzer, unit_symbol: str = '', + time_start=None, time_end=None, + node_coord: Dict[str, List[float]] = None): """ - if self.coord is None: - raise ValueError('Please provide node coordinate by setting param node_coord in Plotting constructor') + Create instance. - balances = [self.agg.get_balance(node=node)[scn, t] for node in self.agg.nodes] - if limit is None: - limit = max(max(balances), -min(balances)) + :param agg: ResultAggragator instence to use + :param unit_symbol: symbol on quantity unit used. ex. MW, litter, Go, ... + :param time_start: time to use as the start of study horizon + :param time_end: time to use as the end of study horizon + :param cmap: matplotlib color map to use (coolwarm as default) + :param node_coord: nodes coordinates to use for map plotting + :param map_element_size: size on element draw on map. default as 1. + """ + Plotting.__init__(self, agg, unit_symbol, time_start, time_end, node_coord) + self.plotting = HTMLElementPlotting(self.unit, self.time_index, self.coord) - fig = go.Figure() - # plot links - links = self.agg.agg_link(self.agg.iscn[scn], self.agg.isrc, self.agg.idest, self.agg.itime) - for src in links.index.get_level_values('src').unique(): - for dest in links.loc[src].index.get_level_values('dest').unique(): - exchange = links.loc[src, dest, t]['used'] # forward - exchange -= links.loc[dest, src, t]['used'] if (dest, src, t) in links.index else 0 # backward - - color = 'rgb' + str(self.cmap(abs(exchange) / 2 / limit + 0.5)[:-1]) - if exchange > 0: - self._plot_links(fig=fig, start=src, end=dest, color=color, qt=exchange) - else: - self._plot_links(fig=fig, start=dest, end=src, color=color, qt=-exchange) - - # plot nodes - text = ['%s: %i' % (n, b) for n, b in zip(self.agg.nodes, balances)] - lon = [self.coord[node][0] for node in self.agg.nodes] - lat = [self.coord[node][1] for node in self.agg.nodes] - - fig.add_trace(go.Scattergeo(lon=lon, lat=lat, hoverinfo='text', text=text, mode='markers', - marker=dict(size=15 * self.size, - colorscale=self.cmap_plotly, cmin=-limit, color=balances, - cmax=limit, colorbar_title="Net Position %s" % self.unit))) - # Config plot - fig.update_layout(title_text='Exchanges Map', showlegend=False, height=600, - geo=dict(projection_type='equirectangular', showland=True, showcountries=True, - resolution=50, landcolor='rgb(200, 200, 200)', countrycolor='rgb(0, 0, 0)', - fitbounds='locations')) - - return fig \ No newline at end of file diff --git a/hadar/workflow/pipeline.py b/hadar/workflow/pipeline.py index a5c4dc5..f6ad8c6 100644 --- a/hadar/workflow/pipeline.py +++ b/hadar/workflow/pipeline.py @@ -4,7 +4,7 @@ # If a copy of the Apache License, version 2.0 was not distributed with this file, you can obtain one at http://www.apache.org/licenses/LICENSE-2.0. # SPDX-License-Identifier: Apache-2.0 # This file is part of hadar-simulator, a python adequacy library for everyone. - +import os from abc import ABC, abstractmethod from copy import deepcopy from typing import List, Tuple, Union, Dict @@ -16,7 +16,7 @@ from hadar.optimizer.input import DTO __all__ = ['RestrictedPlug', 'FreePlug', 'Stage', 'FocusStage', 'Drop', 'Rename', 'Fault', 'RepeatScenario', - 'ToShuffler', 'Pipeline'] + 'ToShuffler', 'Pipeline', 'Clip'] TO_SHUFFLER = 'to_shuffler' @@ -260,6 +260,10 @@ def compute(self, timeline: pd.DataFrame) -> pd.DataFrame: """ timeline = Stage.standardize_column(timeline) + # If compute run inside multiprocessing like in Shuffler. randomness are not independence. + # We need to reseed with urandom + np.random.seed(int.from_bytes(os.urandom(4), byteorder='little')) + names = Stage.get_names(timeline) if not self.plug.computable(names): raise ValueError("Stage accept %s in input, but receive %s" % (self.plug.inputs, names)) @@ -359,7 +363,7 @@ def _process_timeline(self, timeline: pd.DataFrame) -> pd.DataFrame: output = pd.DataFrame(data=np.zeros((n_time, n_type * n_scn)), columns=index) for scn in timeline.columns.get_level_values(0).unique(): - output[scn] = self._process_scenarios(scn, timeline[scn]) + output[scn] = self._process_scenarios(scn, timeline[scn].copy()) return output @@ -463,14 +467,14 @@ def __init__(self, loss: float, occur_freq: float, downtime_min: int, downtime_m self.occur_freq = occur_freq self.downtime_min = downtime_min self.downtime_max = downtime_max - self.seed = np.random.randint(0, 100000000) if seed is None else seed + self.seed = seed def _process_scenarios(self, n_scn: int, scenario: pd.DataFrame) -> pd.DataFrame: - np.random.seed(self.seed) + if self.seed: + np.random.seed(self.seed) horizon = scenario.shape[0] nb_faults = np.random.choice([0, 1], size=horizon, p=[1 - self.occur_freq, self.occur_freq]).sum() - loss_qt = np.zeros(horizon) faults_begin = np.random.randint(low=0, high=horizon, size=nb_faults) faults_duration = np.random.randint(low=self.downtime_min, high=self.downtime_max, size=nb_faults) diff --git a/hadar/workflow/shuffler.py b/hadar/workflow/shuffler.py index 9f61fcb..20c1d3f 100644 --- a/hadar/workflow/shuffler.py +++ b/hadar/workflow/shuffler.py @@ -11,7 +11,7 @@ import pandas as pd from numpy.random.mtrand import randint -from hadar.workflow.pipeline import Pipeline, TO_SHUFFLER +from hadar.workflow.pipeline import Pipeline, TO_SHUFFLER, Stage __all__ = ['Shuffler', 'Timeline'] @@ -127,6 +127,7 @@ def add_pipeline(self, name: str, data: pd.DataFrame, pipeline: Pipeline): :param pipeline: pipeline to generate data :return: self """ + data = Stage.standardize_column(data) pipeline.assert_computable(data) pipeline.assert_to_shuffler() diff --git a/requirements.txt b/requirements.txt index 10aa33e..1181394 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,5 @@ pandas numpy ortools plotly -jupyter matplotlib requests \ No newline at end of file diff --git a/tests/analyzer/test_result.py b/tests/analyzer/test_result.py index 3433d25..ef774fd 100644 --- a/tests/analyzer/test_result.py +++ b/tests/analyzer/test_result.py @@ -7,11 +7,10 @@ import unittest -import pandas as pd import numpy as np +import pandas as pd -from hadar.analyzer.result import Index, TimeIndex, ResultAnalyzer, NodeIndex, NameIndex, SrcIndex, DestIndex, \ - IntIndex +from hadar.analyzer.result import Index, ResultAnalyzer, IntIndex from hadar.optimizer.input import Production, Consumption, Study from hadar.optimizer.output import OutputConsumption, OutputLink, OutputNode, OutputProduction, Result @@ -183,3 +182,7 @@ def test_cost(self): agg = ResultAnalyzer(study=self.study, result=self.result) np.testing.assert_array_equal([[200360, 20036, 20036], [20036, 200360, 200360]], agg.get_cost(node='a')) np.testing.assert_array_equal([[100600, 10060, 10060], [10060, 100600, 100600]], agg.get_cost(node='b')) + + def test_rac(self): + agg = ResultAnalyzer(study=self.study, result=self.result) + np.testing.assert_array_equal([[0, 0, 0], [0, 0, 0]], agg.get_rac()) diff --git a/tests/optimizer/test_input.py b/tests/optimizer/test_input.py index 49117db..7400866 100644 --- a/tests/optimizer/test_input.py +++ b/tests/optimizer/test_input.py @@ -6,7 +6,9 @@ # This file is part of hadar-simulator, a python adequacy library for everyone. import unittest + import numpy as np + from hadar.optimizer.input import Study, Consumption, Production, Link diff --git a/tests/viewer/test_html.py b/tests/viewer/test_html.py index 7029b4c..94844fd 100644 --- a/tests/viewer/test_html.py +++ b/tests/viewer/test_html.py @@ -4,7 +4,6 @@ # If a copy of the Apache License, version 2.0 was not distributed with this file, you can obtain one at http://www.apache.org/licenses/LICENSE-2.0. # SPDX-License-Identifier: Apache-2.0 # This file is part of hadar-simulator, a python adequacy library for everyone. - import hashlib import unittest @@ -19,15 +18,15 @@ class TestHTMLPlotting(unittest.TestCase): def setUp(self) -> None: - self.study = Study(['a', 'b'], horizon=3) \ - .add_on_node('a', data=Consumption(cost=10 ** 6, quantity=[20, 10, 2], name='load')) \ - .add_on_node('a', data=Consumption(cost=10 ** 6, quantity=[30, 15, 3], name='car')) \ - .add_on_node('a', data=Production(cost=10, quantity=[60, 30, 5], name='prod')) \ + self.study = Study(['a', 'b'], horizon=3, nb_scn=2) \ + .add_on_node('a', data=Consumption(cost=10 ** 6, quantity=[[20, 10, 2], [10, 5, 3]], name='load')) \ + .add_on_node('a', data=Consumption(cost=10 ** 6, quantity=[[30, 15, 3], [15, 7, 2]], name='car')) \ + .add_on_node('a', data=Production(cost=10, quantity=[[60, 30, 5], [30, 15, 3]], name='prod')) \ \ - .add_on_node('b', data=Consumption(cost=10 ** 6, quantity=[40, 20, 2], name='load')) \ - .add_on_node('b', data=Production(cost=20, quantity=[10, 5, 1], name='prod')) \ - .add_on_node('b', data=Production(cost=20, quantity=[20, 10, 2], name='nuclear')) \ - .add_link(src='a', dest='b', quantity=[10, 10, 10], cost=2) + .add_on_node('b', data=Consumption(cost=10 ** 6, quantity=[[40, 20, 2], [20, 10, 1]], name='load')) \ + .add_on_node('b', data=Production(cost=20, quantity=[[10, 5, 1], [5, 3, 1]], name='prod')) \ + .add_on_node('b', data=Production(cost=30, quantity=[[20, 10, 2], [10, 5, 1]], name='nuclear')) \ + .add_link(src='a', dest='b', quantity=[[10, 10, 10], [5, 5, 5]], cost=2) optimizer = LPOptimizer() self.result = optimizer.solve(study=self.study) @@ -39,17 +38,53 @@ def setUp(self) -> None: self.hash = hashlib.sha3_256() def test_stack(self): - fig = self.plot.stack(node='a', scn=0) + fig = self.plot.node('a').stack(scn=0) self.assert_fig_hash('d9f9f004b98ca62be934d69d4fd0c1a302512242', fig) def test_map_exchanges(self): - fig = self.plot.exchanges_map(t=0, scn=0) - self.assert_fig_hash('9aa34f28665ea9e6766b271ffbc677d3cda6810b', fig) + fig = self.plot.network().map(t=0, scn=0, zoom=1.6) + # Used this line to plot map: plot(fig) + self.assert_fig_hash('49d81d1457b2ac78e1fc6ae4c1fc6215b8a0bbe4', fig) + + def test_plot_timeline(self): + fig = self.plot.consumption(node='a', name='load').timeline() + self.assert_fig_hash('ba776202b252c9df5c81ca869b2e2d85e56e5589', fig) + + fig = self.plot.production(node='b', name='nuclear').timeline() + self.assert_fig_hash('33baf5d01fda12b6a2d025abf8421905fc24abe1', fig) + + fig = self.plot.link(src='a', dest='b').timeline() + self.assert_fig_hash('0c87d1283db5250858b14e2240d30f9059459e65', fig) + + def test_plot_monotone(self): + fig = self.plot.consumption(node='a', name='load').monotone(scn=0) + self.assert_fig_hash('1ffa51a52b066aab8cabb817c11fd1272549eb9d', fig) + + fig = self.plot.production(node='b', name='nuclear').monotone(t=0) + self.assert_fig_hash('e059878aac45330810578482df8c3d19261f7f75', fig) + + fig = self.plot.link(src='a', dest='b').monotone(scn=0) + self.assert_fig_hash('1d5dba9e2189c741e5daa36d69ff1a879f169964', fig) + + def test_rac_heatmap(self): + fig = self.plot.network().rac_matrix() + self.assert_fig_hash('2b87a4e781e9eeb532f5d2b091c474bb0de625fd', fig) + + def test_gaussian(self): + fig = self.plot.consumption(node='a', name='load').gaussian(scn=0) + self.assert_fig_hash('4f3676a65cde6c268233679e1d0e6207df62764d', fig) + + fig = self.plot.production(node='b', name='nuclear').gaussian(t=0) + # Fail devops self.assert_fig_hash('45ffe15df1d72829ebe2283c9c4b65ee8465c978', fig) + + fig = self.plot.link(src='a', dest='b').gaussian(scn=0) + self.assert_fig_hash('52620565ce8ea670b18707cccf30594b5c3d58ea', fig) def assert_fig_hash(self, expected: str, fig: go.Figure): - h = hashlib.sha1() - h.update(TestHTMLPlotting.get_html(fig)) - self.assertEqual(expected, h.hexdigest()) + actual = hashlib.sha1(TestHTMLPlotting.get_html(fig)).hexdigest() + if expected != actual: + fig.show() + self.assertEqual(expected, actual) @staticmethod def get_html(fig: go.Figure) -> bytes: diff --git a/tests/workflow/test_integration.py b/tests/workflow/test_integration.py index f01a902..2f54750 100644 --- a/tests/workflow/test_integration.py +++ b/tests/workflow/test_integration.py @@ -6,9 +6,9 @@ # This file is part of hadar-simulator, a python adequacy library for everyone. import unittest -import pandas as pd + import numpy as np -from pandas import MultiIndex +import pandas as pd from hadar.workflow.pipeline import Rename, RepeatScenario, Fault, Clip, ToShuffler from hadar.workflow.shuffler import Shuffler diff --git a/tests/workflow/test_pipeline.py b/tests/workflow/test_pipeline.py index 337f629..9046156 100644 --- a/tests/workflow/test_pipeline.py +++ b/tests/workflow/test_pipeline.py @@ -6,8 +6,9 @@ # This file is part of hadar-simulator, a python adequacy library for everyone. import unittest -import pandas as pd + import numpy as np +import pandas as pd from pandas import MultiIndex from hadar.workflow.pipeline import Stage, FreePlug, RestrictedPlug, FocusStage, Clip, Rename, Drop, Fault, \ @@ -35,8 +36,8 @@ def __init__(self): Stage.__init__(self, RestrictedPlug(inputs=['a', 'b'], outputs=['d', 'r'])) def _process_scenarios(self, n_scn: int, scenario: pd.DataFrame) -> pd.DataFrame: - scenario['d'] = (scenario['a'] / scenario['b']).apply(np.floor) - scenario['r'] = scenario['a'] - scenario['b'] * scenario['d'] + scenario.loc[:, 'd'] = (scenario['a'] / scenario['b']).apply(np.floor) + scenario.loc[:, 'r'] = scenario['a'] - scenario['b'] * scenario['d'] return scenario.drop(['a', 'b'], axis=1) @@ -45,7 +46,7 @@ def __init__(self): FocusStage.__init__(self, RestrictedPlug(inputs=['d'], outputs=['d', '-d'])) def _process_scenarios(self, n_scn: int, scenario: pd.DataFrame) -> pd.DataFrame: - scenario['-d'] = -scenario['d'] + scenario.loc[:, '-d'] = -scenario['d'] return scenario.copy() diff --git a/tests/workflow/test_shuffler.py b/tests/workflow/test_shuffler.py index c7b3793..0192881 100644 --- a/tests/workflow/test_shuffler.py +++ b/tests/workflow/test_shuffler.py @@ -10,8 +10,8 @@ import numpy as np import pandas as pd -from hadar.workflow.pipeline import ToShuffler from hadar.workflow.pipeline import Pipeline, TO_SHUFFLER +from hadar.workflow.pipeline import ToShuffler from hadar.workflow.shuffler import Timeline, TimelinePipeline, Shuffler