SearchLibrium 0.0.136__tar.gz → 0.0.138__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 (53) hide show
  1. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/PKG-INFO +1 -1
  2. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/pyproject.toml +1 -1
  3. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/MixedLogit.py +9 -9
  4. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/_choice_model.py +23 -0
  5. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/latent_class.py +1 -1
  6. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/search.py +1 -1
  7. searchlibrium-0.0.138/src/SearchLibrium/version.txt +1 -0
  8. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium.egg-info/PKG-INFO +1 -1
  9. searchlibrium-0.0.136/src/SearchLibrium/version.txt +0 -1
  10. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/README.md +0 -0
  11. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/setup.cfg +0 -0
  12. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/Halton.py +0 -0
  13. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/Mode_Activity_Nested.py +0 -0
  14. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/RandomP.py +0 -0
  15. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/SEARCH_SM_MARIO.py +0 -0
  16. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/Two_Level_Nest.py +0 -0
  17. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/__init__.py +0 -0
  18. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/__main__.py +0 -0
  19. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/_device.py +0 -0
  20. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/banditsa.py +0 -0
  21. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/bhhh/minimize.py +0 -0
  22. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/boxcox_functions.py +0 -0
  23. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/call_meta.py +0 -0
  24. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/constraints_builder.py +0 -0
  25. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/harmony.py +0 -0
  26. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/hspbil.py +0 -0
  27. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/main.py +0 -0
  28. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/main_debug.py +0 -0
  29. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/mdcev.py +0 -0
  30. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/misc.py +0 -0
  31. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/mixed_logit.py +0 -0
  32. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/mixed_nested.py +0 -0
  33. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/mixedrrm.py +0 -0
  34. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/multinomial_logit.py +0 -0
  35. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/multinomial_nested.py +0 -0
  36. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/multinomial_probit.py +0 -0
  37. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/ordered_logit.py +0 -0
  38. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/ordered_logit_mixed.py +0 -0
  39. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/predict.py +0 -0
  40. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/rrm.py +0 -0
  41. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/sapbil.py +0 -0
  42. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/selection_models.py +0 -0
  43. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/setup.py +0 -0
  44. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/siman.py +0 -0
  45. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/test_lc_de.py +0 -0
  46. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/test_mario_searches.py +0 -0
  47. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/test_sapbil_vs_banditsa.py +0 -0
  48. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium/threshold.py +0 -0
  49. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium.egg-info/SOURCES.txt +0 -0
  50. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium.egg-info/dependency_links.txt +0 -0
  51. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium.egg-info/entry_points.txt +0 -0
  52. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/src/SearchLibrium.egg-info/requires.txt +0 -0
  53. {searchlibrium-0.0.136 → searchlibrium-0.0.138}/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.136
3
+ Version: 0.0.138
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>
@@ -73,7 +73,7 @@ Documentation = "https://pypi.org/project/SearchLibrium/"
73
73
  realpython = "SearchLibrium.__main__:main"
74
74
 
75
75
  [tool.bumpver]
76
- current_version = "0.0.136"
76
+ current_version = "0.0.138"
77
77
  version_pattern = "MAJOR.MINOR.PATCH"
78
78
  commit_message = "[skip ci] Bump version {old_version} -> {new_version}"
79
79
  commit = true
@@ -459,12 +459,13 @@ class MixedLogit(DiscreteChoiceModel):
459
459
  print(f"[MXL] Starting beta seed length={n_coeff}, first_values={betas[:min(8, len(betas))]!r}")
460
460
 
461
461
  if self.de_init:
462
- print(f"[MXL] DE init enabled: popsize={self.de_popsize}, maxiter={self.de_maxiter}, tol={self.de_tol}, polish={self.de_polish}")
462
+ _v = getattr(self, 'verbose_de', False)
463
+ if _v: print(f"[MXL] DE init enabled: popsize={self.de_popsize}, maxiter={self.de_maxiter}, tol={self.de_tol}, polish={self.de_polish}")
463
464
  try:
464
465
  before_de_obj = self.get_loglik_gradient(betas, self.X, self.y, self.panel_info,
465
466
  draws, drawstrans, self.weights,
466
467
  self.avail, self.batch_size)[0]
467
- print(f"[MXL] DE before: obj={before_de_obj:.6g}")
468
+ if _v: print(f"[MXL] DE before: obj={before_de_obj:.6g}")
468
469
 
469
470
  def _de_obj(x):
470
471
  return self.get_loglik_gradient(x, self.X, self.y, self.panel_info,
@@ -495,23 +496,22 @@ class MixedLogit(DiscreteChoiceModel):
495
496
  workers=1,
496
497
  )
497
498
  de_improved = False
498
- print(f"[MXL] DE completed: success={de_result.success}, nit={de_result.nit}, message={de_result.message}")
499
+ if _v: print(f"[MXL] DE completed: success={de_result.success}, nit={de_result.nit}, message={de_result.message}")
499
500
  if de_result.success:
500
501
  de_obj = self.get_loglik_gradient(de_result.x, self.X, self.y, self.panel_info,
501
502
  draws, drawstrans, self.weights,
502
503
  self.avail, self.batch_size)[0]
503
- print(f"[MXL] DE after: obj={de_obj:.6g}")
504
+ if _v: print(f"[MXL] DE after: obj={de_obj:.6g}")
504
505
  de_improved = de_obj < before_de_obj
505
506
  if de_improved:
506
507
  betas = de_result.x
507
- print(f"[MXL] DE best seed first_values={betas[:min(8, len(betas))]!r}")
508
- print("[MXL] Differential evolution initialization improved the objective; starting minimise from DE seed.")
509
- else:
508
+ if _v: print(f"[MXL] DE best seed first_values={betas[:min(8, len(betas))]!r}")
509
+ elif _v:
510
510
  print(f"[MXL] Differential evolution did not beat the original start ({de_obj:.6g} >= {before_de_obj:.6g}); keeping original start.")
511
- if not de_improved:
511
+ if not de_improved and _v:
512
512
  print(f"[MXL] Differential evolution initialization rejected because it did not improve the starting objective. Using original seed.")
513
513
  except Exception as e:
514
- print(f"[MXL] Differential evolution initialization failed: {e}")
514
+ if _v: print(f"[MXL] Differential evolution initialization failed: {e}")
515
515
 
516
516
  # '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
517
517
  if dev.using_gpu: # {
@@ -357,10 +357,33 @@ class DiscreteChoiceModel(ABC):
357
357
  # {
358
358
  if self.method == "bfgs":
359
359
  self.stderr = np.sqrt(np.abs(np.diag(result.hess_inv)))
360
+ std_err_estimated = True
360
361
 
361
362
  if self.method == "l-bfgs-b":
362
363
  hess = result['hess_inv'].todense()
363
364
  self.stderr = np.sqrt(np.abs(np.diag(np.array(hess))))
365
+ std_err_estimated = True
366
+ # }
367
+
368
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
369
+ # Fallback: some models (e.g. MixedLogit with the default
370
+ # "slsqp" method) compute and stash a numerical Hessian inverse
371
+ # directly on the result dict (result['hess_inv']) instead of
372
+ # setting self.Hinv or using scipy's bfgs/l-bfgs-b machinery.
373
+ # The two checks above only recognise "bfgs"/"l-bfgs-b", so without
374
+ # this fallback self.stderr silently stays all-zero for every other
375
+ # method even though a usable Hessian was already computed.
376
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
377
+ if not std_err_estimated and 'hess_inv' in result and result['hess_inv'] is not None:
378
+ # {
379
+ hess_inv = result['hess_inv']
380
+ hess_inv = hess_inv.todense() if hasattr(hess_inv, 'todense') else hess_inv
381
+ diag_arr_tmp = np.diag(np.array(hess_inv))
382
+ pos_vals_idx = [ii for ii, el in enumerate(diag_arr_tmp) if el > 0]
383
+ diag_arr = np.zeros(len(diag_arr_tmp))
384
+ diag_arr[pos_vals_idx] = diag_arr_tmp[pos_vals_idx]
385
+ self.stderr = np.sqrt(np.abs(diag_arr))
386
+ std_err_estimated = not np.isnan(self.stderr).any()
364
387
  # }
365
388
 
366
389
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -42,7 +42,7 @@ class LatentClassMixedLogit:
42
42
  optimise_membership=True,
43
43
  membership_maxiter=50,
44
44
  l1_penalty=0.0,
45
- l2_penalty=0.1,
45
+ l2_penalty=0.5,
46
46
  ):
47
47
  self.n_classes = int(n_classes)
48
48
  self.maxiter = int(maxiter)
@@ -686,7 +686,7 @@ class Parameters:
686
686
 
687
687
  # ── Regularisation (primarily for latent class) ──────────────
688
688
  self.l1_penalty = kwargs.get('l1_penalty', 0.0)
689
- self.l2_penalty = kwargs.get('l2_penalty', 0.1)
689
+ self.l2_penalty = kwargs.get('l2_penalty', 0.5)
690
690
 
691
691
  self.intercept_opts = intercept_opts
692
692
  self.base_alt = base_alt
@@ -0,0 +1 @@
1
+ 0.0.138
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SearchLibrium
3
- Version: 0.0.136
3
+ Version: 0.0.138
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.136