Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change continuous distributions to the standard #3214

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

alkino
Copy link
Member

@alkino alkino commented Nov 15, 2024

This PR is here only for continuous:

  • Erlang
  • LogNorm
  • NegExp
  • Normal
  • Uniform
  • Weibull

And unused RndInt is removed.

Here are the data fitted from generated values:

Computation for erlang
KS test 2 samples between old and new
D+=0.004010000000000069, pvalue=0.39631978335488516
KS test 1 sample from old compare to erlang
D+=0.0031418021567620746, pvalue=0.276430366443688
KS test 1 sample from new compare to erlang
D-=0.002751544140646378, pvalue=0.4345156017759174
Fitted old parameters: scale=0.19863874531376705, loc=0, shape=25.14951030822438
Fitted new parameters: scale=0.19932706758506916, loc=0, shape=25.084590186091052
Generating graph...
Over
Computation for lognormal
KS test 2 samples between old and new
D-=0.003009999999999957, pvalue=0.7542898827264349
KS test 1 sample from old compare to lognormal
D+=0.002427843285461251, pvalue=0.5965032909797967
KS test 1 sample from new compare to lognormal
D+=0.0020800761643524623, pvalue=0.7790396649659992
Fitted old parameters: scale=4.8107488739015505, loc=0, shape=0.27763652287355006
Fitted new parameters: scale=4.8093393378099965, loc=0, shape=0.27719507894268125
Generating graph...
Over
Computation for negexp
KS test 2 samples between old and new
D+=0.0036800000000000166, pvalue=0.5062384732899003
KS test 1 sample from old compare to negexp
D+=0.0020296113974088703, pvalue=0.8037645864920905
KS test 1 sample from new compare to negexp
D-=0.002424694125399307, pvalue=0.59816710647604
Fitted old parameters: scale=0.49909674561988776 loc=0.0
Fitted new parameters: scale=0.5008447172512056 loc=0.0
Generating graph...
Over
Computation for normal
KS test 2 samples between old and new
D-=0.0029100000000000237, pvalue=0.7897805451846037
KS test 1 sample from old compare to normal
D-=0.00281200953901356, pvalue=0.40702052300307534
KS test 1 sample from new compare to normal
D-=0.0017727679702720378, pvalue=0.9112110607462915
Fitted old parameters: scale=1.2221744797869214 loc=0
Fitted new parameters: scale=1.2239901661534476 loc=0
Generating graph...
Over
Computation for uniform
KS test 2 samples between old and new
D-=0.0031800000000000717, pvalue=0.6914901624020462
KS test 1 sample from old compare to uniform
D-=0.0027674800981284386, pvalue=0.4271693341284927
KS test 1 sample from new compare to uniform
D-=0.0019578226969142187, pvalue=0.837253161799323
Fitted old parameters: scale=1.9999930942431108 loc=0.0
Fitted new parameters: scale=1.9999915751979327 loc=0.0
Generating graph...
Over
Computation for weibull
KS test 2 samples between old and new
D+=0.0033000000000000806, pvalue=0.6463026318994153
KS test 1 sample from old compare to weibull
D+=0.002500678223098629, pvalue=0.5583433920723122
KS test 1 sample from new compare to weibull
D+=0.0023796913000540543, pvalue=0.6220334366616607
Fitted old parameters: scale=1.084233483717604, loc=0, shape=5.014049611015011
Fitted new parameters: scale=1.084682178649993, loc=0, shape=4.9812025045890795
Generating graph...
Over

erlang_comparison
lognormal_comparison
negexp_comparison
normal_comparison
uniform_comparison
weibull_comparison

Scripts to draw graph and do statistics:

import pickle
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import os.path
from math import pow, sqrt, log, exp

stats_name = {
        'erlang': {'fun': stats.erlang, 'args': [25, 0, 1/5]},
        'lognormal': {'fun': stats.lognorm, 'args': [sqrt(log(2/(5*5) + 1)), 0, 5*5/sqrt(2+5*5)]},
        'negexp': {'fun': stats.expon, 'args': [0, 0.5]},
        'normal': {'fun': stats.norm, 'args': [-1, sqrt(.5)]},
        'uniform': {'fun': stats.uniform, 'args': [0, 2]},
        'weibull': {'fun': stats.weibull_min, 'args': [5, 0, pow(1.5, 1/5)]},
        }
