SearchLibrium 0.0.262__tar.gz → 0.0.265__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. {searchlibrium-0.0.262/src/SearchLibrium.egg-info → searchlibrium-0.0.265}/PKG-INFO +1 -1
  2. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/pyproject.toml +1 -1
  3. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/Halton.py +27 -15
  4. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/MixedLogit.py +477 -53
  5. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/__init__.py +104 -107
  6. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/destination_distances.py +34 -11
  7. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/larch_compat.py +5 -0
  8. searchlibrium-0.0.265/src/SearchLibrium/larch_models.py +938 -0
  9. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/latent_class.py +9 -0
  10. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/latent_spec.py +12 -1
  11. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/multinomial_logit.py +4 -1
  12. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/numba_mxl.py +2 -2
  13. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/search.py +177 -12
  14. searchlibrium-0.0.265/src/SearchLibrium/version.txt +1 -0
  15. {searchlibrium-0.0.262 → searchlibrium-0.0.265/src/SearchLibrium.egg-info}/PKG-INFO +1 -1
  16. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_larch_integration.py +72 -2
  17. searchlibrium-0.0.262/src/SearchLibrium/larch_models.py +0 -413
  18. searchlibrium-0.0.262/src/SearchLibrium/version.txt +0 -1
  19. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/LICENSE +0 -0
  20. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/MANIFEST.in +0 -0
  21. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/README.md +0 -0
  22. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/setup.cfg +0 -0
  23. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/BEHier.py +0 -0
  24. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/MixedLogitGSE.py +0 -0
  25. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/Mode_Activity_Nested.py +0 -0
  26. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/RandomP.py +0 -0
  27. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/SEARCH_SM_MARIO.py +0 -0
  28. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/Two_Level_Nest.py +0 -0
  29. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/__main__.py +0 -0
  30. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/_choice_model.py +0 -0
  31. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/_device.py +0 -0
  32. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/abm.py +0 -0
  33. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/accessibility.py +0 -0
  34. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/banditsa.py +0 -0
  35. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/boxcox_functions.py +0 -0
  36. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/call_meta.py +0 -0
  37. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/constraints_builder.py +0 -0
  38. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/coupled_solver.py +0 -0
  39. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/data/Swissmetro_final.csv +0 -0
  40. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/data/TravelMode.csv +0 -0
  41. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/data/electricity.csv +0 -0
  42. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/harmony.py +0 -0
  43. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/hspbil.py +0 -0
  44. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/jax_utils.py +0 -0
  45. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/logistic_regression.py +0 -0
  46. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/main.py +0 -0
  47. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/main_debug.py +0 -0
  48. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/mdcev.py +0 -0
  49. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/mh_choice_estimator.py +0 -0
  50. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/misc.py +0 -0
  51. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/mixed_logit.py +0 -0
  52. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/mixed_nested.py +0 -0
  53. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/mixedrrm.py +0 -0
  54. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/multinomial_nested.py +0 -0
  55. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/multinomial_probit.py +0 -0
  56. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/numba_engine.py +0 -0
  57. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/numba_rrm.py +0 -0
  58. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/ordered_logit.py +0 -0
  59. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/ordered_logit_mixed.py +0 -0
  60. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/predict.py +0 -0
  61. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/regularization.py +0 -0
  62. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/rrm.py +0 -0
  63. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/sample_data.py +0 -0
  64. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/sapbil.py +0 -0
  65. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/selection_models.py +0 -0
  66. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/setup.py +0 -0
  67. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/siman.py +0 -0
  68. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/skims.py +0 -0
  69. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/sparseea_agds.py +0 -0
  70. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/test_lc_de.py +0 -0
  71. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/test_mario_searches.py +0 -0
  72. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/test_sapbil_vs_banditsa.py +0 -0
  73. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/threshold.py +0 -0
  74. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium/zero_inflated_ordered_probit.py +0 -0
  75. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium.egg-info/SOURCES.txt +0 -0
  76. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium.egg-info/dependency_links.txt +0 -0
  77. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium.egg-info/entry_points.txt +0 -0
  78. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium.egg-info/requires.txt +0 -0
  79. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/src/SearchLibrium.egg-info/top_level.txt +0 -0
  80. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_destination_distances.py +0 -0
  81. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_jax_mask_equivalence.py +0 -0
  82. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_lc_smart_init.py +0 -0
  83. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_mh_choice_estimator.py +0 -0
  84. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_mxl_random_starts.py +0 -0
  85. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_per_alternative_random.py +0 -0
  86. {searchlibrium-0.0.262 → searchlibrium-0.0.265}/tests/test_zero_inflated_ordered_probit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SearchLibrium
