I have a vector of 64 elements between [0, 1]. Those elements represent weights in a model. I would like to define the value t as the 16th maximum weight (75th percentile) and then push the weights above towards 1 and the weights below towards 0. The goal is to increase the separation, the distinction between 'high' weights and 'low' weights. Defining t is not an issue, but I do not know which transformation I could apply to achieve my goal.

I am also interested in a more general solution where the input vector elements are between [a, b] and where you can control the 'rate' at which elements are pushed towards one side or the other.

At first, I thought using logarithmic scaling would help, but it only pushes every value from [0, 1] towards 1 or towards 0 depending on the implementation. The formula for the log scaling was given to me by user1337:

$$x \mapsto \frac{\ln \left(\frac{a \theta -b}{a-b}+\frac{(1-\theta ) x}{a-b}\right)}{ \ln (\theta) }. $$


An imperfect idea, but you tagged python, so perhaps you can make it work for your purpose:

$$f(x) = a+(b-a)\frac{\left(\frac{x-a}{b-a}\right)^{cd}}{ \left(\frac{x-a}{b-a}\right)^{cd} + \left(1- \left(\frac{x-a}{b-a}\right)^c \right)^d }$$

S-curve Positives:

  • $f$ maps $[a,b]$ to $[a,b]$ with $f(a)=a$ and $f(b)=b$ (exactly).
  • $d$ allows to tune the "strength".


  • $c$ is fiendishly complex to calculate as a function of $d$ and what you called $t$. So this is only useful if you can approximate $c$ numerically by looking for the $c$ that minimizes $\vert f(t)-t \vert$.
  • $\begingroup$ Thank you for your reply and the graphs make it very clear. However, I don't really understand what c is. Especially as you refer to theta which in my example above with the log was simply used to change the log used (base 2, ln, base 10, ...). The example log transformation I gave above was not suited to my case anyway and is thus not used. $\endgroup$ – Mathieu Feb 10 at 15:00
  • $\begingroup$ I just noticed that my post was not clear as I named 2 different variables both x. I rename the first to t, the threshold within [a,b] above which values are pushed to b and below which values are pushed to a. The x in the MathJax expression below was simply to give an example of a transformation which pushes in only one direction all the values from [a,b]. $\endgroup$ – Mathieu Feb 10 at 15:22
  • $\begingroup$ Let's keep $[a,b] = [0,1]$. In that case $c=1$ will give you a crossing of $y=x$ at $0.5$ exactly, a value $c>1$ will make that crossing happen at some $x>0.5$. As I understand you need the crossing of $y=x$ at a precise point $t$ (I just noticed that you renamed it in the question). Then $c$ is a function of $d$ and $t$ and very difficult to derive in closed form (if at all possible). I'll edit the answer to reflect your changes. $\endgroup$ – user3733558 Feb 10 at 15:27
  • 1
    $\begingroup$ That was very clear! The parameter defining the crossing point t is c and it is difficult to get an analytical expression linking c to t for a given d (strength). $\endgroup$ – Mathieu Feb 10 at 15:30
  • $\begingroup$ Yes, exactly. By the way, $d>1$ gives you a "pusher", $0<d<1$ will give you a "puller", if you ever need one. $\endgroup$ – user3733558 Feb 10 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.