SearchLibrium 0.0.145__tar.gz → 0.0.147__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 (59) hide show
  1. {searchlibrium-0.0.145/src/SearchLibrium.egg-info → searchlibrium-0.0.147}/PKG-INFO +1 -1
  2. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/pyproject.toml +1 -1
  3. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/search.py +20 -12
  4. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/siman.py +11 -5
  5. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/threshold.py +1 -1
  6. searchlibrium-0.0.147/src/SearchLibrium/version.txt +1 -0
  7. {searchlibrium-0.0.145 → searchlibrium-0.0.147/src/SearchLibrium.egg-info}/PKG-INFO +1 -1
  8. searchlibrium-0.0.145/src/SearchLibrium/version.txt +0 -1
  9. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/MANIFEST.in +0 -0
  10. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/README.md +0 -0
  11. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/setup.cfg +0 -0
  12. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/BEHier.py +0 -0
  13. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/Halton.py +0 -0
  14. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/MixedLogit.py +0 -0
  15. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/Mode_Activity_Nested.py +0 -0
  16. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/RandomP.py +0 -0
  17. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/SEARCH_SM_MARIO.py +0 -0
  18. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/Two_Level_Nest.py +0 -0
  19. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/__init__.py +0 -0
  20. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/__main__.py +0 -0
  21. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/_choice_model.py +0 -0
  22. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/_device.py +0 -0
  23. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/banditsa.py +0 -0
  24. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/bhhh/minimize.py +0 -0
  25. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/boxcox_functions.py +0 -0
  26. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/call_meta.py +0 -0
  27. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/constraints_builder.py +0 -0
  28. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/data/Swissmetro_final.csv +0 -0
  29. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/data/TravelMode.csv +0 -0
  30. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/data/electricity.csv +0 -0
  31. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/harmony.py +0 -0
  32. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/hspbil.py +0 -0
  33. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/latent_class.py +0 -0
  34. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/main.py +0 -0
  35. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/main_debug.py +0 -0
  36. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/mdcev.py +0 -0
  37. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/misc.py +0 -0
  38. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/mixed_logit.py +0 -0
  39. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/mixed_nested.py +0 -0
  40. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/mixedrrm.py +0 -0
  41. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/multinomial_logit.py +0 -0
  42. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/multinomial_nested.py +0 -0
  43. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/multinomial_probit.py +0 -0
  44. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/ordered_logit.py +0 -0
  45. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/ordered_logit_mixed.py +0 -0
  46. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/predict.py +0 -0
  47. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/rrm.py +0 -0
  48. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/sample_data.py +0 -0
  49. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/sapbil.py +0 -0
  50. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/selection_models.py +0 -0
  51. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/setup.py +0 -0
  52. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/test_lc_de.py +0 -0
  53. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/test_mario_searches.py +0 -0
  54. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium/test_sapbil_vs_banditsa.py +0 -0
  55. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium.egg-info/SOURCES.txt +0 -0
  56. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium.egg-info/dependency_links.txt +0 -0
  57. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium.egg-info/entry_points.txt +0 -0
  58. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium.egg-info/requires.txt +0 -0
  59. {searchlibrium-0.0.145 → searchlibrium-0.0.147}/src/SearchLibrium.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SearchLibrium
3
- Version: 0.0.145
3
+ Version: 0.0.147
4
4
  Summary: A Python package for econometric models driven by search
5
5
  Author: Mario Fernando Taco Morales, Alexander Paz, Prithvi Beeramole, Robert Burdett
6
6
  Author-email: Zeke Ahern <z.ahern@qut.edu.au>
@@ -82,7 +82,7 @@ Documentation = "https://pypi.org/project/SearchLibrium/"
82
82
  realpython = "SearchLibrium.__main__:main"
83
83
 
84
84
  [tool.bumpver]
85
- current_version = "0.0.145"
85
+ current_version = "0.0.147"
86
86
  version_pattern = "MAJOR.MINOR.PATCH"
87
87
  commit_message = "[skip ci] Bump version {old_version} -> {new_version}"
88
88
  commit = true
