.NET (22)

Action Script (5)

Agile (1)

Algorithms (5)

Astronomy (1)

C++ (1)

JavaScript (5)

Machine Learning (1)

Robotics (1)

Silverlight (4)

T-SQL (4)

Unity3D (1)

Windows Phone (1)

WPF (2)

XNA (1)

Action Script (5)

Agile (1)

Algorithms (5)

Astronomy (1)

C++ (1)

JavaScript (5)

Machine Learning (1)

Robotics (1)

Silverlight (4)

T-SQL (4)

Unity3D (1)

Windows Phone (1)

WPF (2)

XNA (1)

July 2017 (1)

January 2015 (2)

October 2014 (1)

August 2014 (3)

July 2013 (1)

January 2013 (1)

March 2011 (1)

February 2011 (1)

December 2010 (2)

September 2010 (1)

July 2010 (1)

June 2010 (1)

May 2010 (1)

February 2010 (1)

December 2009 (2)

October 2009 (1)

August 2009 (1)

July 2009 (1)

June 2009 (1)

May 2009 (2)

April 2009 (1)

February 2009 (1)

January 2009 (1)

December 2008 (3)

November 2008 (2)

September 2008 (1)

July 2008 (1)

June 2008 (1)

May 2008 (2)

April 2008 (1)

March 2008 (1)

February 2008 (2)

January 2008 (1)

December 2007 (1)

November 2007 (1)

October 2007 (3)

September 2007 (1)

July 2007 (1)

June 2007 (1)

April 2007 (1)

January 2015 (2)

October 2014 (1)

August 2014 (3)

July 2013 (1)

January 2013 (1)

March 2011 (1)

February 2011 (1)

December 2010 (2)

September 2010 (1)

July 2010 (1)

June 2010 (1)

May 2010 (1)

February 2010 (1)

December 2009 (2)

October 2009 (1)

August 2009 (1)

July 2009 (1)

June 2009 (1)

May 2009 (2)

April 2009 (1)

February 2009 (1)

January 2009 (1)

December 2008 (3)

November 2008 (2)

September 2008 (1)

July 2008 (1)

June 2008 (1)

May 2008 (2)

April 2008 (1)

March 2008 (1)

February 2008 (2)

January 2008 (1)

December 2007 (1)

November 2007 (1)

October 2007 (3)

September 2007 (1)

July 2007 (1)

June 2007 (1)

April 2007 (1)

