Skip to content

Commit 0e241a4

Browse files
author
tommyod
committed
Test for statistical properties of all distrs
1 parent afc149b commit 0e241a4

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

tests/fmudesign/test_create_design.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,151 @@
1818
TESTDATA = Path(__file__).parent / "data"
1919

2020

21+
def test_distribution_statistis(tmpdir, monkeypatch):
22+
"""This test ensures that if any large-sample statistics for any distribution
23+
changes, we will likely pick it up in the future."""
24+
25+
NUM_SAMPLES = 10**5
26+
27+
def gl(paramname, distname, p1, p2, p3="", p4=""):
28+
"""GL = Generate Line. Generates a line in the input sheet."""
29+
return [
30+
"",
31+
"",
32+
"",
33+
paramname,
34+
"",
35+
"",
36+
"",
37+
"",
38+
distname,
39+
p1,
40+
p2,
41+
p3,
42+
p4,
43+
"",
44+
"",
45+
"",
46+
]
47+
48+
# General input sheet
49+
general_input = pd.DataFrame(
50+
data=[
51+
["designtype", "onebyone"],
52+
["repeats", 1],
53+
["rms_seeds", "default"],
54+
["background", "None"],
55+
["distribution_seed", "None"],
56+
]
57+
)
58+
59+
# Design input sheet
60+
design_input = pd.DataFrame(
61+
data=[
62+
# Normal has params (mean, std, low=-inf, high=inf)
63+
gl("NORMAL", "normal", 0, 2),
64+
gl("TRUNCNORM", "normal", 0, 1, -1, 2),
65+
# Lognormal has params (mean, sigma)
66+
gl("LOGNORMAL", "logn", 1.5, 0.5),
67+
# Uniform has params (low, high)
68+
gl("UNIFORM", "unif", -5, 0),
69+
# Triangular has params (low, mode, high)
70+
gl("TRIANG", "triang", -5, 0, 5),
71+
# Pert has has params (low, mode, high, scale=4)
72+
gl("DEFAULTPERT", "pert", -5, 0, 5),
73+
gl("SCALEPERT", "pert", -5, 0, 5, 1),
74+
# Loguniform has params (low, high)
75+
gl("LOGUNIFORM", "logunif", 1, 5),
76+
],
77+
columns=[
78+
"sensname",
79+
"numreal",
80+
"type",
81+
"param_name",
82+
"senscase1",
83+
"value1",
84+
"senscase2",
85+
"value2",
86+
"dist_name",
87+
"dist_param1",
88+
"dist_param2",
89+
"dist_param3",
90+
"dist_param4",
91+
"decimals",
92+
"corr_sheet",
93+
"extern_file",
94+
],
95+
)
96+
design_input.iloc[0, :3] = ["distr_test", (NUM_SAMPLES), "dist"]
97+
98+
# Default values sheet
99+
defaultvalues = pd.DataFrame(
100+
{
101+
"param_name": list(design_input["param_name"]),
102+
"default_value": [0.5] * (len(design_input)),
103+
}
104+
)
105+
106+
# Create a file to do the save => load roundtrip and test that too
107+
FILENAME = "designinput.xlsx"
108+
with pd.ExcelWriter(FILENAME, engine="openpyxl") as writer:
109+
general_input.to_excel(
110+
writer, sheet_name="general_input", index=False, header=None
111+
)
112+
design_input.to_excel(writer, sheet_name="designinput", index=False)
113+
defaultvalues.to_excel(
114+
writer, sheet_name="defaultvalues", index=False
115+
) # Write columns
116+
117+
# Read the file and draw samples
118+
input_dict = excel2dict_design(FILENAME)
119+
design = DesignMatrix()
120+
design.generate(input_dict)
121+
assert len(design.designvalues) == NUM_SAMPLES
122+
df = design.designvalues
123+
124+
# Test statistical properties and boundaries of all variables.
125+
# There were either derived using analytical properties, or empirically
126+
# by drawing 10 million samples.
127+
# Tolerance must be high enough to not pick up on rng differences, but low
128+
# enough to pick up meaningful changes.
129+
atol = 0.005
130+
131+
assert np.isclose(df["NORMAL"].mean(), 0.0, atol=atol)
132+
assert np.isclose(df["NORMAL"].std(), 2.0, atol=atol)
133+
134+
assert np.isclose(df["TRUNCNORM"].mean(), 0.229637, atol=atol)
135+
assert np.isclose(df["TRUNCNORM"].std(), 0.720945, atol=atol)
136+
assert df["TRUNCNORM"].min() >= -1
137+
assert df["TRUNCNORM"].max() <= 2
138+
139+
assert np.isclose(df["LOGNORMAL"].mean(), 5.078418, atol=atol)
140+
assert np.isclose(df["LOGNORMAL"].std(), 2.706487, atol=atol)
141+
142+
assert df["UNIFORM"].min() >= -5
143+
assert df["UNIFORM"].max() <= 0
144+
assert np.isclose(df["UNIFORM"].mean(), -2.5, atol=atol)
145+
assert np.isclose(df["UNIFORM"].std(), 1.443375, atol=atol)
146+
147+
assert df["TRIANG"].min() >= -5
148+
assert df["TRIANG"].max() <= 5
149+
assert np.isclose(df["TRIANG"].mean(), 0, atol=atol)
150+
assert np.isclose(df["TRIANG"].std(), 2.041241, atol=atol)
151+
152+
assert df["DEFAULTPERT"].min() >= -5
153+
assert df["DEFAULTPERT"].max() <= 5
154+
assert np.isclose(df["DEFAULTPERT"].mean(), 0, atol=atol)
155+
assert np.isclose(df["DEFAULTPERT"].std(), 1.889822, atol=atol)
156+
157+
assert df["SCALEPERT"].min() >= -5
158+
assert df["SCALEPERT"].max() <= 5
159+
assert np.isclose(df["SCALEPERT"].mean(), 0, atol=atol)
160+
assert np.isclose(df["SCALEPERT"].std(), 2.5, atol=atol)
161+
162+
assert np.isclose(df["LOGUNIFORM"].mean(), 2.485339, atol=atol)
163+
assert np.isclose(df["LOGUNIFORM"].std(), 1.130975, atol=atol)
164+
165+
21166
def test_generate_onebyone(tmpdir):
22167
"""Test generation of onebyone design"""
23168

0 commit comments

Comments
 (0)