@@ -87,6 +87,7 @@ except ImportError:
87
87
  from .ordered_logit import OrderedLogitLong
88
88
  from . import misc
89
89
  from .multinomial_nested import NestedLogit, MultiLayerNestedLogit
90
+ from addicty import Dict
90
91
 
91
92
  ''' ---------------------------------------------------------- '''
92
93
  ''' CONSTANTS '''
@@ -788,8 +789,9 @@ class Parameters:
788
789
  # TODO I Think we could initialise it this way more effictively
789
790
  acceptable_keys = [
790
791
  'LCR', 'verbose', 'asc_ind', 'nests', 'lambdas', 'varnest',
791
- '_jax', 'all_sig', 'de_init', 'de_popsize', 'de_maxiter',
792
- 'de_tol', 'de_polish', 'sd_penalty', 'halton_opts', 'latent_class'
792
+ '_jax', 'all_sig', 'de_init', 'de_popsize', 'de_maxiter',
793
+ 'de_tol', 'de_polish', 'sd_penalty', 'halton_opts', 'latent_class',
794
+ 'num_classes',
793
795
  ]
794
796
 
795
797
  # Assign all kwargs to self, but only if the key is in the acceptable_keys list
@@ -1985,12 +1987,15 @@ class Search():
1985
1987
  if model_n == 'nested_logit':
1986
1988
  all_vars = list(set(asvars+isvars))
1987
1989
  logging.info('prereqs')
1988
- if 'ps_alt_vars' in self.param.pres_spec_constr:
1989
- ps_alt_vars = self.param.pres_spec_constr['ps_alt_vars']
1990
+ # pres_spec_constr defaults to None when no constraints are supplied
1991
+ # at all -- 'x in None' raises TypeError, so guard with `or {}`.
1992
+ _psc = self.param.pres_spec_constr or {}
1993
+ if 'ps_alt_vars' in _psc:
1994
+ ps_alt_vars = _psc['ps_alt_vars']
1990
1995
  else:
1991
1996
  ps_alt_vars = None
1992
- if 'ps_nest_vars' in self.param.pres_spec_constr:
1993
- ps_nest_vars = self.param.pres_spec_constr['ps_nest_vars']
1997
+ if 'ps_nest_vars' in _psc:
1998
+ ps_nest_vars = _psc['ps_nest_vars']
1994
1999
  else:
1995
2000
  ps_nest_vars = None
