Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

bicm

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bicm - npm Package Compare versions

Comparing version
3.0.6
to
3.1
+89
-91
bicm.egg-info/PKG-INFO
Metadata-Version: 2.1
Name: bicm
Version: 3.0.6
Version: 3.1
Summary: Package for bipartite configuration model

@@ -9,2 +9,90 @@ Home-page: https://github.com/mat701/BiCM

License: UNKNOWN
Description: ## BiCM package
This is a Python package for the computation of the maximum entropy bipartite configuration model (BiCM) and the projection of bipartite networks on one layer. It was developed with Python 3.5.
You can install this package via pip:
pip install bicm
Documentation is available at https://bipartite-configuration-model.readthedocs.io/en/latest/ .
This package is also a module of NEMtropy that you can find at https://github.com/nicoloval/NEMtropy .
For more solvers of maximum entropy configuration models visit https://meh.imtlucca.it/ .
NOTE of the developer: there was an error in the projection threshold, validating less links than it should have.
Please re-run your analysis after updating to the last version (>=3.1)
## Basic functionalities
To install:
pip install bicm
To import the module:
import bicm
To generate a Graph object and initialize it (with a biadjacency matrix, edgelist or degree sequences):
from bicm import BipartiteGraph
myGraph = BipartiteGraph()
myGraph.set_biadjacency_matrix(my_biadjacency_matrix)
myGraph.set_adjacency_list(my_adjacency_list)
myGraph.set_edgelist(my_edgelist)
myGraph.set_degree_sequences((first_degree_sequence, second_degree_sequence))
Or alternatively, with the respective data structure as input:
from bicm import BipartiteGraph
myGraph = BipartiteGraph(biadjacency=my_biadjacency_matrix, adjacency_list=my_adjacency_list, edgelist=my_edgelist, degree_sequences=((first_degree_sequence, second_degree_sequence)))
To compute the BiCM probability matrix of the graph or the relative fitnesses coefficients as dictionaries containing the nodes names as keys:
my_probability_matrix = myGraph.get_bicm_matrix()
my_x, my_y = myGraph.get_bicm_fitnesses()
This will solve the bicm using recommended settings for the solver.
To customize the solver you can alternatively use (in advance) the following method:
myGraph.solve_tool(light_mode=False, method='newton', initial_guess=None, tolerance=1e-8, max_steps=None, verbose=False, linsearch=True, regularise=False, print_error=True, exp=False)
To get the rows or columns projection of the graph:
myGraph.get_rows_projection()
myGraph.get_cols_projection()
Alternatively, to customize the projection:
myGraph.compute_projection(rows=True, alpha=0.05, method='poisson', threads_num=4, progress_bar=True)
Now version 3 is online, and you can use the package with weighted networks as well using the BiWCM models!
See a more detailed walkthrough in **tests/bicm_test** or **tests/biwcm_test** notebooks, or check out the API in the documentation.
## How to cite
If you use the `bicm` module, please cite its location on Github
[https://github.com/mat701/BiCM](https://github.com/mat701/BiCM) and the
original articles [Vallarano2021], [Saracco2015] and [Saracco2017].
If you use the weighted models BiWCM_c or BiMCM you might consider citing also the paper introducing the solvers of this package [Bruno2023].
### References
[Vallarano2021] [N. Vallarano, M. Bruno, E. Marchese, G. Trapani, F. Saracco, T. Squartini, G. Cimini, M. Zanon, Fast and scalable likelihood maximization for Exponential Random Graph Models with local constraints, Nature Scientific Reports](https://doi.org/10.1038/s41598-021-93830-4)
[Bruno2023] [M. Bruno, D. Mazzilli, A. Patelli, T. Squartini, F. Saracco, Inferring comparative advantage via entropy maximization. Journal of Physics: Complexity, Volume 4, Number 4 (2023)](https://doi.org/10.1088/2632-072X/ad1411)
[Saracco2015] [F. Saracco, R. Di Clemente, A. Gabrielli, T. Squartini, Randomizing bipartite networks: the case of the World Trade Web, Scientific Reports 5, 10595 (2015)](http://www.nature.com/articles/srep10595).
[Saracco2017] [F. Saracco, M. J. Straka, R. Di Clemente, A. Gabrielli, G. Caldarelli, and T. Squartini, Inferring monopartite projections of bipartite networks: an entropy-based approach, New J. Phys. 19, 053022 (2017)](http://stacks.iop.org/1367-2630/19/i=5/a=053022)
_Author_:
[Matteo Bruno](https://csl.sony.it/member/matteo-bruno/) (BiCM) (a.k.a. [mat701](https://github.com/mat701))
Platform: UNKNOWN

@@ -20,91 +108,1 @@ Classifier: Programming Language :: Python :: 3

Description-Content-Type: text/markdown
License-File: LICENSE.txt
## BiCM package
This is a Python package for the computation of the maximum entropy bipartite configuration model (BiCM) and the projection of bipartite networks on one layer. It was developed with Python 3.5.
You can install this package via pip:
pip install bicm
Documentation is available at https://bipartite-configuration-model.readthedocs.io/en/latest/ .
This package is also a module of NEMtropy that you can find at https://github.com/nicoloval/NEMtropy .
For more solvers of maximum entropy configuration models visit https://meh.imtlucca.it/ .
## Basic functionalities
To install:
pip install bicm
To import the module:
import bicm
To generate a Graph object and initialize it (with a biadjacency matrix, edgelist or degree sequences):
from bicm import BipartiteGraph
myGraph = BipartiteGraph()
myGraph.set_biadjacency_matrix(my_biadjacency_matrix)
myGraph.set_adjacency_list(my_adjacency_list)
myGraph.set_edgelist(my_edgelist)
myGraph.set_degree_sequences((first_degree_sequence, second_degree_sequence))
Or alternatively, with the respective data structure as input:
from bicm import BipartiteGraph
myGraph = BipartiteGraph(biadjacency=my_biadjacency_matrix, adjacency_list=my_adjacency_list, edgelist=my_edgelist, degree_sequences=((first_degree_sequence, second_degree_sequence)))
To compute the BiCM probability matrix of the graph or the relative fitnesses coefficients as dictionaries containing the nodes names as keys:
my_probability_matrix = myGraph.get_bicm_matrix()
my_x, my_y = myGraph.get_bicm_fitnesses()
This will solve the bicm using recommended settings for the solver.
To customize the solver you can alternatively use (in advance) the following method:
myGraph.solve_tool(light_mode=False, method='newton', initial_guess=None, tolerance=1e-8, max_steps=None, verbose=False, linsearch=True, regularise=False, print_error=True, exp=False)
To get the rows or columns projection of the graph:
myGraph.get_rows_projection()
myGraph.get_cols_projection()
Alternatively, to customize the projection:
myGraph.compute_projection(rows=True, alpha=0.05, method='poisson', threads_num=4, progress_bar=True)
Now version 3.0.0 is online, and you can use the package with weighted networks as well using the BiWCM models!
See a more detailed walkthrough in **tests/bicm_test** or **tests/biwcm_test** notebooks, or check out the API in the documentation.
## How to cite
If you use the `bicm` module, please cite its location on Github
[https://github.com/mat701/BiCM](https://github.com/mat701/BiCM) and the
original articles [Vallarano2021], [Saracco2015] and [Saracco2017].
If you use the weighted models BiWCM_c or BiMCM you might consider citing also the following paper introducing the solvers of this package:
* Bruno, M., Mazzilli, D., Patelli, A., Squartini, T., and Saracco, F. \
*Inferring comparative advantage via entropy maximization.* \
In preparation
### References
[Vallarano2021] [N. Vallarano, M. Bruno, E. Marchese, G. Trapani, F. Saracco, T. Squartini, G. Cimini, M. Zanon, Fast and scalable likelihood maximization for Exponential Random Graph Models with local constraints, Nature Scientific Reports](https://doi.org/10.1038/s41598-021-93830-4)
[Saracco2015] [F. Saracco, R. Di Clemente, A. Gabrielli, T. Squartini, Randomizing bipartite networks: the case of the World Trade Web, Scientific Reports 5, 10595 (2015)](http://www.nature.com/articles/srep10595).
[Saracco2017] [F. Saracco, M. J. Straka, R. Di Clemente, A. Gabrielli, G. Caldarelli, and T. Squartini, Inferring monopartite projections of bipartite networks: an entropy-based approach, New J. Phys. 19, 053022 (2017)](http://stacks.iop.org/1367-2630/19/i=5/a=053022)
_Author_:
[Matteo Bruno](https://csl.sony.it/member/matteo-bruno/) (BiCM) (a.k.a. [mat701](https://github.com/mat701))

@@ -1,2 +0,1 @@

LICENSE.txt
README.md

@@ -16,6 +15,2 @@ setup.py

tests/BiCM_test.py
tests/__init__.py
tests/biwcm_c.py
tests/biwcm_d.py
tests/biwcm_main.py
tests/delta_converter.py
tests/__init__.py

@@ -19,3 +19,3 @@ """

__version__ = "3.0.6"
__version__ = "3.1"
__author__ = """Matteo Bruno (matteobruno180@gmail.com)"""
+89
-91
Metadata-Version: 2.1
Name: bicm
Version: 3.0.6
Version: 3.1
Summary: Package for bipartite configuration model

@@ -9,2 +9,90 @@ Home-page: https://github.com/mat701/BiCM

License: UNKNOWN
Description: ## BiCM package
This is a Python package for the computation of the maximum entropy bipartite configuration model (BiCM) and the projection of bipartite networks on one layer. It was developed with Python 3.5.
You can install this package via pip:
pip install bicm
Documentation is available at https://bipartite-configuration-model.readthedocs.io/en/latest/ .
This package is also a module of NEMtropy that you can find at https://github.com/nicoloval/NEMtropy .
For more solvers of maximum entropy configuration models visit https://meh.imtlucca.it/ .
NOTE of the developer: there was an error in the projection threshold, validating less links than it should have.
Please re-run your analysis after updating to the last version (>=3.1)
## Basic functionalities
To install:
pip install bicm
To import the module:
import bicm
To generate a Graph object and initialize it (with a biadjacency matrix, edgelist or degree sequences):
from bicm import BipartiteGraph
myGraph = BipartiteGraph()
myGraph.set_biadjacency_matrix(my_biadjacency_matrix)
myGraph.set_adjacency_list(my_adjacency_list)
myGraph.set_edgelist(my_edgelist)
myGraph.set_degree_sequences((first_degree_sequence, second_degree_sequence))
Or alternatively, with the respective data structure as input:
from bicm import BipartiteGraph
myGraph = BipartiteGraph(biadjacency=my_biadjacency_matrix, adjacency_list=my_adjacency_list, edgelist=my_edgelist, degree_sequences=((first_degree_sequence, second_degree_sequence)))
To compute the BiCM probability matrix of the graph or the relative fitnesses coefficients as dictionaries containing the nodes names as keys:
my_probability_matrix = myGraph.get_bicm_matrix()
my_x, my_y = myGraph.get_bicm_fitnesses()
This will solve the bicm using recommended settings for the solver.
To customize the solver you can alternatively use (in advance) the following method:
myGraph.solve_tool(light_mode=False, method='newton', initial_guess=None, tolerance=1e-8, max_steps=None, verbose=False, linsearch=True, regularise=False, print_error=True, exp=False)
To get the rows or columns projection of the graph:
myGraph.get_rows_projection()
myGraph.get_cols_projection()
Alternatively, to customize the projection:
myGraph.compute_projection(rows=True, alpha=0.05, method='poisson', threads_num=4, progress_bar=True)
Now version 3 is online, and you can use the package with weighted networks as well using the BiWCM models!
See a more detailed walkthrough in **tests/bicm_test** or **tests/biwcm_test** notebooks, or check out the API in the documentation.
## How to cite
If you use the `bicm` module, please cite its location on Github
[https://github.com/mat701/BiCM](https://github.com/mat701/BiCM) and the
original articles [Vallarano2021], [Saracco2015] and [Saracco2017].
If you use the weighted models BiWCM_c or BiMCM you might consider citing also the paper introducing the solvers of this package [Bruno2023].
### References
[Vallarano2021] [N. Vallarano, M. Bruno, E. Marchese, G. Trapani, F. Saracco, T. Squartini, G. Cimini, M. Zanon, Fast and scalable likelihood maximization for Exponential Random Graph Models with local constraints, Nature Scientific Reports](https://doi.org/10.1038/s41598-021-93830-4)
[Bruno2023] [M. Bruno, D. Mazzilli, A. Patelli, T. Squartini, F. Saracco, Inferring comparative advantage via entropy maximization. Journal of Physics: Complexity, Volume 4, Number 4 (2023)](https://doi.org/10.1088/2632-072X/ad1411)
[Saracco2015] [F. Saracco, R. Di Clemente, A. Gabrielli, T. Squartini, Randomizing bipartite networks: the case of the World Trade Web, Scientific Reports 5, 10595 (2015)](http://www.nature.com/articles/srep10595).
[Saracco2017] [F. Saracco, M. J. Straka, R. Di Clemente, A. Gabrielli, G. Caldarelli, and T. Squartini, Inferring monopartite projections of bipartite networks: an entropy-based approach, New J. Phys. 19, 053022 (2017)](http://stacks.iop.org/1367-2630/19/i=5/a=053022)
_Author_:
[Matteo Bruno](https://csl.sony.it/member/matteo-bruno/) (BiCM) (a.k.a. [mat701](https://github.com/mat701))
Platform: UNKNOWN

@@ -20,91 +108,1 @@ Classifier: Programming Language :: Python :: 3

Description-Content-Type: text/markdown
License-File: LICENSE.txt
## BiCM package
This is a Python package for the computation of the maximum entropy bipartite configuration model (BiCM) and the projection of bipartite networks on one layer. It was developed with Python 3.5.
You can install this package via pip:
pip install bicm
Documentation is available at https://bipartite-configuration-model.readthedocs.io/en/latest/ .
This package is also a module of NEMtropy that you can find at https://github.com/nicoloval/NEMtropy .
For more solvers of maximum entropy configuration models visit https://meh.imtlucca.it/ .
## Basic functionalities
To install:
pip install bicm
To import the module:
import bicm
To generate a Graph object and initialize it (with a biadjacency matrix, edgelist or degree sequences):
from bicm import BipartiteGraph
myGraph = BipartiteGraph()
myGraph.set_biadjacency_matrix(my_biadjacency_matrix)
myGraph.set_adjacency_list(my_adjacency_list)
myGraph.set_edgelist(my_edgelist)
myGraph.set_degree_sequences((first_degree_sequence, second_degree_sequence))
Or alternatively, with the respective data structure as input:
from bicm import BipartiteGraph
myGraph = BipartiteGraph(biadjacency=my_biadjacency_matrix, adjacency_list=my_adjacency_list, edgelist=my_edgelist, degree_sequences=((first_degree_sequence, second_degree_sequence)))
To compute the BiCM probability matrix of the graph or the relative fitnesses coefficients as dictionaries containing the nodes names as keys:
my_probability_matrix = myGraph.get_bicm_matrix()
my_x, my_y = myGraph.get_bicm_fitnesses()
This will solve the bicm using recommended settings for the solver.
To customize the solver you can alternatively use (in advance) the following method:
myGraph.solve_tool(light_mode=False, method='newton', initial_guess=None, tolerance=1e-8, max_steps=None, verbose=False, linsearch=True, regularise=False, print_error=True, exp=False)
To get the rows or columns projection of the graph:
myGraph.get_rows_projection()
myGraph.get_cols_projection()
Alternatively, to customize the projection:
myGraph.compute_projection(rows=True, alpha=0.05, method='poisson', threads_num=4, progress_bar=True)
Now version 3.0.0 is online, and you can use the package with weighted networks as well using the BiWCM models!
See a more detailed walkthrough in **tests/bicm_test** or **tests/biwcm_test** notebooks, or check out the API in the documentation.
## How to cite
If you use the `bicm` module, please cite its location on Github
[https://github.com/mat701/BiCM](https://github.com/mat701/BiCM) and the
original articles [Vallarano2021], [Saracco2015] and [Saracco2017].
If you use the weighted models BiWCM_c or BiMCM you might consider citing also the following paper introducing the solvers of this package:
* Bruno, M., Mazzilli, D., Patelli, A., Squartini, T., and Saracco, F. \
*Inferring comparative advantage via entropy maximization.* \
In preparation
### References
[Vallarano2021] [N. Vallarano, M. Bruno, E. Marchese, G. Trapani, F. Saracco, T. Squartini, G. Cimini, M. Zanon, Fast and scalable likelihood maximization for Exponential Random Graph Models with local constraints, Nature Scientific Reports](https://doi.org/10.1038/s41598-021-93830-4)
[Saracco2015] [F. Saracco, R. Di Clemente, A. Gabrielli, T. Squartini, Randomizing bipartite networks: the case of the World Trade Web, Scientific Reports 5, 10595 (2015)](http://www.nature.com/articles/srep10595).
[Saracco2017] [F. Saracco, M. J. Straka, R. Di Clemente, A. Gabrielli, G. Caldarelli, and T. Squartini, Inferring monopartite projections of bipartite networks: an entropy-based approach, New J. Phys. 19, 053022 (2017)](http://stacks.iop.org/1367-2630/19/i=5/a=053022)
_Author_:
[Matteo Bruno](https://csl.sony.it/member/matteo-bruno/) (BiCM) (a.k.a. [mat701](https://github.com/mat701))

@@ -15,3 +15,6 @@ ## BiCM package

NOTE of the developer: there was an error in the projection threshold, validating less links than it should have.
Please re-run your analysis after updating to the last version (>=3.1)
## Basic functionalities

@@ -60,3 +63,3 @@

Now version 3.0.0 is online, and you can use the package with weighted networks as well using the BiWCM models!
Now version 3 is online, and you can use the package with weighted networks as well using the BiWCM models!

@@ -71,8 +74,4 @@ See a more detailed walkthrough in **tests/bicm_test** or **tests/biwcm_test** notebooks, or check out the API in the documentation.

If you use the weighted models BiWCM_c or BiMCM you might consider citing also the following paper introducing the solvers of this package:
If you use the weighted models BiWCM_c or BiMCM you might consider citing also the paper introducing the solvers of this package [Bruno2023].
* Bruno, M., Mazzilli, D., Patelli, A., Squartini, T., and Saracco, F. \
*Inferring comparative advantage via entropy maximization.* \
In preparation
### References

@@ -82,2 +81,4 @@

[Bruno2023] [M. Bruno, D. Mazzilli, A. Patelli, T. Squartini, F. Saracco, Inferring comparative advantage via entropy maximization. Journal of Physics: Complexity, Volume 4, Number 4 (2023)](https://doi.org/10.1088/2632-072X/ad1411)
[Saracco2015] [F. Saracco, R. Di Clemente, A. Gabrielli, T. Squartini, Randomizing bipartite networks: the case of the World Trade Web, Scientific Reports 5, 10595 (2015)](http://www.nature.com/articles/srep10595).

@@ -84,0 +85,0 @@

@@ -8,3 +8,3 @@ import setuptools

name="bicm",
version="3.0.6",
version="3.1",
author="Matteo Bruno",

@@ -11,0 +11,0 @@ author_email="matteobruno180@gmail.com",

MIT License
Copyright (c) 2020 Matteo Bruno
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
import os, sys
import numpy as np
from scipy.linalg import solve, det
import datetime as dt
from delta_converter import delta_converter
from biwcm_main import biwcm_main
import warnings
warnings.filterwarnings("ignore")
class biwcm_c(biwcm_main):
def __init__(self, s_i, sigma_alpha, ic='random', tol=10**-8, max_iter=500, monitor=True, method='fixed-point', verbose=True):
super().__init__(s_i, sigma_alpha, ic, tol, max_iter, monitor, method, verbose)
def w_i_alpha(self, i, alpha):
return 1/(self.x[i]+self.x[alpha+self.n_rows])
def var_w_i_alpha(self, i, alpha):
return self.w_i_alpha(i, alpha)**2
# fixed-point
def fixed_point_fun(self):
return self.e_strength/self.strength
def fixed_point_x_update(self):
self.x*=self.delta
def fixed_point_jac(self):
_jac=np.zeros((self.n_rows+self.n_cols, self.n_rows+self.n_cols))
for i in range(self.n_rows):
for a in range(self.n_cols):
var_w_ia=self.var_w_i_alpha(i,a)
# off-diagonal terms
_jac[i,a+self.n_rows]=-self.x[i]/self.strength[i]*var_w_ia
_jac[a+self.n_rows, i]=-self.x[a+self.n_rows]/self.strength[a+self.n_rows]*var_w_ia
# terms on the diagonal
_jac[i, i]+=-self.x[a+self.n_rows]/self.strength[i]*var_w_ia
_jac[a+self.n_rows, a+self.n_rows]+=-self.x[i]/self.strength[a+self.n_rows]*var_w_ia
return _jac
# Newton
def newton_fun(self):
return -self.strength+self.e_strength
# written in terms of the variance of w_i_alpha
# the Newton's jacobian is the same for both the continuous and the discrete case
import os, sys
import numpy as np
from scipy.linalg import solve, det
import datetime as dt
from delta_converter import delta_converter
from biwcm_main import biwcm_main
class biwcm_d(biwcm_main):
def __init__(self, s_i, sigma_alpha, ic='random', tol=10**-8, max_iter=500, monitor=True, method='fixed-point', verbose=True):
super().__init__(s_i, sigma_alpha, ic, tol, max_iter, monitor, method, verbose)
def w_i_alpha(self, i, alpha):
num=np.exp(-(self.x[i]+self.x[alpha+self.n_rows]))
return num/(1-num)
def var_w_i_alpha(self, i, alpha):
num=np.exp(-(self.x[i]+self.x[alpha+self.n_rows]))
return num/(1-num)**2
# fixed-point
def fixed_point_fun(self):
return np.log(self.e_strength/self.strength)
def fixed_point_x_update(self):
self.x+=self.delta
def anderson_alpha(self, alpha):
delta=self.x+self.delta
min_delta=np.min(delta)
# actually, the limitation is stricter than necessary
if min_delta<=0:
w_min=np.where(delta==min_delta)[0]
exp_alpha=np.ceil(-np.log10(np.abs(self.x[w_min]/min_delta)))[0]
if self.verbose:
print('\nAnderson! alpha=10^{:d}\n'.format(-exp_alpha))
return 10**-exp_alpha
return 1
def fixed_point_jac(self):
_jac_diag=np.ones(self.n_rows+self.n_cols)
# the ones on the diagonal
_jac=np.diag(_jac_diag)
for i in range(self.n_rows):
for a in range(self.n_cols):
var_w_ia=self.var_w_i_alpha(i, a)
# off-diagonal terms
_jac[i,a+self.n_rows]=-var_w_ia/self.e_strength[i]
_jac[a+self.n_rows, i]=-var_w_ia/self.e_strength[a+self.n_rows]
# terms on the diagonal
_jac[i, i]+=-var_w_ia/self.e_strength[i]
_jac[a+self.n_rows, a+self.n_rows]+=-var_w_ia/self.e_strength[a+self.n_rows]
return _jac
# Newton
def newton_fun(self):
return -self.strength+self.e_strength
#return -np.log(self.strength)+np.log(self.e_strength)
# written in terms of the variance of w_i_alpha
# the Newton's jacobian is the same for both the continuous and the discrete case
import os, sys
import numpy as np
from scipy.linalg import solve, det
import datetime as dt
from delta_converter import delta_converter
class biwcm_main:
def __init__(self, s_i, sigma_alpha, ic='random', tol=10**-8, max_iter=500, monitor=True, method='fixed-point', verbose=True):
self.n_rows=len(s_i)
self.n_cols=len(sigma_alpha)
self.strength=np.concatenate((s_i, sigma_alpha))
self.tol=tol
self.max_iter=max_iter
self.monitor=monitor
self.method=method
self.verbose=verbose
# get initial conditions
if type(ic)==str:
# flat
if ic=='flat':
self.x=np.ones(self.n_rows+self.n_cols)
# still flat
elif ic=='galaxy':
self.x=42*np.ones(self.n_rows+self.n_cols)
# random
elif ic=='random':
self.x=np.random.random(size=self.n_rows+self.n_cols)
# positive, but distributed over a longer interval
self.x=-np.log(self.x)
elif ic=='zero':
self.x=tol*np.ones(self.n_rows+self.n_cols)
elif ic=='cla' or ic=='rca':
self.w=np.sum(s_i)
self.x=-np.log(self.strength/np.sqrt(self.w))
else:
print('the IC has not been implemented yet, turning to random IC')
self.x=np.random.random(size=self.n_rows+self.n_cols)
# positive, but distributed over a longer interval
self.x=-np.log(self.x)
elif type(ic)==np.ndarray:
self.x=ic
# saving the initial condition for further analysis
self.ic=self.x.copy()
# calculate how far I am from results from the very beginning
self.get_e_strength()
self.max_err()
if self.monitor:
# taking trace of what happened step by step
self.monitor_d={}
self.monitor_d['x']=[self.x.copy()]
self.monitor_d['mrse']=[self.mrse]
self.monitor_d['mase']=[self.mase]
self.monitor_d['s_n']=[self.e_strength.copy()]
if self.method=='fixed-point':
_jac=self.fixed_point_jac()
elif self.method=='newton':
_jac=self.newton_jac()
det_j=det(_jac)
self.monitor_d['det_J']=[det_j]
self.counter=0
def get_theta_eta(self):
self.start=dt.datetime.now()
if self.method=='fixed-point':
self.get_theta_eta_fixed_point()
elif self.method=='newton':
self.get_theta_eta_newton()
else:
print('method not implemented (yet?). Proceeding with Newton...')
self.get_theta_eta_newton()
self.has_converged()
# fixed-point
def get_theta_eta_fixed_point(self):
if self.verbose:
print('{:} MRSE={:.4e} MASE={:.4e}'.format(self.counter, self.mrse, self.mase), end='\r')
while self.mrse>self.tol and self.max_iter>self.counter:
self.counter+=1
self.fixed_point_iter()
if self.verbose:
print('{:} MRSE={:.4e} MASE={:.4e}'.format(self.counter, self.mrse, self.mase), end='\r')
def fixed_point_iter(self):
self.delta=self.fixed_point_fun()
#alpha=self.anderson_alpha(1)
#self.x+=alpha*self.delta
self.fixed_point_x_update()
# check the result
self.get_e_strength()
self.max_err()
if self.monitor:
self.monitor_d['x'].append(self.x.copy())
self.monitor_d['mrse'].append(self.mrse)
self.monitor_d['mase'].append(self.mase)
self.monitor_d['s_n'].append(self.e_strength.copy())
_jac=self.fixed_point_jac()
det_j=det(_jac)
self.monitor_d['det_J'].append(det_j)
# Newton
def get_theta_eta_newton(self):
if self.verbose:
print('{:} MRSE={:.4e} MASE={:.4e}'.format(self.counter, self.mrse, self.mase), end='\r')
while self.mrse>self.tol and self.max_iter>self.counter:
self.counter+=1
self.newton_iter()
if self.verbose:
print('{:} MRSE={:.4e} MASE={:.4e}'.format(self.counter, self.mrse, self.mase), end='\r')
def newton_iter(self):
self._matrix=self.newton_jac()
self._f=self.newton_fun()
self.delta=solve(self._matrix, self._f, assume_a='sym')
self.x+=self.delta
# check the result
self.get_e_strength()
self.max_err()
if self.monitor:
self.monitor_d['x'].append(self.x.copy())
self.monitor_d['mrse'].append(self.mrse)
self.monitor_d['mase'].append(self.mase)
self.monitor_d['s_n'].append(self.e_strength.copy())
_jac=self.newton_jac()
det_j=det(_jac)
self.monitor_d['det_J'].append(det_j)
# written in terms of the variance of w_i_alpha
# the Newton's jacobian, it is the same for both the continuous and the discrete case
def newton_jac(self):
# actually it is -J, i.e. the quantity that enters in the Newton step
_jac=np.zeros((self.n_rows+self.n_cols, self.n_rows+self.n_cols))
for i in range(self.n_rows):
for a in range(self.n_cols):
var_w_ia=self.var_w_i_alpha(i,a)
# off-diagonal terms
_jac[i,a+self.n_rows]=var_w_ia
_jac[a+self.n_rows, i]=var_w_ia
# terms on the diagonal
_jac[i, i]+=var_w_ia
_jac[a+self.n_rows, a+self.n_rows]+=var_w_ia
return _jac
# auxiliary functions
def max_err(self):
self.mrse=np.abs(self.strength-self.e_strength)/self.strength
self.mrse=np.max(self.mrse)
self.mase=np.abs(self.strength-self.e_strength)
self.mase=np.max(self.mase)
def has_converged(self):
if self.mrse<=self.tol:
self.converged=True
else:
self.converged=False
if self.verbose:
if self.converged:
final_result=' converged '
else:
final_result=' did not converge '
delta=dt.datetime.now()-self.start
sentence='Algorithm'+final_result+'after {:} steps in {:}. MRSE={:.4e} MASE={:.4e}'.format(self.counter, delta_converter(delta), self.mrse, self.mase)
print(sentence)
# written in terms of the expected value of w_i_alpha get_e_strength, it is the same for both the continuous and the discrete case
def get_e_strength(self):
self.e_strength=np.zeros(self.n_rows+self.n_cols)
for i in range(self.n_rows):
for a in range(self.n_cols):
wia=self.w_i_alpha(i,a)
self.e_strength[i]+=wia
self.e_strength[a+self.n_rows]+=wia
def delta_converter(delta):
if delta.seconds//60==0:
return str(delta.seconds)+' s'
elif delta.seconds//3600==0:
minutes=delta.seconds//60
seconds=delta.seconds % 60
return str(minutes)+' m and '+str(seconds)+' s'
else:
hours=delta.seconds//3600
rest=delta.seconds % 3600
minutes=rest//60
seconds=resrt % 60
return str(hours)+' h and '+str(minutes)+' m and '+str(seconds)+' s'

Sorry, the diff of this file is too big to display