Skip to content

Commit d7077a1

Browse files
authored
Merge pull request #122 from vissarion/fix/mmcs_and_warning
Remove mmcs option for generate_steady_states_no_multiphase and fix a warning
2 parents cdcb43c + 04e8376 commit d7077a1

5 files changed

Lines changed: 40 additions & 57 deletions

File tree

dingo/PolytopeSampler.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ def get_polytope(self):
5353
"""
5454

5555
if (
56-
self._A == []
57-
or self._b == []
58-
or self._N == []
59-
or self._N_shift == []
60-
or self._T == []
61-
or self._T_shift == []
56+
len(self._A) == 0
57+
or len(self._b) == 0
58+
or len(self._N) == 0
59+
or len(self._N_shift) == 0
60+
or len(self._T) == 0
61+
or len(self._T_shift) == 0
6262
):
6363

6464
(
@@ -161,7 +161,8 @@ def generate_steady_states(
161161
return steady_states
162162

163163
def generate_steady_states_no_multiphase(
164-
self, method = 'billiard_walk', n=1000, burn_in=0, thinning=1, variance=1.0, bias_vector=None, ess=1000
164+
self, method = 'billiard_walk', n=1000, burn_in=0, thinning=1,
165+
variance=1.0, bias_vector=None
165166
):
166167
"""A member function to sample steady states.
167168
@@ -171,6 +172,8 @@ def generate_steady_states_no_multiphase(
171172
burn_in -- the number of points to burn before sampling
172173
thinning -- the walk length of the chain
173174
"""
175+
if method == "mmcs":
176+
raise ValueError("method cannot be 'mmcs'. Use generate_steady_states() instead.")
174177

175178
self.get_polytope()
176179

@@ -181,7 +184,7 @@ def generate_steady_states_no_multiphase(
181184
else:
182185
bias_vector = bias_vector.astype('float64')
183186

184-
samples = P.generate_samples(method.encode('utf-8'), n, burn_in, thinning, variance, bias_vector, self._parameters["solver"], ess)
187+
samples = P.generate_samples(method.encode('utf-8'), n, burn_in, thinning, variance, bias_vector, self._parameters["solver"])
185188
samples_T = samples.T
186189

187190
steady_states = map_samples_to_steady_states(
@@ -216,7 +219,7 @@ def sample_from_polytope(
216219

217220
@staticmethod
218221
def sample_from_polytope_no_multiphase(
219-
A, b, method = 'billiard_walk', n=1000, burn_in=0, thinning=1, variance=1.0, bias_vector=None, solver=None, ess=1000
222+
A, b, method = 'billiard_walk', n=1000, burn_in=0, thinning=1, variance=1.0, bias_vector=None, solver=None
220223
):
221224
"""A static function to sample from a full dimensional polytope with an MCMC method.
222225
@@ -235,7 +238,7 @@ def sample_from_polytope_no_multiphase(
235238

236239
P = HPolytope(A, b)
237240

238-
samples = P.generate_samples(method.encode('utf-8'), n, burn_in, thinning, variance, bias_vector, solver, ess)
241+
samples = P.generate_samples(method.encode('utf-8'), n, burn_in, thinning, variance, bias_vector, solver)
239242

240243
samples_T = samples.T
241244
return samples_T

dingo/bindings/bindings.cpp

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ double HPolytopeCPP::apply_sampling(int walk_len,
9191
double radius,
9292
double* samples,
9393
double variance_value,
94-
double* bias_vector_,
95-
int ess){
94+
double* bias_vector_){
9695

9796
RNGType rng(HP.dimension());
9897
HP.normalize();
@@ -134,13 +133,6 @@ double HPolytopeCPP::apply_sampling(int walk_len,
134133
} else if (strcmp(method, "vaidya_walk") == 0) { // vaidya walk
135134
uniform_sampling<VaidyaWalk>(rand_points, HP, rng, walk_len, number_of_points,
136135
starting_point, number_of_points_to_burn);
137-
} else if (strcmp(method, "mmcs") == 0) { // vaidya walk
138-
MT S;
139-
int total_ess;
140-
//TODO: avoid passing polytopes as non-const references
141-
const Hpolytope HP_const = HP;
142-
mmcs(HP_const, ess, S, total_ess, walk_len, rng);
143-
samples = S.data();
144136
} else if (strcmp(method, "gaussian_hmc_walk") == 0) { // Gaussian sampling with exact HMC walk
145137
NT a = NT(1)/(NT(2)*variance);
146138
gaussian_sampling<GaussianHamiltonianMonteCarloExactWalk>(rand_points, HP, rng, walk_len, number_of_points, a,
@@ -170,14 +162,12 @@ double HPolytopeCPP::apply_sampling(int walk_len,
170162
throw std::runtime_error("This function must not be called.");
171163
}
172164

173-
if (strcmp(method, "mmcs") != 0) {
174-
// The following block of code allows us to copy the sampled points
175-
auto n_si=0;
176-
for (auto it_s = rand_points.cbegin(); it_s != rand_points.cend(); it_s++){
177-
for (auto i = 0; i != it_s->dimension(); i++){
178-
samples[n_si++] = (*it_s)[i];
179-
}
180-
}
165+
// The following block of code allows us to copy the sampled points
166+
auto n_si=0;
167+
for (auto it_s = rand_points.cbegin(); it_s != rand_points.cend(); it_s++){
168+
for (auto i = 0; i != it_s->dimension(); i++){
169+
samples[n_si++] = (*it_s)[i];
170+
}
181171
}
182172
return 0.0;
183173
}

dingo/bindings/bindings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class HPolytopeCPP{
141141
// the apply_sampling() function
142142
double apply_sampling(int walk_len, int number_of_points, int number_of_points_to_burn,
143143
char* method, double* inner_point, double radius, double* samples,
144-
double variance_value, double* bias_vector, int ess);
144+
double variance_value, double* bias_vector);
145145

146146
void mmcs_initialize(int d, int ess, bool psrf_check, bool parallelism, int num_threads);
147147

dingo/volestipy.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ cdef extern from "bindings.h":
5555
# Random sampling
5656
double apply_sampling(int walk_len, int number_of_points, int number_of_points_to_burn, \
5757
char* method, double* inner_point, double radius, double* samples, \
58-
double variance_value, double* bias_vector, int ess)
58+
double variance_value, double* bias_vector)
5959

6060
# Initialize the parameters for the (m)ultiphase (m)onte (c)arlo (s)ampling algorithm
6161
void mmcs_initialize(unsigned int d, int ess, int psrf_check, int parallelism, int num_threads);
@@ -119,7 +119,7 @@ cdef class HPolytope:
119119

120120
# Likewise, the generate_samples() function
121121
def generate_samples(self, method, number_of_points, number_of_points_to_burn, walk_len,
122-
variance_value, bias_vector, solver = None, ess = 1000):
122+
variance_value, bias_vector, solver = None):
123123

124124
n_variables = self._A.shape[1]
125125
cdef double[:,::1] samples = np.zeros((number_of_points, n_variables), dtype = np.float64, order = "C")
@@ -133,7 +133,7 @@ cdef class HPolytope:
133133

134134
self.polytope_cpp.apply_sampling(walk_len, number_of_points, number_of_points_to_burn, \
135135
method, &inner_point_for_c[0], radius, &samples[0,0], \
136-
variance_value, &bias_vector_[0], ess)
136+
variance_value, &bias_vector_[0])
137137
return np.asarray(samples)
138138

139139

tests/sampling_no_multiphase.py

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# dingo is part of GeomScale project
33

44
# Copyright (c) 2022 Apostolos Chalkis
5-
# Copyright (c) 2022 Vissarion Fisikopoulos
5+
# Copyright (c) 2022-2025 Vissarion Fisikopoulos
66
# Copyright (c) 2022 Haris Zafeiropoulos
77
# Copyright (c) 2024 Ke Shi
88

@@ -11,41 +11,33 @@
1111
import unittest
1212
import os
1313
import sys
14+
import numpy as np
1415
from dingo import MetabolicNetwork, PolytopeSampler
1516
from dingo.pyoptinterface_based_impl import set_default_solver
1617

18+
def test_shape_and_non_zero(steady_states, shape0, shape1, testing_class):
19+
testing_class.assertTrue( steady_states.shape[0] == shape0 )
20+
testing_class.assertTrue( steady_states.shape[1] == shape1 )
21+
testing_class.assertTrue( np.any(np.abs(steady_states) > 1e-12) )
22+
1723
def sampling(model, testing_class):
1824
sampler = PolytopeSampler(model)
1925

2026
#Gaussian hmc sampling
21-
steady_states = sampler.generate_steady_states_no_multiphase(method = 'mmcs', ess=1000)
22-
23-
testing_class.assertTrue( steady_states.shape[0] == 95 )
24-
testing_class.assertTrue( steady_states.shape[1] == 1000 )
25-
26-
#Gaussian hmc sampling
27-
steady_states = sampler.generate_steady_states_no_multiphase(method = 'gaussian_hmc_walk', n=500)
28-
29-
testing_class.assertTrue( steady_states.shape[0] == 95 )
30-
testing_class.assertTrue( steady_states.shape[1] == 500 )
27+
steady_states = sampler.generate_steady_states_no_multiphase(method = 'gaussian_hmc_walk', n=1000)
28+
test_shape_and_non_zero(steady_states, 95, 1000, testing_class)
3129

3230
#exponential hmc sampling
33-
steady_states = sampler.generate_steady_states_no_multiphase(method = 'exponential_hmc_walk', n=500, variance=50)
34-
35-
testing_class.assertTrue( steady_states.shape[0] == 95 )
36-
testing_class.assertTrue( steady_states.shape[1] == 500 )
37-
31+
steady_states = sampler.generate_steady_states_no_multiphase(method = 'exponential_hmc_walk', n=1000, variance=50)
32+
test_shape_and_non_zero(steady_states, 95, 1000, testing_class)
33+
3834
#hmc sampling with Gaussian distribution
39-
steady_states = sampler.generate_steady_states_no_multiphase(method = 'hmc_leapfrog_gaussian', n=500)
40-
41-
testing_class.assertTrue( steady_states.shape[0] == 95 )
42-
testing_class.assertTrue( steady_states.shape[1] == 500 )
35+
steady_states = sampler.generate_steady_states_no_multiphase(method = 'hmc_leapfrog_gaussian', n=1000)
36+
test_shape_and_non_zero(steady_states, 95, 1000, testing_class)
4337

4438
#hmc sampling with exponential distribution
45-
steady_states = sampler.generate_steady_states_no_multiphase(method = 'hmc_leapfrog_exponential', n=500, variance=50)
46-
47-
testing_class.assertTrue( steady_states.shape[0] == 95 )
48-
testing_class.assertTrue( steady_states.shape[1] == 500 )
39+
steady_states = sampler.generate_steady_states_no_multiphase(method = 'hmc_leapfrog_exponential', n=1000, variance=50)
40+
test_shape_and_non_zero(steady_states, 95, 1000, testing_class)
4941

5042
#steady_states[12].mean() seems to have a lot of discrepancy between experiments, so we won't check the mean for now
5143
#self.assertTrue( abs( steady_states[12].mean() - 2.504 ) < 1e-03 )
@@ -70,8 +62,6 @@ def test_sample_sbml(self):
7062
model = MetabolicNetwork.from_sbml( input_file_sbml )
7163
sampling(model, self)
7264

73-
74-
7565
if __name__ == "__main__":
7666
if len(sys.argv) > 1:
7767
set_default_solver(sys.argv[1])

0 commit comments

Comments
 (0)