Posted on 4/20/2009 1:27:57 PM
in #Algorithms
Very often we have a scale of values that can be generalized and described as a real number within the range of 0 and 1, 0 being the lowest value and 1 being the highest. For example if we are building an airplane with highest possible altitude of 5 miles we can represent the current altitude with a number from 0 to 1, in this case 0 will represent the plane on the ground and 1 on it’s highest altitude of 5 miles. This may be useful in many different situations, for example if you show this value to a person or instrument that is not familiar with the specific value but can understand the idea of minimum and maximum of this value. Another useful scenario would be in you want to represent this value in a diagram, arranging it from 0 to 1 makes it easy to plot on a surface of any size. Now we can imagine a situation when we will need to be more sensitive for the value changes near the minimum. For example if we go back to our airplane example. When a plane is taking off very little modification of the altitude may be very important simply because we have more buildings, towers and hills near the ground. But once a highest altitude is reached, 50 feet higher or lower may not be of such a big importance. In this case we may want to plot the altitude of a plane in such a way to make changes near the minimum of 0 more noticeable than changes near the maximum, and of course the transition between those two should be gradual. Now we can think of four general transformations that we can use to alter our 0 to 1 scale. - Make changes near the maximum more noticeable.
- Make changes near the minimum more noticeable.
- Make changes at both extremes more noticeable.
- Make changes at the middle more noticeable.
Now let’s see how do we expect the graphs of those transformations to look: Now we have to come up with a function that describes each of these for equations. - The first one is quite easy as it is quite obviously the part of the parabola between the values of 0 and 1, so the first equation is y = x^2
- The second looks like the same parabola but up side down and moved one point to the right and one to the top. To flip the parabola we can multiply it by negative one like this y = (x^2)*-1. To move it up one point we simply add one or y = (x^2)*-1 + 1 and of course the same can be written as just y = 1 - (x^2). To move it one point to the right we subtract 1 from x before taking the power, or the final formula will be y = 1 – (x – 1)^2
- The third gets a little bit more complicated. It looks like x raised to the third power but a little bit squeezed and moved to the right and up. So we start with y = x ^ 3. Now we have to move it up 0.5 points to get the bending point just between 0 and 1. That looks simple y = x ^ 3 + 0.5. And we do the same just before taking the power in order to move it right, or y = (x – 0.5) ^ 3 + 0.5. To squeeze the graph we have to multiply x ^ 3 by some constant value, let’s call it C, or
**y = C ((x – 0.5) ^ 3 + 0.5)**. We don’t know that value but we know that if x is 1 and y is 1, that value should satisfy the equation, so we deduce this 1 = C (1 – 0.5) ^ 3 + 0.5 1 – 0.5 = C (1 – 0.5) ^ 3 0.5 = C (1 – 0.5) ^ 3 C = 0.5 / (0.5 ^ 3) C = 0.5 / 0.125 C = 4 So at the end our formula is y = 4(x - 0.5) ^ 3 + 0.5 - The fourth graph looks like a reflection of a third graph around the diagonal line y = x. So we have to swap the x and y, or
x = 4(y – 0.5)^3 + 0.5 (x – 0.5) / 4 = (y – 0.5)^3 ((x – 0.5) / 4 ) ^ (1/3) = y – 0.5
**y = ((x – 0.5) / 4 ) ^ (1/3) + 0.5** That technically could be our solution but the problem is that the values of x between 0 and 0.5 will produce negative number and event though cubic root of a negative number shouldn’t be a problem, the windows function for taking a power returns not a number value for any negative number. So to get around this we have to modify our equation as y = sign(x – 0.5)(abs(x – 0.5) / 4 ) ^ (1/3) + 0.5 where sign is a function that returns –1 if the number is negative 0 if it’s 0 and 1 if the number is positive. And here are our graphs with the corresponding equations.
Now let’s write those equations in C# public static double ShiftNearZero(double x){ if(x < 0 || x > 1) throw new ArgumentException("X must be between 0 and 1"); return Math.Pow(x, 2); } public static double ShiftNearOne(double x){ if(x < 0 || x > 1) throw new ArgumentException("X must be between 0 and 1"); return 1 - Math.Pow(x - 1, 2); } public static double ShiftBetweenZeroAndOne(double x){ if(x < 0 || x > 1) throw new ArgumentException("X must be between 0 and 1"); return 4 * Math.Pow(x – 0.5, 3) + 0.5; } public static double ShiftNearZeroAndOne(double x){ if(x < 0 || x > 1) throw new ArgumentException("X must be between 0 and 1"); return Math.Sign(x – 0.5) * Math.Pow(Math.Abs(x – 0.5)/4D, 1/3D) + 0.5; } Another thing we may want to consider is if we want to make those four diagrams even more extreme. Let’s look at the four cases: - y = x^N, where N is any even integer
higher than 2, for example
**y = x ^ 4** - y = (1-(x-1)^N), where N is any even integer
higher than 2, for example
**y = (1-(x-1) ^ 6)** **y = C(x-0.5)^N+0.5**, where N is any odd integer higher than 3, and C is a constant that will squeeze the graph to make it pass through 0,0 and 1,1. We can calculate this constant by replacing y and x with 1, as the graph should pass through point 1,1 1 = C(1-0.5)^N+0.5 1 – 0.5 = C 0.5 ^ N C = 0.5 / 0.5 ^ N So our final formula will be y = (0.5 / 0.5 ^ N)(x-0.5)^N+0.5, where N is any odd integer higher than 3 for example
**y = (0.5 / 0.5 ^ 5)(x-0.5)^5+0.5**- The fourth graph would look like
**y = sign(x – 0.5)(abs(x – 0.5) / C ) ^ (1/3) + 0.5** and when we replace C (we use the same C because this graph is reflection of the previous one) we will end up with y = sign(x – 0.5)(abs((x-0.5)/(0.5/0.5^N))^(1/N))+0.5, for example
**y = sign(x – 0.5)(abs((x-0.5)/(0.5/0.5^7))^(1/7))+0.5**
If on the other hand you need to change the curvature gradually I can recommend another formula. Here it is: In C# that would look like: private static double Transform(double value, double curveture) { return (Math.Pow(value, curveture) + (1 - Math.Pow(1 - value, 1/curveture)))/2; } The value or X is the value of your coefficient that you want to transform. The curvature or N is the value that will determine the direction and degree of the curvature. N must be between 0 and positive infinity. If it is less than 0 the values of X will be shifted closer to 1 of Y. If N is 1 the line will be just a diagonal line, so X will equal Y. If N is more than 1 the values of X will be shifted closer to 0 of Y. Here is an example of that: Share this post: digg Stumble Upon del.icio.us E-mail |

Commenting temporarily disabled