def plot(name):
    print(f"Computation for {name}")
    with open(f'old/{name}.data', 'rb') as f:
        old_data = pickle.load(f)
    with open(f'new/{name}.data', 'rb') as f:
        new_data = pickle.load(f)

    if name in stats_name:
        fun = stats_name[name]["fun"]
        args = stats_name[name]["args"]
        print("KS test 2 samples from old to new")
        res = stats.ks_2samp(old_data, new_data)
        print(f"D{'-' if res.statistic_sign == -1 else '+'}={res.statistic}, pvalue={res.pvalue}")
        print(f"KS test 1 sample from old compare to {name}")
        res = stats.ks_1samp(x=old_data, cdf=fun.cdf, args=args)
        print(f"D{'-' if res.statistic_sign == -1 else '+'}={res.statistic}, pvalue={res.pvalue}")
        print(f"KS test 1 sample from new compare to {name}")
        res = stats.ks_1samp(x=new_data, cdf=fun.cdf, args=args)
        print(f"D{'-' if res.statistic_sign == -1 else '+'}={res.statistic}, pvalue={res.pvalue}")
        if name == 'negexp' or name == 'normal' or name == 'uniform':
            old_loc, old_scale = fun.fit(old_data, floc=0)  # floc=0 fixes the location at 0, as lognormal is defined on (0, inf)
            new_loc, new_scale = fun.fit(new_data, floc=0)  # floc=0 fixes the location at 0, as lognormal is defined on (0, inf)

            print(f"Fitted old parameters: scale={old_scale} loc={old_loc}")
            print(f"Fitted new parameters: scale={new_scale} loc={new_loc}")
        else:
            old_shape, old_loc, old_scale = fun.fit(old_data, floc=0)  # floc=0 fixes the location at 0, as lognormal is defined on (0, inf)
            new_shape, new_loc, new_scale = fun.fit(new_data, floc=0)  # floc=0 fixes the location at 0, as lognormal is defined on (0, inf)

            print(f"Fitted old parameters: scale={old_scale}, loc={old_loc}, shape={old_shape}")
            print(f"Fitted new parameters: scale={new_scale}, loc={new_loc}, shape={new_shape}")

        NUM_BINS = 2000  # Increase this number for smaller bins
    else:
        NUM_BINS = 'auto'

    print("Generating graph...")
    plt.hist(old_data, bins=NUM_BINS, density=True, alpha=0.6, color='b')
    plt.hist(new_data, bins=NUM_BINS, density=True, alpha=0.6, color='g')
    plt.title(f"Histogram of Data and Fitted {name} Distribution")
    plt.savefig(f"{name}_comparison.png")
    plt.clf()
    print("Over")

if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1:
        plot(sys.argv[1])
    else:
        for n in stats_name.keys():
            if os.path.isfile(os.path.join("old", f"{n}.data")) and os.path.isfile(os.path.join("new", f"{n}.data")):
                plot(n)
from neuron import h
import pickle

r = h.Random()

nrun = int(1e6)

def generate_data(name, *args):
    fun = getattr(r, name)
    fun(*args)
    hist = []
    for i in range(nrun):
        j = r.repick()
        hist.append(j)
    with open(f"{name}.data", "wb") as h:
        pickle.dump(hist, h)

# Discrete
# generate_data("binomial", 20, .5)
# generate_data("discunif", 0, 10)
# generate_data("poisson", 3)

# Continuous
generate_data("negexp", 0.5)
generate_data("normal", -1, .5)
generate_data("lognormal", 5, 2) # mean = 5, variance = 2
generate_data("uniform", 0, 2)
generate_data("erlang", 5, 1)
generate_data("weibull", 5, 1.5)

# Not implemented
# generate_data("geometric", .8)
# generate_data("hypergeo", 10, 150)

@bbpbuildbot

This comment has been minimized.

Copy link

sonarcloud bot commented Nov 15, 2024

[0.0, 0.00046940111168614074, 0.004571699024450762, 0.01086603263672303]
[0.0, 0.006769657533393409, 0.01017024899523811, 0.016085586243023933]
Copy link
Member Author

@alkino alkino Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need the review of @nrnhines on that

Copy link

✔️ f9e61d7 -> Azure artifacts URL

Copy link

✔️ c361243 -> Azure artifacts URL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants