I have a table with columns: a, b, x_1, x_2, x_3, x_4, x_5, y_1, y_2, y_3, y_4, y_5 and need to apply a formula such as: a * (x_i * (1 + (b / (1 - b)) ) + (y_i - x_i)) where i = {1,2,3,4,5}.
My problem is that I need to sum() the results of this formula partitioned w.r.t two the other columns a, b. So the select query will be like:
select(
col_1,
col_2,
func.sum(
a * (x_1 * (1 + (c / (1 - c)) ) + (y_1 - x_1))
).over(partition_by=[col_1, col_2]).label("sum1"),
func.sum(
a * (x_2 * (1 + (c / (1 - c)) ) + (y_2 - x_2))
).over(partition_by=[col_1, col_2]).label("sum2"),
...
func.sum(
a * (x_5 * (1 + (c / (1 - c)) ) + (y_5 - x_5))
).over(partition_by=[col_1, col_2]).label("sum5")
)
As you can see it is cumbersome to maintain and keep repeating the formula is error prone.
Is there a way to wrap this formula so that I can simply refer to formula like below or some way of abstracting it?
select(
col_1,
col_2,
func.sum(my_custom_formula(a, b, x_1, y_1)).over(partition_by=[col_1, col_2]).label("sum1"),
func.sum(my_custom_formula(a, b, x_2, y_2)).over(partition_by=[col_1, col_2]).label("sum2"),
...
func.sum(my_custom_formula(a, b, x_5, y_5)).over(partition_by=[col_1, col_2]).label("sum5")
)
You can hide even more of the implementation detail if you want. The below should give you directional idea:
def get_expression(T: MyTable, pos: int, c):
xn = getattr(T, f"x_{pos}")
yn = getattr(T, f"y_{pos}")
_expr = T.a * (xn * (1 + (c / (1 - c)) ) + (yn - xn))
expr = func.sum(_expr).over(partition_by=[T.col_1, T.col_2]).label(f"sum{pos}")
return expr
q = select(
T.col_1,
T.col_2,
get_expression(T, 1, c),
get_expression(T, 2, c),
get_expression(T, 3, c),
get_expression(T, 4, c),
get_expression(T, 5, c),
)
Related
This code make an operation on a and b and check if result is equal to c.
If yes, just print this row. My question is how to change this code to display
rows when result (a / b) = 0.
SELECT id, a, b, operation, c
FROM expressions
where
case
when operation LIKE '+' AND (a + b = c) then c
when operation LIKE '-' AND (a - b = c) then c
when operation like '/' AND (a / b = c) then c
when operation like '*' AND (a * b = c) then c
ELSE FALSE END;
Output:
id a b operation c
1 2 3 + 5
4 4 7 * 28
11 0 1 / 0
14 239 0 * 0
15 18 18 - 0
1, 2 rows are ok and printed. 3, 4, 5 rows should be printed but they are not!
When a / b = 0 then second condition in sql query is false - row is not printed, e.g. 0 / 1 = 0. It is 0 and should be printed. In contrart to 1 / 0 which shouldn`t be printed.
My solution is to cast (a / b = c) to unsigned but it is not working?
You shouldn't mix types like boolean and int because implicit conversion occurs.
Use explicit value instead of TRUE/FALSE (0 is treated as FALSE).
SELECT id, a, b, operation, c
FROM expressions
where
case
when operation LIKE '+' AND (a + b = c) then 1
when operation LIKE '-' AND (a - b = c) then 1
when operation like '/' AND (a / b = c) then 1
when operation like '*' AND (a * b = c) then 1
ELSE 0 END = 1;
alternatively:
SELECT id, a, b, operation, c
FROM expressions
where
case
when operation LIKE '+' AND (a + b = c) then TRUE
when operation LIKE '-' AND (a - b = c) then TRUE
when operation like '/' AND (a / b = c) then TRUE
when operation like '*' AND (a * b = c) then TRUE
ELSE FALSE END;
As already pointed out, the issue is that 0 is treated as false.
I would simplify the logic to:
SELECT id, a, b, operation, c
FROM expressions
WHERE (operation LIKE '+' AND (a + b = c) ) OR
(operation LIKE '-' AND (a - b = c) ) OR
(operation LIKE '/' AND (a / b = c) ) OR
(operation LIKE '*' AND (a * b = c) );
I don't think the CASE makes the code more understandable.
If you are concerned about divide-by-zero, then use nullif():
(operation LIKE '/' AND (a / nullif(b, 0) = c) ) OR
Write two versions of the function power, the first version takes two integer arguments m and n
and returns the value m^n
Note that both m and n can be any integers (positive or non-positive).
The second version of the function is called (cpower m n) and it is the curried version.
Remark: if both m and n are Zero then an exception should be raised.
fun power(m,n) = if n=0 then 1 else m * power(m,n-1);
fun cpower (m,n) : int =
if n = 0 then 1 else
if n >= 0 then power(m,n) else
if n < 0 then 1/power(m,n) else m * cpower (m,n-1);
How do I add so that this function throws an exception?
Your cpower function does not have the right type signature. It isn't curried. A curried function with two arguments looks like:
fun cpower m n = ...
It has the type int → int → int as opposed to power's type (int × int) → int. Curried functions with two arguments are equivalent to functions with one argument that return a function with another argument. E.g.
fun cpower m = (fn n => ...)
that can also be written
val rec cpower = (fn m => fn n => ...)
Your current cpower function appears to have a special case for n<0, but here you write 1/power(m,n). But the / operator is not defined for integers which the rest of your program assumes through integer literals (0, 1) and if the result is a fraction below 1, it isn't in the domain of integers.
Consider using pattern matching instead of if-then-else in both cases. For the first power function it would look like:
fun naive_power (m, 0) = 1
| naive_power (m, n) = m * naive_power (m, n-1)
Your functions don't throw when both m and n are zero. (Neither does my version that uses pattern matching.) You might want to write an additional if-then-else and throw if both m and n are zero, e.g. like,
fun power (m, 0) = 1
| power (m, n) = if n < 0 then raise Domain else m * power (m, n-1)
One bad thing about this function is that it will check if n < 0 at every single recursive call to itself when, really, you know that if it was positive the first time and the base case will catch it at 0, it won't be negative at any later stage. An elegant solution here is to wrap the recursive part of your function in a non-recursive function that performs these checks once, e.g. like,
fun power (0, 0) = raise Domain
| power (m, n) = if n < 0 then raise Domain else naive_power (m, n)
where naive_power was the function above that assumed its input valid.
One other bad thing about this function is that it isn't tail-recursive when it could easily be. That is, a call to power (m, 5) will evaluate as such:
power (2, 5) ~> 2 * (power (m, 4))
~> 2 * (2 * (power (m, 3)))
~> 2 * (2 * (2 * (power (m, 2))))
~> 2 * (2 * (2 * (2 * (power (m, 1)))))
~> 2 * (2 * (2 * (2 * (2 * power (m, 0)))))
~> 2 * (2 * (2 * (2 * (2 * 1))))
~> 2 * (2 * (2 * (2 * 2)))
~> 2 * (2 * (2 * 4))
~> 2 * (2 * 8)
~> 2 * 16
~> 32
meaning a lot of function calls waiting for the next function call to resolve before itself can resolve. A tail-recursive version might use an additional argument to store the temporary result in and return it at the end:
fun power (0, 0) = raise Domain
| power (M, N) =
let fun power_helper (m, 0, result) = result
| power_helper (m, n, tmp) = power_helper (m, n-1, tmp * m)
in if N < 0 then raise Domain else power_helper (M, N, 1) end
It can be useful to embed helper functions into other functions either because you need to perform certain checks once and have the main, recursive part of your algorithm resolved in another function, or because you wish to add more arguments to your recursive function without breaking the type signature. (power_helper takes three arguments, so a tail-recursive version would not, without being wrapped, be a valid solution to the problem of writing a function with two arguments that calculates mⁿ.
Evaluating power (2, 5) assuming its tail-recusive implementation could look as such:
power (2, 5) ~> power_helper (2, 5, 1)
~> power_helper (2, 4, 2)
~> power_helper (2, 3, 4)
~> power_helper (2, 2, 8)
~> power_helper (2, 1, 16)
~> power_helper (2, 0, 32)
~> 32
I want to build a function in the following way:
f[x_] := 0;
For[i = 1, i <= n, i++,
g[x_] := 0;
For[k = 1, k <= i, k++,
g ^:= g[#]*(# - X[[k]]) &;
g[x_] = g;
]
f ^:= f[#] + Q[[1, i]]*g[#];
f[x_] = f;
So I get a polynomial
Q_11 * (x-x_1) + Q_12 * (x-x_1) * (x-2x_2) ...
This is the latest version I have, but it does not work. The problem is that I have to add functions (I found some posts where it is done) but I have to save the new function so I can use it again.
Does someone know what to do?
Thanks!
Marius
I cant make head or tail of your code but you can readily construct that result just like this:
qlist = Array[q, {10, 10}];
xlist = Array[x, 10];
poly[n_] := Sum[ qlist[[1, j]] Product[ (x - xlist[[i]] ), {i, j}] , {j, 3}]
poly[3]
q[1, 1] (x - x[1]) + q[1, 2] (x - x[1]) (x - x[2]) +
q[1, 3] (x - x[1]) (x - x[2]) (x - x[3])
If you really need help using UpSetDelayed you should pose a more simple / specific question ( ie without the For loops. )
My problem is just really simple,
I found somethng in the stackoverflow a same problem but it finds the largest number between 2 numbers
var c =(Math.sqrt( a*a + b*b - 2*a*b ) + a + b) / 2;
can somebody help me revised this equation so the lowest number should print out?
hi i have one solution
c = ((a + b) - sqrt((a - b) * (a - b))) / 2
Hope this will help you
Rewrite your code as below:
var c =((a + b) - Math.sqrt((a - b) * (a - b))) / 2;
As far as I know:
c = ((a + b) - sqrt((a - b) * (a - b))) / 2
equals
c = ((a + b) - (a - b)) / 2
equals
c = (a - a + b + b) /2 = b
or am I missing something?
Why don't you use the Math class for it? Like Math.min(a,b) ????
I have an equation for a parabolic curve intersecting a specified point, in my case where the user clicked on a graph.
// this would typically be mouse coords on the graph
var _target:Point = new Point(100, 50);
public static function plot(x:Number, target:Point):Number{
return (x * x) / target.x * (target.y / target.x);
}
This gives a graph such as this:
I also have a series of line segments defined by start and end coordinates:
startX:Number, startY:Number, endX:Number, endY:Number
I need to find if and where this curve intersects these segments (A):
If it's any help, startX is always < endX
I get the feeling there's a fairly straight forward way to do this, but I don't really know what to search for, nor am I very well versed in "proper" math, so actual code examples would be very much appreciated.
UPDATE:
I've got the intersection working, but my solution gives me the coordinate for the wrong side of the y-axis.
Replacing my target coords with A and B respectively, gives this equation for the plot:
(x * x) / A * (B/A)
// this simplifies down to:
(B * x * x) / (A * A)
// which i am the equating to the line's equation
(B * x * x) / (A * A) = m * x + b
// i run this through wolfram alpha (because i have no idea what i'm doing) and get:
(A * A * m - A * Math.sqrt(A * A * m * m + 4 * b * B)) / (2 * B)
This is a correct answer, but I want the second possible variation.
I've managed to correct this by multiplying m with -1 before the calculation and doing the same with the x value the last calculation returns, but that feels like a hack.
SOLUTION:
public static function intersectsSegment(targetX:Number, targetY:Number, startX:Number, startY:Number, endX:Number, endY:Number):Point {
// slope of the line
var m:Number = (endY - startY) / (endX - startX);
// where the line intersects the y-axis
var b:Number = startY - startX * m;
// solve the two variatons of the equation, we may need both
var ix1:Number = solve(targetX, targetY, m, b);
var ix2:Number = solveInverse(targetX, targetY, m, b);
var intersection1:Point;
var intersection2:Point;
// if the intersection is outside the line segment startX/endX it's discarded
if (ix1 > startX && ix1 < endX) intersection1 = new Point(ix1, plot(ix1, targetX, targetY));
if (ix2 > startX && ix2 < endX) intersection2 = new Point(ix2, plot(ix2, targetX, targetY));
// somewhat fiddly code to return the smallest set intersection
if (intersection1 && intersection2) {
// return the intersection with the smaller x value
return intersection1.x < intersection2.x ? intersection1 : intersection2;
} else if (intersection1) {
return intersection1;
}
// this effectively means that we return intersection2 or if that's unset, null
return intersection2;
}
private static function solve(A:Number, B:Number, m:Number, b:Number):Number {
return (m + Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
private static function solveInverse(A:Number, B:Number, m:Number, b:Number):Number {
return (m - Math.sqrt(4 * (B / (A * A)) * b + m * m)) / (2 * (B / (A * A)));
}
public static function plot(x:Number, targetX:Number, targetY:Number):Number{
return (targetY * x * x) / (targetX * targetX);
}
Or, more explicit yet.
If your parabolic curve is
y(x)= A x2+ B x + C (Eq 1)
and your line is
y(x) = m x + b (Eq 2)
The two possible solutions (+ and -) for x are
x = ((-B + m +- Sqrt[4 A b + B^2 - 4 A C - 2 B m + m^2])/(2 A)) (Eq 3)
You should check if your segment endpoints (in x) contains any of these two points. If they do, just replace the corresponding x in the y=m x + b equation to get the y coordinate for the intersection
Edit>
To get the last equation you just say that the "y" in eq 1 is equal to the "y" in eq 2 (because you are looking for an intersection!).
That gives you:
A x2+ B x + C = m x + b
and regrouping
A x2+ (B-m) x + (C-b) = 0
Which is a quadratic equation.
Equation 3 are just the two possible solutions for this quadratic.
Edit 2>
re-reading your code, it seems that your parabola is defined by
y(x) = A x2
where
A = (target.y / (target.x)2)
So in your case Eq 3 becomes simply
x = ((m +- Sqrt[4 A b + m^2])/(2 A)) (Eq 3b)
HTH!
Take the equation for the curve and put your line into y = mx +b form. Solve for x and then determine if X is between your your start and end points for you line segment.
Check out: http://mathcentral.uregina.ca/QQ/database/QQ.09.03/senthil1.html
Are you doing this often enough to desire a separate test to see if an intersection exists before actually computing the intersection point? If so, consider the fact that your parabola is a level set for the function f(x, y) = y - (B * x * x) / (A * A) -- specifically, the one for which f(x, y) = 0. Plug your two endpoints into f(x,y) -- if they have the same sign, they're on the same side of the parabola, while if they have different signs, they're on different sides of the parabola.
Now, you still might have a segment that intersects the parabola twice, and this test doesn't catch that. But something about the way you're defining the problem makes me feel that maybe that's OK for your application.
In other words, you need to calulate the equation for each line segment y = Ax + B compare it to curve equation y = Cx^2 + Dx + E so Ax + B - Cx^2 - Dx - E = 0 and see if there is a solution between startX and endX values.