Skip to content

Commit

Permalink
Bump version: 5.5.8 → 5.5.9
Browse files Browse the repository at this point in the history
  • Loading branch information
jpn-- committed Nov 13, 2021
2 parents 2a3efc8 + 911841f commit 40a4abe
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 5 deletions.
2 changes: 1 addition & 1 deletion bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 5.5.8
current_version = 5.5.9
commit = True
tag = True

Expand Down
2 changes: 1 addition & 1 deletion conda-recipe/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package:
name: larch
version: "5.5.8"
version: "5.5.9"

source:
path: ../
Expand Down
2 changes: 1 addition & 1 deletion larch/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

__version__ = '5.5.8'
__version__ = '5.5.9'

from .util.interface_info import Info, ipython_status
import sys
Expand Down
14 changes: 12 additions & 2 deletions larch/dataframes.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ def _infer_name(thing):


def get_dataframe_format(df):
'''Check the format of a dataframe.
"""
Check the format of a dataframe.
This function assumes the input dataframe is in |idco|, |idca|, or
|idce| formats, and returns the format found.
Expand All @@ -319,7 +320,9 @@ def get_dataframe_format(df):
-------
str
one of {'idco', 'idca', 'idce'}
'''
"""
if df is None:
return None
if isinstance(df.index, pandas.MultiIndex) and df.index.nlevels==2:
# The df is idca or idce format
if len(df) < len(df.index.levels[0]) * len(df.index.levels[1]):
Expand Down Expand Up @@ -1566,6 +1569,9 @@ cdef class DataFrames:
caseindex_name = self._caseindex_name or df.index.names[0]
df = df.set_index(df.index.set_names(caseindex_name))

if not df.index.is_monotonic_increasing:
df = df.sort_index()

if self._computational:
self._data_co = _ensure_dataframe_of_dtype(df, l4_float_dtype, 'data_co')
self._array_co = _df_values(self.data_co)
Expand Down Expand Up @@ -1692,6 +1698,8 @@ cdef class DataFrames:

@data_av.setter
def data_av(self, df:pandas.DataFrame):
if df is not None and not df.index.is_monotonic_increasing:
df = df.sort_index()
self._data_av = _ensure_dataframe_of_dtype(df, numpy.int8, 'data_av', warn_on_convert=False)
self._array_av = _df_values(self.data_av, (self.n_cases, self.n_alts))

Expand Down Expand Up @@ -1754,6 +1762,8 @@ cdef class DataFrames:

@data_ch.setter
def data_ch(self, df:pandas.DataFrame):
if df is not None and not df.index.is_monotonic_increasing:
df = df.sort_index()
self._data_ch = _ensure_dataframe_of_dtype(df, l4_float_dtype, 'data_ch')
self._array_ch = _df_values(self.data_ch, (self.n_cases, self.n_alts))

Expand Down
2 changes: 2 additions & 0 deletions larch/model/parameter_frame.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,8 @@ cdef class ParameterFrame:
maximum = numpy.minimum(self.pf.maximum, cap)
self._frame.loc[:,'minimum'] = numpy.where(minimum <= maximum, minimum, self.pf.minimum)
self._frame.loc[:,'maximum'] = numpy.where(minimum <= maximum, maximum, self.pf.maximum)
self._frame.loc[:,'minimum'] = self._frame.loc[:,'minimum'].fillna(-cap)
self._frame.loc[:,'maximum'] = self._frame.loc[:,'maximum'].fillna(cap)
self._check_if_frame_values_changed()

def get_values(self):
Expand Down
84 changes: 84 additions & 0 deletions tests/test_model5.py
Original file line number Diff line number Diff line change
Expand Up @@ -4770,3 +4770,87 @@ def test_model_without_co_data():
m.choice_ca_var = '_choice_'
m.load_data()
assert m.loglike() == approx(-7309.600971749625)

def test_scrambled_data():
mix = lambda x: (x % 10) * 10000 + x
d = MTC()
ca = d.data_ca[['ivtt', 'ovtt', 'totcost', 'chose', 'tottime', ]]
co = d.data_co[['age', 'hhinc', 'hhsize', 'numveh']]
ca = ca.sort_index(level=0, key=mix)
co = co.sort_index(key=mix)
av = d.data_av.sort_index(key=mix)
ch = d.data_ch.sort_index(key=mix)

from larch.dataframes import DataFrames
from larch import Model

dfs = DataFrames(
ca=ca,
co=co,
av=av,
ch=ch,
)

m5 = Model()

# from larch.roles import P, X, PX
from larch.model.linear import ParameterRef_C as P
from larch.model.linear import DataRef_C as X
def PX(i):
return P(i) * X(i)

m5.utility_co[2] = P("ASC_SR2") * X("1") + P("hhinc#2") * X("hhinc")
m5.utility_co[3] = P("ASC_SR3P") * X("1") + P("hhinc#3") * X("hhinc")
m5.utility_co[4] = P("ASC_TRAN") * X("1") + P("hhinc#4") * X("hhinc")
m5.utility_co[5] = P("ASC_BIKE") * X("1") + P("hhinc#5") * X("hhinc")
m5.utility_co[6] = P("ASC_WALK") * X("1") + P("hhinc#6") * X("hhinc")
m5.utility_ca = PX("tottime") + PX("totcost")

m5.dataframes = dfs

beta_in1 = {
'ASC_BIKE': -0.8523646111088327,
'ASC_SR2': -0.5233769323949348,
'ASC_SR3P': -2.3202089848081027,
'ASC_TRAN': -0.05615933557609158,
'ASC_WALK': 0.050082767550586924,
'hhinc#2': -0.001040241396513087,
'hhinc#3': 0.0031822969445656542,
'hhinc#4': -0.0017162484345735326,
'hhinc#5': -0.004071521055900851,
'hhinc#6': -0.0021316332241034445,
'totcost': -0.001336661560553717,
'tottime': -0.01862990704919887,
}

ll2 = m5.loglike2(beta_in1, return_series=True)

q1_dll = {
'ASC_BIKE': -139.43832,
'ASC_SR2': -788.00574,
'ASC_SR3P': -126.84879,
'ASC_TRAN': -357.75186,
'ASC_WALK': -116.137886,
'hhinc#2': -46416.28,
'hhinc#3': -8353.63,
'hhinc#4': -21409.012,
'hhinc#5': -8299.654,
'hhinc#6': -7395.375,
'totcost': 39520.043,
'tottime': -26556.303,
}

assert -4930.3212890625 == approx(ll2.ll)

for k in q1_dll:
assert q1_dll[k] == approx(dict(ll2.dll)[k], rel=1e-5), f"{k} {q1_dll[k]} != {dict(ll2.dll)[k]}"

# Test calculate_parameter_covariance doesn't choke if all holdfasts are on:
m5.lock_values(*beta_in1.keys())
m5.calculate_parameter_covariance()

assert numpy.all(m5.pf['std_err'] == 0)
assert numpy.all(m5.pf['robust_std_err'] == 0)



0 comments on commit 40a4abe

Please sign in to comment.