Reputation: 19
I have a series of data points which form a curve I do not have an equation for, and for which i have not been able to satisfyingly calculate an equation with either libreoffice or the online curve fitting tools in the first 2 pages of google results.
I would like the equation for the curve and ideally a python implementation of calculating y values for a given x value along that curve in case there are unexpected hoops to jump through. Failing that I would like any more elegant python solution than a list of elif statements incrementing y if x is high enough for it to increase by a whole number, which is the ugly solution of last resort - my immediate plans do not require decimal precision.
The curve crosses the zero line at 10, and every whole number incrementation of y requires x to be incremented by one more whole number than the previous, so y1 is reached at x11, y2 at x13, y3 at x16 etc, with the curve bending in the other direction in the negatives such that y-1 is at x9, y-2 is at x7 etc. I suspect i am missing something obvious as far as finding the curve equation when i already have this knowledge.
In addition to trying to use libreoffice calc and several online curve-fitting websites to no avail, i have tried slicing the s-curve (I have given up on searching the term sigmoid function as all my results are either related to neural nets or expect my y values to never exceed +-1) into two logarythmic curves, which almost works - 5 *(np.log(x) - 11) gets something frustratingly close to the top half of the curve, but which i ultimately haven't been able to use - in addition to crossing the number line at 9 it produced some odd behaviour when I returned round() rounded y values directly, displaying results in the negative 40s when returned directly, but seeming to work fine when those numbers are fed into other calculations.
If somebody can give me two working logarythms that round to the right numbers for x values between 0 and 50 that is good enough for this project.
Thank you for your time and patience.
-EDIT- these are triangular numbers apparently, x-10 is equal to the number of dots in a triangle with y dots on each side, what I need is the inverse of the triangular number formula. Thank you to everyone who commented.
Upvotes: 0
Views: 1026
Reputation: 19
As mentioned in my edit, the y i am trying to find is the triangular root of x. This solution:
def get_triangle_root(x: int) -> int:
current_value = x - 10
negative = False
if current_value < 0:
current_value = current_value * -1
negative = True
current_value = np.sqrt(1 + (current_value * 8))
current_value = (current_value - 1)/2
if negative == True:
current_value = current_value * -1
current_value = int(current_value)
return current_value
seems to work fine for now. Curiously, when I calculate (-1+(sqrt(1+(8*x)))/2) using libreoffice or google, rather than getting the same results this python script gives me, i get results 0.5 lower than the actual triangle root. Unimportant at this time, but I am curious as to what would cause it.
At any rate, thank you to everyone who lent their time to me. I apologise to anyone looking at this question who was looking for a universal solution for creating S-curves rather than just one that works for my specific task, but feel it is best to attach an answer to this question so as not to prevail on more people's time.
-EDIT- changed python script to handle negative triangular numbers as well, something i had overlooked in excitement.
Upvotes: 1
Reputation: 363
What you're looking for are a class of functions called "Sigmoid functions". They have a characteristic S-shape. Go to Wolfram and play around with some common Sigmoid funcs, remembering that the "a" in a function, f(x-a), shifts the entire curve left or right, and appending a value "b" to the function, f(x-a) + b will shift the curve up and down. Using a coefficient of "c", f(c*x - a) + b here acts as a scalar. That should get you where you want to be in short time.
Example: (1/(1 + C*exp(-(x + A)))) + B
Upvotes: 0