huff 1.5.3__tar.gz → 1.5.4__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.
- {huff-1.5.3 → huff-1.5.4}/PKG-INFO +4 -6
- {huff-1.5.3 → huff-1.5.4}/README.md +3 -5
- {huff-1.5.3 → huff-1.5.4}/huff/models.py +93 -58
- {huff-1.5.3 → huff-1.5.4}/huff/tests/tests_huff.py +2 -2
- {huff-1.5.3 → huff-1.5.4}/huff.egg-info/PKG-INFO +4 -6
- {huff-1.5.3 → huff-1.5.4}/setup.py +1 -1
- {huff-1.5.3 → huff-1.5.4}/MANIFEST.in +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/__init__.py +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/gistools.py +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/ors.py +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/osm.py +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/__init__.py +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach.cpg +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach.dbf +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach.prj +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach.qmd +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach.shp +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach.shx +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_new_supermarket.cpg +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_new_supermarket.dbf +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_new_supermarket.prj +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_new_supermarket.qmd +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_new_supermarket.shp +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_new_supermarket.shx +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_supermarkets.cpg +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_supermarkets.dbf +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_supermarkets.prj +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_supermarkets.qmd +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_supermarkets.shp +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Haslach_supermarkets.shx +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff/tests/data/Wieland2015.xlsx +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff.egg-info/SOURCES.txt +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff.egg-info/dependency_links.txt +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff.egg-info/requires.txt +0 -0
- {huff-1.5.3 → huff-1.5.4}/huff.egg-info/top_level.txt +0 -0
- {huff-1.5.3 → huff-1.5.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: huff
|
3
|
-
Version: 1.5.
|
3
|
+
Version: 1.5.4
|
4
4
|
Summary: huff: Huff Model Market Area Analysis
|
5
5
|
Author: Thomas Wieland
|
6
6
|
Author-email: geowieland@googlemail.com
|
@@ -18,12 +18,10 @@ Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geo
|
|
18
18
|
See the /tests directory for usage examples of most of the included functions.
|
19
19
|
|
20
20
|
|
21
|
-
## Updates v1.5.
|
21
|
+
## Updates v1.5.4
|
22
22
|
- Bugfixes:
|
23
|
-
-
|
24
|
-
-
|
25
|
-
- Confidence intervals (bootstrap) for Huff Model ML estimations
|
26
|
-
- ValueError and KeyError are more precise (function is included)
|
23
|
+
- Use of check_vars() is now optional (default: True)
|
24
|
+
- Correction of args argument when calling minimize() in huff_ml_fit()
|
27
25
|
|
28
26
|
|
29
27
|
## Features
|
@@ -10,12 +10,10 @@ Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geo
|
|
10
10
|
See the /tests directory for usage examples of most of the included functions.
|
11
11
|
|
12
12
|
|
13
|
-
## Updates v1.5.
|
13
|
+
## Updates v1.5.4
|
14
14
|
- Bugfixes:
|
15
|
-
-
|
16
|
-
-
|
17
|
-
- Confidence intervals (bootstrap) for Huff Model ML estimations
|
18
|
-
- ValueError and KeyError are more precise (function is included)
|
15
|
+
- Use of check_vars() is now optional (default: True)
|
16
|
+
- Correction of args argument when calling minimize() in huff_ml_fit()
|
19
17
|
|
20
18
|
|
21
19
|
## Features
|
@@ -4,8 +4,8 @@
|
|
4
4
|
# Author: Thomas Wieland
|
5
5
|
# ORCID: 0000-0001-5168-9846
|
6
6
|
# mail: geowieland@googlemail.com
|
7
|
-
# Version: 1.5.
|
8
|
-
# Last update: 2025-07-
|
7
|
+
# Version: 1.5.4
|
8
|
+
# Last update: 2025-07-18 18:07
|
9
9
|
# Copyright (c) 2025 Thomas Wieland
|
10
10
|
#-----------------------------------------------------------------------
|
11
11
|
|
@@ -766,7 +766,10 @@ class InteractionMatrix:
|
|
766
766
|
self.supply_locations.metadata = supply_locations_metadata
|
767
767
|
self.customer_origins.metadata = customer_origins_metadata
|
768
768
|
|
769
|
-
def utility(
|
769
|
+
def utility(
|
770
|
+
self,
|
771
|
+
check_df_vars: bool = True
|
772
|
+
):
|
770
773
|
|
771
774
|
interaction_matrix_df = self.interaction_matrix_df
|
772
775
|
|
@@ -781,10 +784,11 @@ class InteractionMatrix:
|
|
781
784
|
if interaction_matrix_df["A_j"].isna().all():
|
782
785
|
raise ValueError ("Error in utility calculation: Attraction variable is not defined")
|
783
786
|
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
787
|
+
if check_df_vars:
|
788
|
+
check_vars(
|
789
|
+
df = interaction_matrix_df,
|
790
|
+
cols = ["A_j", "t_ij"]
|
791
|
+
)
|
788
792
|
|
789
793
|
customer_origins = self.customer_origins
|
790
794
|
customer_origins_metadata = customer_origins.get_metadata()
|
@@ -793,9 +797,9 @@ class InteractionMatrix:
|
|
793
797
|
if tc_weighting["func"] == "power":
|
794
798
|
interaction_matrix_df["t_ij_weighted"] = interaction_matrix_df["t_ij"] ** tc_weighting["param"]
|
795
799
|
elif tc_weighting["func"] == "exponential":
|
796
|
-
interaction_matrix_df["t_ij_weighted"] = np.exp(tc_weighting["param"] * interaction_matrix_df[
|
800
|
+
interaction_matrix_df["t_ij_weighted"] = np.exp(tc_weighting["param"] * interaction_matrix_df["t_ij"])
|
797
801
|
elif tc_weighting["func"] == "logistic":
|
798
|
-
interaction_matrix_df["t_ij_weighted"] = 1+np.exp(tc_weighting["param"][0] + tc_weighting["param"][1] * interaction_matrix_df[
|
802
|
+
interaction_matrix_df["t_ij_weighted"] = 1+np.exp(tc_weighting["param"][0] + tc_weighting["param"][1] * interaction_matrix_df["t_ij"])
|
799
803
|
else:
|
800
804
|
raise ValueError ("Error in utility calculation: Transport costs weighting is not defined.")
|
801
805
|
|
@@ -818,8 +822,8 @@ class InteractionMatrix:
|
|
818
822
|
|
819
823
|
for key, attrac_var in enumerate(attrac_vars):
|
820
824
|
|
821
|
-
attrac_var_key = key
|
822
|
-
if attrac_var_key == 0:
|
825
|
+
attrac_var_key = key
|
826
|
+
if attrac_var_key == 0:
|
823
827
|
continue
|
824
828
|
|
825
829
|
name = supply_locations_metadata["weighting"][attrac_var_key]["name"]
|
@@ -850,7 +854,10 @@ class InteractionMatrix:
|
|
850
854
|
|
851
855
|
return self
|
852
856
|
|
853
|
-
def probabilities (
|
857
|
+
def probabilities (
|
858
|
+
self,
|
859
|
+
check_df_vars: bool = True
|
860
|
+
):
|
854
861
|
|
855
862
|
interaction_matrix_df = self.interaction_matrix_df
|
856
863
|
|
@@ -858,6 +865,12 @@ class InteractionMatrix:
|
|
858
865
|
self.utility()
|
859
866
|
interaction_matrix_df = self.interaction_matrix_df
|
860
867
|
|
868
|
+
if check_df_vars:
|
869
|
+
check_vars(
|
870
|
+
df = interaction_matrix_df,
|
871
|
+
cols = ["U_ij"]
|
872
|
+
)
|
873
|
+
|
861
874
|
utility_i = pd.DataFrame(interaction_matrix_df.groupby("i")["U_ij"].sum())
|
862
875
|
utility_i = utility_i.rename(columns = {"U_ij": "U_i"})
|
863
876
|
|
@@ -876,7 +889,10 @@ class InteractionMatrix:
|
|
876
889
|
|
877
890
|
return self
|
878
891
|
|
879
|
-
def flows (
|
892
|
+
def flows (
|
893
|
+
self,
|
894
|
+
check_df_vars: bool = True
|
895
|
+
):
|
880
896
|
|
881
897
|
interaction_matrix_df = self.interaction_matrix_df
|
882
898
|
|
@@ -885,10 +901,11 @@ class InteractionMatrix:
|
|
885
901
|
if interaction_matrix_df["C_i"].isna().all():
|
886
902
|
raise ValueError ("Error in flows calculation: Market size column in customer origins not defined. Use CustomerOrigins.define_marketsize()")
|
887
903
|
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
904
|
+
if check_df_vars:
|
905
|
+
check_vars(
|
906
|
+
df = interaction_matrix_df,
|
907
|
+
cols = ["C_i"]
|
908
|
+
)
|
892
909
|
|
893
910
|
if interaction_matrix_df["p_ij"].isna().all():
|
894
911
|
self.probabilities()
|
@@ -900,15 +917,19 @@ class InteractionMatrix:
|
|
900
917
|
|
901
918
|
return self
|
902
919
|
|
903
|
-
def marketareas(
|
920
|
+
def marketareas(
|
921
|
+
self,
|
922
|
+
check_df_vars: bool = True
|
923
|
+
):
|
904
924
|
|
905
925
|
interaction_matrix_df = self.interaction_matrix_df
|
906
926
|
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
927
|
+
if check_df_vars:
|
928
|
+
check_vars(
|
929
|
+
df = interaction_matrix_df,
|
930
|
+
cols = ["E_ij"],
|
931
|
+
check_zero = False
|
932
|
+
)
|
912
933
|
|
913
934
|
market_areas_df = pd.DataFrame(interaction_matrix_df.groupby("j")["E_ij"].sum())
|
914
935
|
market_areas_df = market_areas_df.reset_index(drop=False)
|
@@ -947,9 +968,9 @@ class InteractionMatrix:
|
|
947
968
|
if tc_weighting["func"] == "power":
|
948
969
|
interaction_matrix_df["t_ij_weighted"] = interaction_matrix_df["t_ij"] ** tc_weighting["param"]
|
949
970
|
elif tc_weighting["func"] == "exponential":
|
950
|
-
interaction_matrix_df["t_ij_weighted"] = np.exp(tc_weighting["param"] * interaction_matrix_df[
|
971
|
+
interaction_matrix_df["t_ij_weighted"] = np.exp(tc_weighting["param"] * interaction_matrix_df["t_ij"])
|
951
972
|
elif tc_weighting["func"] == "logistic":
|
952
|
-
interaction_matrix_df["t_ij_weighted"] = 1+np.exp(tc_weighting["param"][0] + tc_weighting["param"][1] * interaction_matrix_df[
|
973
|
+
interaction_matrix_df["t_ij_weighted"] = 1+np.exp(tc_weighting["param"][0] + tc_weighting["param"][1] * interaction_matrix_df["t_ij"])
|
953
974
|
else:
|
954
975
|
raise ValueError ("Error in hansen accessibility calculation: Transport costs weighting is not defined.")
|
955
976
|
|
@@ -1073,7 +1094,8 @@ class InteractionMatrix:
|
|
1073
1094
|
def loglik(
|
1074
1095
|
self,
|
1075
1096
|
params,
|
1076
|
-
fit_by = "probabilities"
|
1097
|
+
fit_by = "probabilities",
|
1098
|
+
check_df_vars: bool = True
|
1077
1099
|
):
|
1078
1100
|
|
1079
1101
|
if fit_by not in ["probabilities", "flows"]:
|
@@ -1160,9 +1182,9 @@ class InteractionMatrix:
|
|
1160
1182
|
|
1161
1183
|
interaction_matrix_copy = copy.deepcopy(self)
|
1162
1184
|
|
1163
|
-
interaction_matrix_copy.utility()
|
1164
|
-
interaction_matrix_copy.probabilities()
|
1165
|
-
interaction_matrix_copy.flows()
|
1185
|
+
interaction_matrix_copy.utility(check_df_vars = check_df_vars)
|
1186
|
+
interaction_matrix_copy.probabilities(check_df_vars = check_df_vars)
|
1187
|
+
interaction_matrix_copy.flows(check_df_vars = check_df_vars)
|
1166
1188
|
|
1167
1189
|
interaction_matrix_df_copy = interaction_matrix_copy.get_interaction_matrix_df()
|
1168
1190
|
|
@@ -1196,7 +1218,8 @@ class InteractionMatrix:
|
|
1196
1218
|
bounds: list = [(0.5, 1), (-3, -1)],
|
1197
1219
|
constraints: list = [],
|
1198
1220
|
fit_by = "probabilities",
|
1199
|
-
update_estimates: bool = True
|
1221
|
+
update_estimates: bool = True,
|
1222
|
+
check_df_vars: bool = True
|
1200
1223
|
):
|
1201
1224
|
|
1202
1225
|
supply_locations = self.supply_locations
|
@@ -1232,7 +1255,7 @@ class InteractionMatrix:
|
|
1232
1255
|
ml_result = minimize(
|
1233
1256
|
self.loglik,
|
1234
1257
|
initial_params,
|
1235
|
-
args=fit_by,
|
1258
|
+
args=(fit_by, check_df_vars),
|
1236
1259
|
method = method,
|
1237
1260
|
bounds = bounds,
|
1238
1261
|
constraints = constraints,
|
@@ -1745,7 +1768,8 @@ class HuffModel:
|
|
1745
1768
|
|
1746
1769
|
def loglik(
|
1747
1770
|
self,
|
1748
|
-
params
|
1771
|
+
params,
|
1772
|
+
check_df_vars: bool = True
|
1749
1773
|
):
|
1750
1774
|
|
1751
1775
|
if not isinstance(params, list):
|
@@ -1827,9 +1851,9 @@ class HuffModel:
|
|
1827
1851
|
|
1828
1852
|
interaction_matrix_copy = copy.deepcopy(huff_model_copy.interaction_matrix)
|
1829
1853
|
|
1830
|
-
interaction_matrix_copy = interaction_matrix_copy.utility()
|
1831
|
-
interaction_matrix_copy = interaction_matrix_copy.probabilities()
|
1832
|
-
interaction_matrix_copy = interaction_matrix_copy.flows()
|
1854
|
+
interaction_matrix_copy = interaction_matrix_copy.utility(check_df_vars = check_df_vars)
|
1855
|
+
interaction_matrix_copy = interaction_matrix_copy.probabilities(check_df_vars = check_df_vars)
|
1856
|
+
interaction_matrix_copy = interaction_matrix_copy.flows(check_df_vars = check_df_vars)
|
1833
1857
|
|
1834
1858
|
huff_model_copy = interaction_matrix_copy.marketareas()
|
1835
1859
|
|
@@ -1855,7 +1879,8 @@ class HuffModel:
|
|
1855
1879
|
constraints: list = [],
|
1856
1880
|
fit_by = "probabilities",
|
1857
1881
|
update_estimates: bool = True,
|
1858
|
-
check_numbers: bool = True
|
1882
|
+
check_numbers: bool = True,
|
1883
|
+
check_df_vars: bool = True
|
1859
1884
|
):
|
1860
1885
|
|
1861
1886
|
if fit_by in ["probabilities", "flows"]:
|
@@ -1866,7 +1891,8 @@ class HuffModel:
|
|
1866
1891
|
bounds = bounds,
|
1867
1892
|
constraints = constraints,
|
1868
1893
|
fit_by = fit_by,
|
1869
|
-
update_estimates = update_estimates
|
1894
|
+
update_estimates = update_estimates,
|
1895
|
+
check_df_vars = check_df_vars
|
1870
1896
|
)
|
1871
1897
|
|
1872
1898
|
elif fit_by == "totals":
|
@@ -1914,6 +1940,7 @@ class HuffModel:
|
|
1914
1940
|
ml_result = minimize(
|
1915
1941
|
self.loglik,
|
1916
1942
|
initial_params,
|
1943
|
+
args=check_df_vars,
|
1917
1944
|
method = method,
|
1918
1945
|
bounds = bounds,
|
1919
1946
|
constraints = constraints,
|
@@ -1999,11 +2026,11 @@ class HuffModel:
|
|
1999
2026
|
|
2000
2027
|
else:
|
2001
2028
|
|
2002
|
-
self.interaction_matrix.utility()
|
2003
|
-
self.interaction_matrix.probabilities()
|
2004
|
-
self.interaction_matrix.flows()
|
2029
|
+
self.interaction_matrix.utility(check_df_vars = check_df_vars)
|
2030
|
+
self.interaction_matrix.probabilities(check_df_vars = check_df_vars)
|
2031
|
+
self.interaction_matrix.flows(check_df_vars = check_df_vars)
|
2005
2032
|
|
2006
|
-
huff_model_new_marketareas = self.interaction_matrix.marketareas()
|
2033
|
+
huff_model_new_marketareas = self.interaction_matrix.marketareas(check_df_vars = check_df_vars)
|
2007
2034
|
self.market_areas_df["T_j"] = huff_model_new_marketareas.get_market_areas_df()["T_j"]
|
2008
2035
|
|
2009
2036
|
self.interaction_matrix.metadata["fit"] = {
|
@@ -2372,7 +2399,8 @@ class MCIModel:
|
|
2372
2399
|
|
2373
2400
|
def utility(
|
2374
2401
|
self,
|
2375
|
-
transformation = "LCT"
|
2402
|
+
transformation = "LCT",
|
2403
|
+
check_df_vars: bool = True
|
2376
2404
|
):
|
2377
2405
|
|
2378
2406
|
interaction_matrix = self.interaction_matrix
|
@@ -2384,10 +2412,11 @@ class MCIModel:
|
|
2384
2412
|
if interaction_matrix_df["A_j"].isna().all():
|
2385
2413
|
raise ValueError ("Error in utility calculation: Attraction variable is not defined")
|
2386
2414
|
|
2387
|
-
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2415
|
+
if check_df_vars:
|
2416
|
+
check_vars(
|
2417
|
+
df = interaction_matrix_df,
|
2418
|
+
cols = ["A_j", "t_ij"]
|
2419
|
+
)
|
2391
2420
|
|
2392
2421
|
customer_origins = interaction_matrix.get_customer_origins()
|
2393
2422
|
customer_origins_metadata = customer_origins.get_metadata()
|
@@ -2476,7 +2505,8 @@ class MCIModel:
|
|
2476
2505
|
|
2477
2506
|
def flows (
|
2478
2507
|
self,
|
2479
|
-
transformation = "LCT"
|
2508
|
+
transformation = "LCT",
|
2509
|
+
check_df_vars: bool = True
|
2480
2510
|
):
|
2481
2511
|
|
2482
2512
|
interaction_matrix = self.interaction_matrix
|
@@ -2488,10 +2518,11 @@ class MCIModel:
|
|
2488
2518
|
if interaction_matrix_df["C_i"].isna().all():
|
2489
2519
|
raise ValueError ("Error in flows calculation: Market size column in customer origins not defined. Use CustomerOrigins.define_marketsize()")
|
2490
2520
|
|
2491
|
-
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2521
|
+
if check_df_vars:
|
2522
|
+
check_vars(
|
2523
|
+
df = interaction_matrix_df,
|
2524
|
+
cols = ["C_i"]
|
2525
|
+
)
|
2495
2526
|
|
2496
2527
|
if interaction_matrix_df["p_ij"].isna().all():
|
2497
2528
|
self.probabilities(transformation=transformation)
|
@@ -2504,15 +2535,19 @@ class MCIModel:
|
|
2504
2535
|
|
2505
2536
|
return self
|
2506
2537
|
|
2507
|
-
def marketareas (
|
2538
|
+
def marketareas (
|
2539
|
+
self,
|
2540
|
+
check_df_vars: bool = True
|
2541
|
+
):
|
2508
2542
|
|
2509
2543
|
interaction_matrix = self.interaction_matrix
|
2510
2544
|
interaction_matrix_df = interaction_matrix.get_interaction_matrix_df()
|
2511
2545
|
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2515
|
-
|
2546
|
+
if check_df_vars:
|
2547
|
+
check_vars(
|
2548
|
+
df = interaction_matrix_df,
|
2549
|
+
cols = ["E_ij"]
|
2550
|
+
)
|
2516
2551
|
|
2517
2552
|
market_areas_df = pd.DataFrame(interaction_matrix_df.groupby("j")["E_ij"].sum())
|
2518
2553
|
market_areas_df = market_areas_df.reset_index(drop=False)
|
@@ -2735,7 +2770,7 @@ def load_interaction_matrix(
|
|
2735
2770
|
xlsx_sheet: str = None,
|
2736
2771
|
crs_input = "EPSG:4326",
|
2737
2772
|
crs_output = "EPSG:4326",
|
2738
|
-
check_df_vars = True
|
2773
|
+
check_df_vars: bool = True
|
2739
2774
|
):
|
2740
2775
|
|
2741
2776
|
if isinstance(data, pd.DataFrame):
|
@@ -2976,7 +3011,7 @@ def load_marketareas(
|
|
2976
3011
|
csv_decimal = ",",
|
2977
3012
|
csv_encoding="unicode_escape",
|
2978
3013
|
xlsx_sheet: str = None,
|
2979
|
-
check_df_vars = True
|
3014
|
+
check_df_vars: bool = True
|
2980
3015
|
):
|
2981
3016
|
|
2982
3017
|
if isinstance(data, pd.DataFrame):
|
@@ -4,8 +4,8 @@
|
|
4
4
|
# Author: Thomas Wieland
|
5
5
|
# ORCID: 0000-0001-5168-9846
|
6
6
|
# mail: geowieland@googlemail.com
|
7
|
-
# Version: 1.5.
|
8
|
-
# Last update: 2025-07-
|
7
|
+
# Version: 1.5.4
|
8
|
+
# Last update: 2025-07-18 18:06
|
9
9
|
# Copyright (c) 2025 Thomas Wieland
|
10
10
|
#-----------------------------------------------------------------------
|
11
11
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: huff
|
3
|
-
Version: 1.5.
|
3
|
+
Version: 1.5.4
|
4
4
|
Summary: huff: Huff Model Market Area Analysis
|
5
5
|
Author: Thomas Wieland
|
6
6
|
Author-email: geowieland@googlemail.com
|
@@ -18,12 +18,10 @@ Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geo
|
|
18
18
|
See the /tests directory for usage examples of most of the included functions.
|
19
19
|
|
20
20
|
|
21
|
-
## Updates v1.5.
|
21
|
+
## Updates v1.5.4
|
22
22
|
- Bugfixes:
|
23
|
-
-
|
24
|
-
-
|
25
|
-
- Confidence intervals (bootstrap) for Huff Model ML estimations
|
26
|
-
- ValueError and KeyError are more precise (function is included)
|
23
|
+
- Use of check_vars() is now optional (default: True)
|
24
|
+
- Correction of args argument when calling minimize() in huff_ml_fit()
|
27
25
|
|
28
26
|
|
29
27
|
## Features
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|