Skip to content

Instantly share code, notes, and snippets.

@Xorgon
Created June 27, 2017 00:09
Show Gist options
  • Save Xorgon/afc4d3e58e141449ddb4b40edfe12edb to your computer and use it in GitHub Desktop.
Save Xorgon/afc4d3e58e141449ddb4b40edfe12edb to your computer and use it in GitHub Desktop.
Calculates coefficients for an equation to redistribute a random distribution between 0 and 1.
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 26 21:05:22 2017
@author: Xorgon
"""
import numpy as np
import scipy.optimize as opt
import matplotlib.pyplot as plt
import warnings
def func(x, a, b, c, d):
return - np.log(a/(x+b) - 1)/c + d
def calculate(f, y75=0.58, p0=[1.025, 0.0125, 9.19, 0.5],
eqn_string="- Math.log(%f/(x+%f) - 1)/%f + %f"):
"""
Calculates coefficients for an equation to redistribute a random
distribution between 0 and 1.
Defaults are all set to be usable for the example function 'func' provided.
Arguments:
f -- a function with parameters (x, a, b, c, d) where x is the independant
variable and a, b, c, and d are coefficients to be determined. This
should map from x in range 0 to 1, to y in range 0 to 1.
Keyword arguments:
y75 -- The value of the function for an x value of 0.75.
p0 -- The initial guess at parameters, this can be quite sensitive so
attempting to approximate this using a graphing calculator may be
necessary, e.g. desmos.com/calculator.
eqn_string -- A string of the equation with formatting characters to be
replaced by a, b, c, and d (in that order).
Returns:
a, b, c, d -- Coefficients for the equation.
"""
xdata = [0.0, 0.5, 0.75, 1.0]
ydata = [0.001, 0.5, y75, 0.999]
warnings.filterwarnings("ignore") # Remove annoying messages.
result = opt.curve_fit(f, xdata, ydata, p0=p0, maxfev=int(1e4))
warnings.filterwarnings("default") # Warnings might be needed elsewhere.
a, b, c, d = result[0]
print("a = %f, b = %f, c = %f, d = %f" % (a, b, c, d))
xs = []
ys = []
for i in range(0, 998):
xs.append((i + 1)/1000)
ys.append(func((i+1)/1000, a, b, c, d))
plt.plot(xs, ys)
plt.xlabel("Random between 0 and 1", fontsize=10)
plt.ylabel("Redistributed random between 0 and 1", fontsize=10)
print("Copy-pastable formula for Java:")
print(eqn_string % (a, b, c, d))
return a, b, c, d
calculate(func)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment