step function that increases gait with X - math

I feel like a moron for not seeing how to express this.
I have need of a step function that approximates a linear function, with frequent, small steps near 0 and fewer, larger steps as X grows, approach some nominal max gait.
e.g.
/ |
/ |
/____| +5
/|
/ |
/ |
/ |
/____| +5
/|
/ |
/ |
/ |
/____| +5
/|
/ |
/ |
/___| +4
/|
/ |
/__| +3
/|
/_| +2
/| +1

I assume you want a function whose graph is the horizontal lines in your example.
If you check the graph's corners that lie on the line, you see that the x-coordinates (as well as the y-coordinates) are the triangular numbers 0, 1, 3, 6, 10, 15, ... They are the partial sums of the arithmetic series 0 + 1 + 2 + 3 + 4 + 5 + ...
It is well known that the formula for the nth triangular number is
x = n*(n+1)/2
That is a quadratic equation in n. If we solve that equation for n and take the positive root we get
n = (-1 + sqrt(8*x + 1)) / 2
So given any point on one of your horizontal line segments, we can find which segment it is by taking the integer part (floor) of that expression. We then use our original expression to find the appropriate y value for that segment. Thus our final expression, slightly simplified, is
0.5 * int((-1 + sqrt(8*x + 1))/2) * int((1 + sqrt(8*x + 1))/2)
Note that the above expression is undefined for x < -1/8 and is zero for -1/8 <= x < 0. To avoid those, only graph for x >= 0. That is an expression in one line. In a computer program there are some obvious efficiencies that could be made, such as calculating n = int((-1 + sqrt(8*x + 1))/2) before using the function value 0.5 * n * (n + 1). You could also avoid the negative x values.
Here is the resulting graph (unfortunately leaving in the values for -1/8 <= x < 0), with dashed vertical and diagonal lines added for clarity.

Related

Avoiding bias in randomly generated subtraction problems

