Increase when smaller than, decrease when lower than - language-agnostic

Out of curiosity, is there a (language independent*) way to make these two generic statements into one statement?
if (a < b) a += x;
else if (a > b) a -= x;
May also be used as
if (abs(b - a) < x) a = b;
else if (a < b) a += x;
else if (a > b) a -= x;
Oh, now that I'm writing this I'm thinking of something like this:
if (a != b) a += x * (a < b ? 1 : -1);
But that doesn't really benefit the readability. Other ways perhaps?
= Normal languages, not Brainfuck and the likes or really ancient ones

a += x * sgn(b-a)
Where sgn is the sign function:
sgn x | x > 0 = 1
| x < 0 = -1
| otherwise = 0

You should really wonder why you want this, the compiler will do fine optimizing and the given statement is very readable.

Language independent is a bit tricky, but if you have cmp or similar, you can use that:
a += x * cmp(b, a)
cmp(b, a) returns:
0 if b==a
1 if b > a
-1 if a < b
Also, there is a bug in your suggested implementation:
a = 9;
b = 10;
x = 2;
if (a < b) a += x;
if (a > b) a -= x;
print a;
Output: 9 (expected 11)
You need an else to fix this. Alternatively, if you want to prevent a going past b, do this:
if (a < b)
{
a = min(b, a + x);
}
else if (a > b)
{
a = max(b, a - x);
}
If you want to do this in one expression you can:
a = (a < b) ? min(b, a + x) : max(b, a - x);
I think the first way is clearer though.

a += (b - a) / abs(b - a) * x
But this is not language independent and does not really help readiness if you ask me....

Related

mathematica Sum of functions

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. )

AS3 convert a positive number to 1 and a negative number to -1

There is a simple trick to convert a number to 1 or -1.
Just raise it to the power of 0.
So:
4^0 = 1
-4^0 = -1
However, in AS3:
Math.pow( 4, 0); // = 1
Math.pow(-4, 0); // = 1
Is there a way to get the right answer without an if else?
This could be done bitwise.
Given the number n (avg time: 0.0065ms):
1 + 2 * (n >> 31);
Or slightly slower (avg time: 0.0095ms):
(n < 0 && -1) || 1;
However, Marty's solution is the fastest (avg time: 0.0055ms)
n < 0 ? -1 : 1;
Not sure if without an if/else includes the ternary operator in your eyes, but if not:
// Where x is your input.
var r:int = x < 0 ? -1 : 1;
Will be more efficient than Math.pow() anyway.

How to perform a conditional assignment on each element of the vector

I have a function like this:
y=-2 with x<=0
y=-2+3x^2 with 0=1
I need to compute this function on each element of the 1D matrix, without using a loop.
I thought it was possibile defining a function like this one:
function y= foo(x)
if x<=0
y=-2;
elseif x>=1
y=1;
else
y= -2+3*x.^2;
end
end
But this just produces a single result, how to operate on all elements? I know the . operator, but how to access the single element inside an if?
function b = helper(s)
if s<=0
b=-2;
elseif s>=1
b=1;
else
b= -2+3*s^2;
end
end
Then simply call
arrayfun(#helper, x)
to produce the behaviour you want of your function foo.
Another approach which doesn't need arrayfun() would be to multiply by the conditions:
y = -2*(x <= 0) + (-2+3*x.^2).*(x < 1).*(x > 0) + (x >= 1)
which you could also make a function. This will accept vector inputs for x e.g.
x = [1 4 0 -1 0.5];
y = -2*(x <= 0) + (-2+3*x.^2).*(x < 1).*(x > 0) + (x >= 1)
outputs
y =
1.0000 1.0000 -2.0000 -2.0000 -1.2500

Languages where 3 > 2 > 1 is true

I have written a decimal floating point unit for LaTeX3 (pure macros... that was tough). In particular, I have to decide how x < y < z should be parsed. I see three options:
Treat < as a left-associative binary operator, so x < y < z would be equivalent to (x < y) < z. This is what C does: -1 < 0 < 1 becomes (-1 < 0) < 1, thus 1 < 1, which is 0.
Treat < as a right-associative binary operator, so x<y<z would be equivalent to x < (y < z). I see no advantage to that option.
When encountering <, read ahead for more comparison operators, and treat x < y < z as equivalent to (x < y) && (y < z), where y would be evaluated only once. This is what most non-programmers would expect. And quite a few LaTeX users are non-programmers.
At the moment I am using the first option, but it does not seem very natural. I think that I can implement the second case whithout too much overhead. Should I?
Since that question is subjective, let me ask an objective question: what mainstream languages pick option 3? I'm interested in the details of what happens with mixed things like a < b > c == d < e != f. I'm also interested in other choices if they exist.
Short answer: it only makes sense to parse comparison sequences if they are "pointing into the same direction", and when you don't use !=.
Long answer: In Python, 3 > 2 > 1 evaluates to True. However, I have to say that the implementation used is overly simplistic, because it allows for expressions like a < b > c == d < e != f, which are nonsensical in my opinion. The expression would be interpreted as (a < b) and (b > c) and (c == d) and (d < e) and (e != f). It's an easy rule, but because it allows for surprising results, I don't like that interpretation.
I propose a more predictable option:
Consider a proposition xAyBzCw. If this proposition is "sensical", it is equivalent to xAy and yBz and zCw. For "sensicality", it is necessary that...
the values (x, y, z, w) are part of the same set X (or their types can be unified as such), and
the relations (A, B, C) are transitive binary relations on X, and
for every ordered pair of relations A and B, there exists a relation C, such that xAy and yBz implies xCz for all x, y, z; this relation is also subject to these restrictions.
Regarding the last rule, you want to be able to say that 1 < 2 = a < 4 is equivalent to 1<2 and 2=a and a<4, but also that 1<2 and 1<a and 1<4. To say the latter, you must know how = and < interact.
You can't use != in my option, because it isn't transitive. But you also can't say 1 < 3 > 2, 2 < 3 > 1, or 1 < 3 > 1, unless you have a relation ? such that 1?2, 2?1 and 1?1 (basically, it would be a relation allows any pair).
From a syntactical standpoint: you want to treat relational operators as special operators (+ is more of a functional operator), kind of like in your third option.
Python chains relational operators. Which gets interesting when you hit in and is, since they're considered relational as well.
>>> 1 < 2 in [True, False]
False
>>> 1 < 2 in [2, 4]
True
J evaluates statements right-to-left so that:
3 > 2 > 1
Becomes first
2 > 1
Which resolves to true, represented as 1, thus:
3 > 1
Which also resolves to true, thus 1. The opposite operator < would result in false, whereas the whole statement happens to be true. So you're no further with J.
Your main issue is that your initial representation:
3 > 2 > 1
is human shorthand for
(3 > 2) AND (2 > 1)
So while reading ahead seems icky, it's really what the representation needs. Unless of course there's some Python magic, as others have stated.

Intersection of parabolic curve and line segment

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.