3
- Version: 0.0.262
3
+ Version: 0.0.265
4
4
  Summary: Automated specification search for discrete choice models (logit, mixed logit, nested logit, RRM and more) using metaheuristic optimisation
5
5
  Author: Zeke Ahern, Mario Fernando Taco Morales, Alexander Paz, Prithvi Beeramole, Robert Burdett
6
6
  Maintainer-email: Zeke Ahern <z.ahern@qut.edu.au>
@@ -132,7 +132,7 @@ Documentation = "https://pypi.org/project/SearchLibrium/"
132
132
  realpython = "SearchLibrium.__main__:main"
133
133
 
134
134
  [tool.bumpver]
135
- current_version = "0.0.262"
135
+ current_version = "0.0.265"
136
136
  version_pattern = "MAJOR.MINOR.PATCH"
137
137
  commit_message = "[skip ci] Bump version {old_version} -> {new_version}"
138
138
  commit = true
@@ -45,8 +45,9 @@ class HaltonSequence:
45
45
  self.drop = drop
46
46
  self.shuffled = shuffled
47
47
 
48
- def generate(self, sample_size, n_draws, n_vars):
49
- return _sobol_generate(sample_size, n_draws, n_vars, shuffled=self.shuffled)
48
+ def generate(self, sample_size, n_draws, n_vars, offset=0):
49
+ return _sobol_generate(sample_size, n_draws, n_vars,
50
+ shuffled=self.shuffled, offset=offset)
50
51
 
51
52
 
52
53
  class Halton:
@@ -56,12 +57,14 @@ class Halton:
56
57
  Set use_sobol=True to use scrambled Sobol sequences instead.
57
58
  """
58
59
 
59
- def __init__(self, primes=None, drop=100, shuffled=False, antithetic=False, use_sobol=False):
60
+ def __init__(self, primes=None, drop=100, shuffled=False,
61
+ antithetic=False, use_sobol=False, seed=None):
60
62
  self.primes = primes
61
63
  self.drop = drop
62
64
  self.shuffled = shuffled
63
65
  self.antithetic = antithetic
64
66
  self.use_sobol = use_sobol
67
+ self.seed = seed
65
68
 
66
69
  # Default primes for Halton sequence
67
70
  if self.primes is None:
@@ -72,7 +75,7 @@ class Halton:
72
75
  239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293,
73
76
  307, 311]
74
77
 
75
- def generate_draws(self, sample_size, n_draws, n_vars):
78
+ def generate_draws(self, sample_size, n_draws, n_vars, offset=0):
76
79
  """Generate random draws for multiple variables.
77
80
 
78
81
  When ``antithetic=True``, draws of size ``n_draws // 2`` are generated
@@ -81,36 +84,40 @@ class Halton:
81
84
  if self.use_sobol:
82
85
  # Use Sobol sequence (newer method)
83
86
  base = n_draws // 2 if self.antithetic else n_draws
84
- draws = _sobol_generate(sample_size, base, n_vars, shuffled=self.shuffled)
87
+ draws = _sobol_generate(
88
+ sample_size, base, n_vars, shuffled=self.shuffled,
89
+ seed=self.seed, offset=offset)
85
90
  if self.antithetic:
86
91
  draws = np.concatenate([draws, 1.0 - draws], axis=2)
87
92
  else:
88
93
  # Use traditional Halton sequence (compatible with searchlogit)