I'm writing a Python script to generate problems for mental arithmetic drills. The addition and multiplication ones were easy, but I'm running into trouble trying to generate unbiased problems for the subtraction ones.
I want to be able to specify a minimum and maximum value that the minuend (first number) will be -- e.g., for two-digit subtraction it should be between 20 and 99. The subtrahend should also have a range option (11-99, say). The answer needs to be positive and preferably also bounded by a minimum of, say, 10 for this situation.
So:
20 < Minuend < 99
11 < Subtrahend < 99
Answer = Minuend - Subtrahend
Answer >= 10
All the numeric values should be used as variables, of course.
I have these conditions met as follows:
ansMin, ansMax = 10, 99
subtrahendMin, minuendMax = 11,99
# the other max and min did not seem to be necessary here,
# and two ranges was the way I had the program set up
answer = randint(ansMin, ansMax)
subtrahend = randint(subtrahendMin, minuendMax - answer)
minuend = answer + subtrahend # rearranged subtraction equation
The problem here is that the minuend values wind up being nearly all over 50 because the answer and subtrahend were generated first and added together, and only the section of them that were both in the bottom 25% of the range will get the result below 50%. (Edit: that's not strictly true -- for instance, bottom 1% plus bottom 49% would work, and percentages are a bad way of describing it anyway, but I think the idea is clear.)
I also considered trying generating the minuend and subtrahend values both entirely randomly, then throwing out the answer if it didn't match the criteria (namely, that the minuend be greater than the subtrahend by a value at least greater than the answerMin and that they both be within the criteria listed above), but I figured that would result in a similar bias.
I don't care about it being perfectly even, but this is too far off. I'd like the minuend values to be fully random across the allowable range, and the subtrahend values random across the range allowed by the minuends (if I'm thinking about it right, this will be biased in favor of lower ones). I don't think I really care about the distribution of the answers (as long as it's not ridiculously biased). Is there a better way to calculate this?
There are several ways of defining what "not biased" means in this case. I assume that what you are looking for is that every possible subtraction problem from the allowed problem space is chosen with equal probability. Quick and dirty approach:
Pick random x in [x_min, x_max]
Pick random y in [y_min, y_max]
If x - y < answer_min, discard both x and y and start over.
Note the bold part. If you discard only y and keep the x, your problems will have an uniform distribution in x, not in the entire problem space. You need to ensure that for every valid x there is at least one valid y - this is not the case for your original choice of ranges, as we'll see later.
Now the long, proper approach. First we need to find out the actual size of the problem space.
The allowed set of subtrahends is determined by the minuend:
x in [21, 99]
y in [11, x-10]
or using symbolic constants:
x in [x_min, x_max]
y in [y_min, x - answer_min]
We can rewrite that as
x in [21, 99]
y = 11 + a
a in [0, x-21]
or again using symbolic constants
x in [x_min, x_max]
y = y_min + a
a in [0, x - (answer_min + y_min)].
From this, we see that valid problems exist only for x >= (answer_min + y_min), and for a given x there are x - (answer_min + y_min) + 1 possible subtrahents.
Now we assume that x_max does not impose any further constraints, e.g. that answer_min + y_min >= 0:
x in [21, 99], number of problems:
(99 - 21 + 1) * (1 + 78+1) / 2
x in [x_min, x_max], number of problems:
(x_max - x_min + 1) * (1 + x_max - (answer_min + y_min) + 1) / 2
The above is obtained using the formula for the sum of an arithmetic sequence. Therefore, you need to pick a random number in the range [1, 4740]. To transform this number into a subtraction problem, we need to define a mapping between the problem space and the integers. An example mapping is as follows:
1 <=> x = 21, y = 11
2 <=> x = 22, y = 12
3 <=> x = 22, y = 11
4 <=> x = 23, y = 13
5 <=> x = 23, y = 12
6 <=> x = 23, y = 11
and so on. Notice that x jumps by 1 when a triangular number is exceeded. To compute x and y from the random number r, find the lowest triangular number t greater than or equal to r, preferably by searching in a precomputed table; write this number as q*(q+1)/2. Then x = x_min + q-1 and y = y_min + t - r.
Complete program:
import random
x_min, x_max = (21, 99)
y_min = 11
answer_min = 10
triangles = [ (q*(q+1)/2, q) for q in range(1, x_max-x_min+2) ]
upper = (x_max-x_min+1) * (1 + x_max - (answer_min + y_min) + 1) / 2
for i in range(0, 20):
r = 1 + random.randrange(0, upper)
(t, q) = next(a for a in triangles if a[0] >= r)
x = x_min + q - 1
y = y_min + t - r
print "%d - %d = ?" % (x, y)
Note that for a majority of problems (around 75%), x will be above 60. This is correct, because for low values of the minuend there are fewer allowed values of the subtrahend.
I can see a couple of issues with your starting values - if you want the answer to always be greater than 10 - then you need to either increase MinuendMin, or decrease SubtrahendMin because 20-11 is less than 10... Also you have defined the answer min and max as 3,9 - which means the answer will never be more than 10...
Apart from that I managed to get a nice even distribution of values by selecting the minuend value first, then selecting the subtrahend value based on it and the answerMin:
ansMin = 10
minuendMin, minuendMax = 20,99
subtrahendMin = 9;
minuend = randint(minuendMin, minuendMax )
subtrahend = randint(subtrahendMin,(minuend-ansMin) )
answer = minuend - subtrahend
You say you've already got addition working properly. Assuming you have similar restrictions for the addends/sum you could rearrange the factors so that:
minuend <= sum
subtrahend <= first addend
answer <= second addend
A similar mapping can be made for multiplication/division, if required.

Given f(x) linear function, how to obtain a Quadratic Bezier control point

I've been doing a lot of research on the topic and found a couple of post that where helpful but I just can't get this right.
I am developing a very simple structural analysis app. In this app I need to display a graph showing the internal stress of the beam. The graph is obtained by the formula:
y = (100 * X / 2) * (L - X)
where L is the known length of the beam (lets say its 1 for simplicity). And X is a value between 0 and the Length of be beam. So the final formula would be:
y = (100 * X / 2) * (1 - x) where 0 < X < 1.
Assuming my start and end points are P0 = (0,0) and P2 = (1,0). How can I obtain P2 (control point)?? I have been searching in the Wikipedia page but I am unsure how to obtain the control point from the quadratic bezier curve formula:
B(t) = (1 - t)^2 * P0 + 2*(1 - t)*t * P1 + t^2 * P2
I'm sure it must be such an easy problem to fix… Can anyone help me out?
P.S.: I also found this, How to find the mathematical function defining a bezier curve, which seems to explain how to do the opposite of what I am trying to achieve. I just can't figure out how to turn it around.
We want the quadratic curve defined by y to match the quadratic Bezier curve
defined by B(t).
Among the many points that must match is the peak which occurs at x =
0.5. When x = 0.5,
y = (100 * x / 2) * (1 - x)
100 1 25
y = ---- * --- = ---- = 12.5
4 2 2
Therefore, let's arrange for B(0.5) = (0.5, 12.5):
B(t) = (1-t)^2*(0,0) + 2*(1-t)*t*(Px, Py) + t^2*(1,0)
(0.5, 12.5) = B(0.5) = (0,0) + 2*(0.5)*(0.5)*(Px, Py) + (0.25)*(1,0)
0.5 = 0.5 * Px + 0.25
12.5 = 0.5 * Py
Solving for Px and Py, we get
(Px, Py) = (0.5, 25)
And here is visual confirmation (in Python) that we've found the right point:
# test.py
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 1, 100)
y = (100*x/2)*(1-x)
t = np.linspace(0, 1, 100)
P0 = np.array([0,0])
P1 = np.array([0.5,25])
P2 = np.array([1,0])
B = ((1-t)**2)[:,np.newaxis]*P0 + 2*((1-t)*t)[:,np.newaxis]*P1 + (t**2)[:,np.newaxis]*P2
plt.plot(x, y)
plt.plot(B[:,0], B[:,1])
plt.show()
Running python test.py, we see the two curves overlap:
How did I know to choose t = 0.5 as the parameter value when B(t) reaches its maximum height?
Well, it was mainly based on intuition, but here is a more formal way to prove it:
The y-component of B'(t) equals 0 when B(t) reaches its maximum height. So, taking the derivative of B(t), we see
0 = 2*(1-2t)*Py
t = 0.5 or Py = 0
If Py = 0 then B(t) is a horizontal line from (0,0) to (1,0). Rejecting this degenerate case, we see B(t) reaches its maximum height when t = 0.5.
Your quadratic bezier curve formula has a typo in the middle term. It should be:
B(t) = (1 - t)^2 * P0 + 2 * (1 - t) * t * P1 + t^2 * P2
This means you should take the P1=(1,50) that #unutbu found and divide the coordinates in half to get P1=(.5,25). (This won't matter if you're plotting the parametric equation on your own, but if you want something like LaTeX's \qbezier(0,0)(.5,25)(1,0), then you'll need the corrected point.)
The P1 control point is defined so that the tangent lines at P0 and P2 intersect at P1. Which means that if (P1)x=(P2)x, the graph should be vertical on its righthand side (which you don't want).
In response to your comment, if you have a quadratic y=f(x), then it is symmetrical about its axis (almost tautologically). So the maximum/minimum will occur at the average of the roots (as well as the control point).

Know coordinate of Z from XY value and angle

I am using XY coordinate of drawing to draw object using Ink. Now I have one requirement. I have one Object, which is slope of 30 degree and I need to write some text for e.g. 'ABC' on the slope. What I have is XY coordiate and Angle and I want to find the Z from this information. Could you please suggest me some proper way to find the Z from the given information?
While Marking on the slope I need to down the Z axis to remain focus on Slope and for the same I will need value of Z at every point. As of now I have XY coordinate and Angle and I wanted to find the Z coordinate.
Looking forward to hear the experts suggestion/direction.
So, I guess it looks somewhat like this:
/|
/ |
x / |
/ | z
/ |
/ |
/γ)____|
y
You might want to use this:
z = sqrt(x² + y² - 2 * x * y * cos(γ))
... or this (at any offset s):
z = ((y - s) / sin(90 - γ) * sin(γ)
UPDATE:
So, let's say point P1 is the start of your triangle (bottom left corner) and point P2 is any point on the slope:
/
P2 .< P2.y
/|
/ |
/ |
/ |
.γ)__|___
P1 ^
P2.x
P2.x goes from P1.x to P1.x + <the width of your triangle>. Now, the only thing you need is coordinate y of P2. And (knowing the slope/angle γ) you can get it with the formula from above:
P2.y = ((P2.x - P1.x) / sin(90 - γ) * sin(γ) + P1.y

get uvw coordinates from pixel coordinates for ray-tracing

I'm trying to implement a simple ray-tracing algorithm
so the first step is to convert pixel coordinates into uvw coordinates system
iam using those two equations that i found in a book
where l,r,b,t are the view frustum points , (i,j) are the pixel indexes , (nx,ny) are the scene width and height
then to calculate canonical coordinate i use
i want to understand the previous equations and why they give uwv coordinates for perspective projection not for orthogonal projection (when i use orthogonal projection the equation still gives the result as if perspective projection is used)
Let's assume your camera is some sort of a pyramid. It has a bottom face which I'll refer to as the "camera screen", and the height of the pyramid, also known as the focal length, will be marked as F (or in your equations, Ws).
T(op)
*---------*
|\ /|
| \ / |
| \ / |
| \ / |
L(eft) | *E(ye| R(ight)
| / \ |
| / \ |
| / \ |
|/ \|
*---------*
B(ottom)
Let's assume j goes from the bottom to the top (from -Ny/2 to +Ny/2 in steps of 1/Ny), and i goes from left to right (from -Nx/2 to +Nx/2 in steps of 1/Nx). Note that if Ny is even, j goes up to Nx/2-1 (and similar when Nx is even).
As you go from bottom to top in the image, on the screen, you move from the B value to the T value. At the fraction d (between 0=bottom and 1=top) of your way from bottom to top, your height is
Vs = T + (B-T) * d
A bit of messing around shows that the fraction d is actually:
d = (j + 0.5) / Ny
So:
Vs = T + (B-T) * (j + 0.5) / Ny
And similarly:
Us = L + (R-L) * (i + 0.5) / Nx
Now, let's denote U as the vector going from left to right, V from bottom to top, 'W' going from the eye forward. All these vectors are normalized.
Now, assume the eye is located directly above (0,0) where that is exactly above the center of the rectangular face of the pyramid.
To go from the eye directly to (0,0) you would go:
Ws * W
And then to go from that point to another point on the screen at indexes (i,j) you would go:
Us * U + Vs * V
You will be able to see that Us = 0 for i = 0 and Vs = 0 for j = 0 (since B = -T and L = -R, as the eye is directly above the center of the rectangle).
And finally, if we compose it together, a point on the screen at indexes (i,j) is
S = E + Us * U + Vs * V + Ws * W
Enjoy!

What is being done in here ? (Used math recognition)

I know this isn't exactly programming related per se, but programmers are the most
probable of all people who will recognize this maybe.
I have the following (X and Y are arrays, both with 3 elements), and I cannot recognize (although it reminds me of a few things, but none quite!) what is being done here. Does it ring any bells for anyone else ?
I gather you can disregard the lower part; the upper should probably give it away ... but I still cannot see it.
At first it reminded me of linear interpolation in 3d space ...
SUBROUTINE TRII(X,Y,XR,YR)
DIMENSION X(3),Y(3)
D=X(1)*(X(2)**2-X(3)**2)+
> X(2)*(X(3)**2-X(1)**2)+
> X(3)*(X(1)**2-X(2)**2)
D1=Y(1)*(X(2)*X(3)**2-X(3)*X(2)**2)+
> Y(2)*(X(3)*X(1)**2-X(1)*X(3)**2)+
> Y(3)*(X(1)*X(2)**2-X(2)*X(1)**2)
D2=Y(1)*(X(2)**2-X(3)**2)+
> Y(2)*(X(3)**2-X(1)**2)+
> Y(3)*(X(1)**2-X(2)**2)
D3=X(2)*(Y(3)-Y(1))+
> X(1)*(Y(2)-Y(3))+
> X(3)*(Y(1)-Y(2))
A=D1/D
B=D2/D
C=D3/D
YR=A+B*XR+C*XR**2
RETURN
END
SUBROUTINE TRIM(X,Y,XR,YR,XM,YM)
DIMENSION X(3),Y(3)
D=X(1)*(X(2)**2-X(3)**2)+
> X(2)*(X(3)**2-X(1)**2)+
> X(3)*(X(1)**2-X(2)**2)
D1=Y(1)*(X(2)*X(3)**2-X(3)*X(2)**2)+
> Y(2)*(X(3)*X(1)**2-X(1)*X(3)**2)+
> Y(3)*(X(1)*X(2)**2-X(2)*X(1)**2)
D2=Y(1)*(X(2)**2-X(3)**2)+
> Y(2)*(X(3)**2-X(1)**2)+
> Y(3)*(X(1)**2-X(2)**2)
D3=X(2)*(Y(3)-Y(1))+
> X(1)*(Y(2)-Y(3))+
> X(3)*(Y(1)-Y(2))
A=D1/D
B=D2/D
C=D3/D
XR=-B/(2.*C)
YR=A+B*XR+C*XR**2
XM=XR
IF(XR.GT.X(1).OR.XR.LT.X(3))XM=X(1)
YM=A+B*XM+C*XM**2
IF(YM.LT.Y(1))XM=X(1)
IF(YM.LT.Y(1))YM=Y(1)
RETURN
END
">" is a continuation sign.
The code run as follows
Routine TRII takes as input the coordinates of three points (x,y) and interpolates a parabola using Lagrange interpolation. Also takes as input the coordinate XR. Returns in YR the value at XR for the interpolating parabola.
I guess the name of the routine comes from "TRI" (Croatian for "three" (points)) and "I" for Interpolation.
Routine TRIM also calculates the same parabola, and returns the minimun value of the function in the interval {X(1),X(3)}.The name comes from "TRI" and "M" (minimum)
(I "really" executed the program) >)
Note that this is FORTRAN code and the parameters are passed by reference, so the results are returned back in the same parameters (very odd!)
Edit
Just for fun, let's run TRII
TRII[X_, Y_, XR_] :=
Module[{D0, D1, D2, D3, A, B, C},
D0 = X[[1]]*(X[[2]]^2 - X[[3]]^2) +
X[[2]]*(X[[3]]^2 - X[[1]]^2) +
X[[3]]*(X[[1]]^2 - X[[2]]^2);
D1 = Y[[1]]*(X[[2]]*X[[3]]^2 - X[[3]]*X[[2]]^2) +
Y[[2]]*(X[[3]]*X[[1]]^2 - X[[1]]*X[[3]]^2) +
Y[[3]]*(X[[1]]*X[[2]]^2 - X[[2]]*X[[1]]^2);
D2 = Y[[1]]*(X[[2]]^2 - X[[3]]^2) +
Y[[2]]*(X[[3]]^2 - X[[1]]^2) +
Y[[3]]*(X[[1]]^2 - X[[2]]^2);
D3 = X[[2]]*(Y[[3]] - Y[[1]]) +
X[[1]]*(Y[[2]] - Y[[3]]) +
X[[3]]*(Y[[1]] - Y[[2]]);
A = D1/D0;
B = D2/D0;
C = D3/D0;
Return[A + B*XR + C*XR^2];];
X = RandomReal[1, 3];
Y = RandomReal[1, 3];
Show[Plot[TRII[X, Y, x], {x, 0, 1}],
ListPlot[Transpose[{X, Y}], PlotMarkers -> Automatic]]
D is the determinant of the matrix:
| x(1) x(1)² 1 |
D = det | x(2) x(2)² 1 |
| x(3) x(3)² 1 |
In D1, the rightmost column has been replaced with Y:
| x(1) x(1)² Y(1) |
D1 = det | x(2) x(2)² Y(2) |
| x(3) x(3)² Y(3) |
In D2, and D3 it's the first and second columns, respectively. Is it easier to recognize now? Looks a lot like using Cramer's rule to solve a linear equation to me.
Edit: To be more precise: (A, B, C) is the solution to the system:
A + x(1)*B + x(1)²*C = Y(1)
A + x(2)*B + x(2)²*C = Y(2)
A + x(3)*B + x(3)²*C = Y(3)
YR is the square of the solution to the quadratic equation (nb, different x!):
C*x² + B*x + A = 0
I feel like this should be obvious now, but I can't quite grasp it...
This code represents a kind of interpolation/quadratic curve fitting on three 2d points together with a way to compute the minimum or maximum value of such a fitted quadratic within the interval itself. I guess that TRII stands for triple (point)-interpolation and TRIM stands for triple (point) minimum or maximum.
To be more precised TRII solves the problem :- find a quadratic curve that passes through the points (x1,y1),(x2,y2) and (x3,y3) in the form Y=A+BX+CX^2 and compute the Y value of the quadratic at the point XR and return as YR. This is basically a way to interpolate smoothly between three 2d points. It is often used to find a better approximation for the max or min value of a set of discrete data points.
All the D, D1, D2, D3 stuff is to solve the matrix equation:
(1 X1 X1^2) *(A) = (Y1)
(1 X2 X2^2) *(B) = (Y2)
(1 X3 X3^2) *(C) = (Y3)
using Cramers rule as mentioned in one of the other comments, D is the matrix determinant and D1, D2, D3 are co-factors.
TRIM again computes the quadratic Y=A+BX+CX^2 and then finds a max/min of this quadratic (XM, YM). This is done by initially finding the point where the quadratic has a turning point: if F(X)=A+BX+CX^2, F'(XR)=B+2*C*XR=0, or XR=-B/2*C, YR=A+BXR+CXR^2. There is then some logic to force the returned XM, YM min or max values to lie within certain bounds.
The code:
XM=XR
.
.
.
IF(YM.LT.Y(1))YM=Y(1)
Is a little weird since if we assume that GT and LT mean greater than and less than respectively then we need to assume that X3'<'X1 otherwise the condition (XR.GT.X(1).OR.XR.LT.X(3)) is trivial and XM,YM are set to X1, Y1.
So X3'<'X1 and the condition says that if the quadratics max/min value is outside the interval (X1,X3) then set (XM,YM) to (X1, Y1) as before. If not then if Y1 is above the min/max value in Y then again set (XM,YM) to (X1, Y1).
It is hard to understand what this means and I suspect the code may be wrong! Any thoughts?
Ivan
I'm not sure what language this is, but it's clear that this is some sort of solver for quadratic equations. The XR and YR expressions are a dead giveaway:
XR = -B / (2.*C)
YR = A + B*XR + C*XR**2
Without knowing what the X(1..3) and Y(1..3) expressions are, however, it's not going to be possible to infer too much more about what the A/B/C coefficients represent, however. Lots of things use quadratic equations -- area of a circle given the radius, intensity of light at a given distance, et cetera. More contextual data is required.
Update: The OP indicated that he can't be too much more specific for secrecy reasons. Here are some hints, though:
What does the subroutine return? How are those results used later on? That may lead to better insights.
It appears that Y(1) is some sort of magic lower bound for the result of this computation. Notice that if YM is less than Y(1), then both XM and YM are set to X(1) and Y(1), respectively.
The "D" expressions look like this, in more natural syntax:
d = x1 * [x2^2 - x3^2] + x2 * [x3^2 - x1^2] + x3 * [x1^1 - x2^2]
d1 = y1 * [x2*x3^2 - x3*x2^2] + y2 * [x3*x1^2 - x1*x3^2] + y3 * [x1*x2^2 - x1*x2^2]
d2 = y1 * [x2^2 - x3^2] + y2 * [x3^2 - x1^2] + y3 * [x1^2 - x2^2]
d3 = x2 * [y3 - y1] + x1 * [y2 - y3] * x3 * [y1 - y2]
This looks very much like some sort of matrix operation; D is almost certainly for "determinant". But there are other things that have the same mathematical relationship.
This is a way to solve linear equation systems, specifically cramers rule. Also have a look at the rule of sarrus. After that, you seem to construct a quadratic equation out of it.

Resources