1996
2001
  state = Dict({'all_vars': all_vars,
@@ -3749,8 +3754,8 @@ class Search():
3749
3754
  ''' and cache the result if it converged. '''
3750
3755
  ''' ------------------------------------------------------------------ '''
3751
3756
 
3752
- def evaluate_solution(self, sol):
3753
-
3757
+ def evaluate_solution(self, sol, track_best=True):
3758
+
3754
3759
  sig = self.setup_signature(sol)
3755
3760
 
3756
3761
  if sig not in self.explored_specs:
@@ -3763,7 +3768,7 @@ class Search():
3763
3768
  sol.update_objective(i, score)
3764
3769
  return sol, True
3765
3770
 
3766
- sol, converged = self._evaluate_solution(sol)
3771
+ sol, converged = self._evaluate_solution(sol, track_best=track_best)
3767
3772
 
3768
3773
  if converged:
3769
3774
  self.evaluated_solutions[sig] = [sol.obj(i) for i in range(self.nb_crit)]
@@ -3780,7 +3785,7 @@ class Search():
3780
3785
  ''' re-estimated. The function returns the estimated solution '''
3781
3786
  ''' only if it converges. '''
3782
3787
  ''' ---------------------------------------------------------- '''
3783
- def _evaluate_solution(self, sol):
3788
+ def _evaluate_solution(self, sol, track_best=True):
3784
3789
  # {
3785
3790
  # apply_constraints() was previously only wired into evaluate_lc/
3786
3791
  # evaluate_nested_logit/evaluate_mixed_nested — plain multinomial/mixed
@@ -3836,7 +3841,7 @@ class Search():
3836
3841
  sol['converged'] = True
3837
3842
  self.update_objectives(self.param.criterions, sol)
3838
3843
 
3839
- if not hasattr(self, 'best_solution') or self.find_best_sol([sol, self.best_solution]) == sol:
3844
+ if track_best and (not hasattr(self, 'best_solution') or self.find_best_sol([sol, self.best_solution]) == sol):
3840
3845
  self.best_solution = sol
3841
3846
  if self.last_printed_solution is None or not self.solutions_equal(sol, self.last_printed_solution):
3842
3847
  self.print_best_solution(sol)
@@ -4404,7 +4409,10 @@ class Search():
4404
4409
  if len(all_vars) == 0:
4405
4410
  raise ValueError('need a variable: todo debug why')
4406
4411
  all_vars = [var for var in self.param.varnames if var in all_vars]
4407
- nest_vars = [var for var in self.param.varnest if var in all_vars]
4412
+ # varnest (nest-level utility variables) is optional and has no default
4413
+ # in Parameters.__init__ -- most nested_logit specs don't use nest-level
4414
+ # covariates at all, so treat missing/None as "no nest variables".
4415
+ nest_vars = [var for var in (getattr(self.param, 'varnest', None) or []) if var in all_vars]
4408
4416
 
4409
4417
  X, y = self.param.df[all_vars].values, self.param.choices
4410
4418
  X_nest = self.param.df[nest_vars]
@@ -516,7 +516,10 @@ class SA(Search):
516
516
  for attempt in range(1, N_trials + 1):
517
517
  sol = self.generate_solution()
518
518
  sol = self.repair_solution_for_clarity(sol)
519
- sol, converged = self.evaluate(sol)
519
+ # track_best=False: this is a disposable calibration trial, not
520
+ # part of the accepted search trajectory, so it must not update
521
+ # (or print) the run's global best solution.
522
+ sol, converged = self.evaluate(sol, track_best=False)
520
523
  if converged:
521
524
  base_sol = sol
522
525
  break
@@ -579,7 +582,10 @@ class SA(Search):
579
582
  print(f"Trial {trial}: Could not generate a new proposed solution, skipping temperature calculation.")
580
583
  continue
581
584
 
582
- proposed_sol, converged = self.evaluate(proposed_sol)
585
+ # track_best=False: same reason as above — these proposals are
586
+ # only used to estimate delta_E for the starting temperature and
587
+ # are discarded immediately after, they never become current_sol.
588
+ proposed_sol, converged = self.evaluate(proposed_sol, track_best=False)
583
589
  if not converged:
584
590
  print(f"Trial {trial}: Proposed solution did not converge, skipping temperature calculation.")
585
591
  continue
@@ -639,10 +645,10 @@ class SA(Search):
639
645
  ''' ---------------------------------------------------------- '''
640
646
  ''' Function. Evaluate how good a solution is '''
641
647
  ''' ---------------------------------------------------------- '''
642
- def evaluate(self, sol):
648
+ def evaluate(self, sol, track_best=True):
643
649
  # {
644
- sol, converged = self.evaluate_solution(sol)
645
-
650
+ sol, converged = self.evaluate_solution(sol, track_best=track_best)
651
+
646
652
  return sol, converged
647
653
  # }
648
654
 
@@ -367,7 +367,7 @@ class TA(Search):
367
367
  if self.nb_crit == 1:
368
368
  # {
369
369
  if is_better(sol.obj(0), self.best_sol.obj(0), self.param.sign_crit(0)):
370
- self.best_sol.copy_solution(sol)
370
+ self.best_sol = self.copy_solution(sol)
371
371
  self.no_impr = 0
372
372
  # }
373
373
  else:
@@ -0,0 +1 @@
1
+ 0.0.147
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SearchLibrium
3
- Version: 0.0.145
3
+ Version: 0.0.147
4
4
  Summary: A Python package for econometric models driven by search
5
5
  Author: Mario Fernando Taco Morales, Alexander Paz, Prithvi Beeramole, Robert Burdett
6
6
  Author-email: Zeke Ahern <z.ahern@qut.edu.au>
@@ -1 +0,0 @@
1
- 0.0.145