89
- draws = self._generate_halton_draws(sample_size, n_draws, n_vars)
94
+ draws = self._generate_halton_draws(
95
+ sample_size, n_draws, n_vars, offset=offset)
90
96
  if self.antithetic:
91
97
  draws_half = draws[:, :, : n_draws // 2]
92
98
  draws = np.concatenate([draws_half, 1.0 - draws_half], axis=2)
93
99
 
94
100
  return draws
95
101
 
96
- def _generate_halton_draws(self, sample_size, n_draws, n_vars):
102
+ def _generate_halton_draws(self, sample_size, n_draws, n_vars, offset=0):
97
103
  """Generate traditional Halton draws using different primes for each variable."""
98
104
  draws_list = []
99
105
  for i in range(n_vars):
100
106
  prime = self.primes[i % len(self.primes)]
101
107
  halton_seq = _halton_seq_traditional(
102
- sample_size * n_draws,
108
+ offset * n_draws + sample_size * n_draws,
103
109
  prime=prime,
104
110
  drop=self.drop,
105
111
  shuffled=self.shuffled
106
- )
112
+ )[offset * n_draws:]
107
113
  draws_list.append(halton_seq.reshape(sample_size, n_draws))
108
114
 
109
115
  draws = np.stack(draws_list, axis=1) # (sample_size, n_vars, n_draws)
110
116
  return draws
111
117
 
112
118
 
113
- def _sobol_generate(sample_size, n_draws, n_vars, shuffled=False):
119
+ def _sobol_generate(sample_size, n_draws, n_vars, shuffled=False, seed=None,
120
+ offset=0):
114
121
  """Generate scrambled Sobol (0,1) draws.
115
122
 
116
123
  Returns
@@ -123,7 +130,9 @@ def _sobol_generate(sample_size, n_draws, n_vars, shuffled=False):
123
130
  p2 = 1
124
131
  while p2 < total:
125
132
  p2 <<= 1
126
- sobol = Sobol(d=n_vars, scramble=True)
133
+ sobol = Sobol(d=n_vars, scramble=True, seed=seed)
134
+ if offset:
135
+ sobol.fast_forward(offset * n_draws)
127
136
  flat = sobol.random(p2)[:total] # (total, n_vars)
128
137
  draws = flat.reshape(sample_size, n_draws, n_vars).transpose(0, 2, 1)
129
138
  else:
@@ -159,10 +168,11 @@ class Draws:
159
168
  self.rvdist = rvdist or ['n'] * k
160
169
  self.rvtransdist = rvtransdist or ['n'] * k
161
170
 
162
- def generate_draws(self, sample_size, n_draws, halton=True):
171
+ def generate_draws(self, sample_size, n_draws, halton=True, offset=0):
163
172
  """Generate draws based on the chosen method."""
164
173
  if halton:
165
- draws = self.fn_generate_draws(sample_size, n_draws, self.k)
174
+ draws = self.fn_generate_draws(
175
+ sample_size, n_draws, self.k, offset=offset)
166
176
  else:
167
177
  draws = np.random.uniform(size=(sample_size, self.k, n_draws))
168
178
  draws = self.evaluate_distribution(self.rvdist, draws)
@@ -189,9 +199,11 @@ class Draws:
189
199
  index = index if index is not None else self.rvdist
190
200
  for k, distr in enumerate(index):
191
201
  if distr == 'ln':
192
- betas_random[:, k, :] = np.exp(betas_random[:, k, :])
202
+ betas_random[:, k, :] = np.exp(
203
+ np.clip(betas_random[:, k, :], -50.0, 50.0))
193
204
  elif distr == 'nln': # negative log-normal
194
- betas_random[:, k, :] = -np.exp(betas_random[:, k, :])
205
+ betas_random[:, k, :] = -np.exp(
206
+ np.clip(betas_random[:, k, :], -50.0, 50.0))
195
207
  elif distr == 'tn':
196
208
  betas_random[:, k, :] = np.maximum(betas_random[:, k, :], 0)
197
209
  return betas_random