How to optimize if statement given the if statement has: > or < - python

How to make code similar to the one below run faster.
I know you can use a dictionary for equality if-statements but no sure with this one.
Delta = 3
if (x - y) >= Delta:
pass
elif y < Delta:
pass
else:
pass

Here's an example of how a dictionary lookup would look here, if you really wanted to use one:
def do_something():
pass
def do_something_else_1():
pass
def do_something_else_2():
pass
{
y < Delta: do_something_else_1,
x - y >= Delta: do_something
}.get(True, do_something_else_2)()
But I can guarantee you this will run slower (mainly because all the conditions are greedily evaluated now, instead of lazily). The reason you cannot optimize your existing code with a dictionary lookup is because a dictionary lookup excels where computing a hash followed by computing equality with the narrowed search space is faster than computing equality with the entire search space. Because of this benefit, you have to pay the upfront cost of constructing the hash table in the first place.
However, you aren't checking equality here. You're using the inequality functions < and >=, which don't play nice with the concept of a hash table. The hash of a bool (the result of this inequality function) is no quicker to compute compared to using the bool itself, which means that constructing the hash table here will outweigh any time savings you get by using the constructed hash table immediately afterwards. Seeing as x and y may change each time, there's no way for you to cache this hash table, meaning you suffer the cost of construction each time.
Keep the code as it is.

Optimization usually takes advantage of some common expression or common code. You have none here. At the register level, your comparisons look like:
load r1, x
sub r1, y
sub r1, 3
brlt ELIF # if less than 0, branch to ELIF
# TRUE-clause stuff, aka "Do something"
br ENDIF
ELIF:
load r1, y
sub r1, 3
brge ELSE # if >= 0, branch to ELSE
# ELIF-clause stuff, aka "Do something else #1"
ELSE:
# ELSE-caluse stuff, aka "Do something else #2"
ENDIF:
# Remainder of program
The only commonality her in either data or flow is loading y into a register. Any reasonably aware optimization level will do this for you -- it will alter the first expression to load y into r2, a trivial cost in micro-instruction utilization.
There appears to be nothing else to optimize here. The normal flow analysis will recognize that 3 is a constant within this block, and substitute the immediate operand for Delta.

Related

How to enforce relative constraints on hypothesis strategies?

Say I have 2 variables a and b where it is given that b > a, how then can I enforce this relative constraint on the hypothesis strategies?
from hypothesis import given, strategies as st
#given(st.integers(), st.integers())
def test_subtraction(a, b):
# only evaluates to true if b > a
# hence I'd like to enforce this constraint on the strategy
assert abs(b - a) == -(a - b)
(I've no idea how to do this in Python, but it's a common enough problem, so I hope you can use these F# FsCheck examples instead. The ideas are universal.)
Filtering
Most property-based frameworks come with an ability to filter values based on a predicate. In FsCheck it's the ==> operator. In QuickCheck the equivalent is called suchThat.
Using the ==> operator in FsCheck, you can write the property like this:
[<Property>]
let property_using_filtering (a : int) (b : int) =
b > a ==> lazy
Assert.Equal (abs (b - a), -(a - b))
(It's possible to write the test in a more terse and idiomatic style, but since I'm assuming that you may not be familiar with F#, I chose to be more explicit than usual.)
Notice that the predicate b > a precedes the filtering operator ==>. This means that the rest of the code to the right of, and below, the operator only runs when the predicate is true.
The framework is still going to generate entirely random values, so (assuming a uniform random distribution) it'll be throwing half of the generated values away.
Thus, to generate 100 (the default) valid test cases, it'll have to generate on average 200 test cases (i.e. 400 integers). Generating 400 integers instead of 200 integers probably isn't a big deal, but in general, this kind of filtering can be prohibitively wasteful.
Therefore, it's always useful to be aware of alternatives.
Seed and diff
When faced with this sort of problem, it usually helps to take an alternative look at how to generate values. How do you generate two values where one is strictly greater than the other?
You can generate a random value (the seed), which in this case will also serve as the first value itself. Then a second value will indicate the difference between the two.
Some property-based frameworks come with features where you can tell it to generate strictly positive numbers. FsCheck comes with those features, but assuming for the moment that not all frameworks can do this, you can still use an unconstrained random value.
In that case, the difference, being any random number, may be both negative, zero, or positive. In this case, we can take the absolute value of the number and then add one to ensure that it's strictly greater than zero. Now you have a number that's guaranteed to be greater than zero. If you add that to the first number, you're guaranteed to have a number greater than the first one:
[<Property>]
let property_using_seed_and_diff (seed : int) (diff : int) =
let a = seed
let b = a + 1 + abs diff
Assert.Equal (abs (b - a), -(a - b))
Here, (somewhat redundantly) we set a = seed and then b = a + 1 + abs diff according to the above description.
(I only included the redundant seed function parameter to illustrate the general idea. Sometimes, you need one or more values calculated from a seed, but not the seed itself. In the present case, however, the value and seed coincide.)
In addition to the filtering and seed-plus-diff approaches shown above, the "fix-it-up" approach can be useful: try to generate something valid, and just patch the object if it's not satisfied. In this case, that might look like:
#given(st.integers(), st.integers())
def test_subtraction(a, b):
a, b = sorted([a, b])
....
The advantage here is that the minimal failing example tends to look a bit more natural, and might have a nicer distribution than a seed-and-diff (or "constructive") approach. It also combines well with the other approaches, especially if you're defining your own strategy with #st.composite.
You can add these constrains using assume in hypothesis:
from hypothesis import assume, given, strategies as st
#given(st.integers(), st.integers())
def test_subtraction(a, b):
assume(b > a)
assert abs(b - a) == -(a - b)
See: https://hypothesis.readthedocs.io/en/latest/details.html#making-assumptions for more details

Named conditions in Python and a silly textbook - and how to prove they're wrong

Python's abstraction is often seen as magic by many. Coming from a C background, I know very well there is no such thing as magic, only cold hard code made up of simple components that produces abstraction.
So, when a textbook and my teacher say that we can "store conditions" or use "named conditions" for readability, and say that assigning a boolean expression to a variable suddenly makes it a dynamic condition akin to a macro, I lose it.
EDIT 1 : They don't explicitly say its like a macro (direct quotes are placed within quotes) since we aren't expected to know any other language beforehand.
The way they say that " the variable stores the condition unevaluated ", is like saying it is a macro , and this is my opinion. They imply it to be practically the equivalent of a macro by their articulation, just without saying the word 'macro'.
Here's the claim in code form :
x,y = 1,2
less = x < y
more = x > y
'''
less/ more claimed to store not boolean True/False but some magical way of storing the
expression itself (unevaluated, say like a macro) and apparently
'no value is being stored to less and more'.
'''
It is being represented as though one was doing :
// C-style
#define less (x < y)
#define more (x > y)
Of course, this is not true, because all less and more store in the so-called 'named conditions' is just the return value of the operator between x and y .
This is obvious since < , >, == , <= , >= all have boolean return values as per the formal man pages and the spec, and less or more are only storing the True or False boolean return value , which we may prove by calling print() on them and/or by calling type() on them.
Also, changing the values of x and y , say by doing x,y = y,x does not change the values of less or more because they store not a dynamic expression but the static return value of the > or < operand on the initial x and y values.
The question isn't that this claim is a misunderstanding of the purported abstraction ( its not actually an abstraction, similar storage can be achieved in asm or C too) , but rather how to clearly and efficiently articulate to my teacher that it is not working like a C macro but rather storing the boolean return value of >or < statically.
Obviously less = x < y just looks at the current values of x and y and stores either True or False into the variable less.
If I understand where you and your teacher disagree, you two have a different idea of what the following code will print out:
x, y = 1, 2
less = x < y
print(less)
x, y = 2, 1
print(less)
"Macro's" could be implemented as text strings that can be evaluated, like (bad example - not the recommended solution):
less = "({0}) < ({1})"
and use them like:
x = 1
y = 3
outcome = eval(less.format("x", "y"))
But this is really a silly thing to do, and eval() is susceptible for security issues.
Perhaps your teacher meant to use lambda expressions, which are nameless, ad-hoc functions:
less = lambda a, b: a < b
x = 1
y = 3
outcome = less(x, y)
Note:
There is already a function for lambda a, b: a < b available in the standard library operator module: operator.lt.

Improving preformance by using multiple threads/cores

I have a game (using pygame) that I want to improve the performance of. I noticed that when I have low fps the game was only using 20% of the CPU at most, is there a way I can use threads to utilize more of the CPU?
I have tried to implement threads already, but seem to have no good luck, some help would be appreciated.
This function is what is causing the lag:
First Version
def SearchFood(self):
if not self.moving:
tempArr = np.array([])
for e in entityArr:
if type(e) == Food:
if e.rect != None and self.viewingRect != None:
if self.viewingRect.colliderect(e.rect):
tempArr = np.append(tempArr, e)
if tempArr.size > 0:
self.nearestFood = sorted(tempArr, key=lambda e: Mag((self.x - e.x, self.y - e.y)))[0]
Second Version (Slower)
def SearchFood(self):
if not self.moving:
s_arr = sorted(entityArr, key=lambda e: math.hypot(self.x - e.x, self.y - e.y))
for e, i in enumerate(s_arr):
if type(e) != Food:
self.nearestFood = None
else:
self.nearestFood = s_arr[i]
break
I look through the entire list of entities and sort it after if the entity is food and the distance to the thing that wants to eat said food. Problem is that the entity array is 500 elements (and more) long and thus takes a really long time to iterate through and sort. Then to remedy that I want to make use of more of the CPU with the use of threading.
Here's the full script if that helps: https://github.com/Lobsternator/Game-Of-Life-Esque.git
In Python, threading does not increase the number of used core. You must use multiprocessing instead.
The doc : https://docs.python.org/3.7/library/multiprocessing.html#multiprocessing.Manager
Multithreading in Python is nearly useless (for CPU-intensive tasks like this), and multiprocessing, while viable, requires expensive marshaling of data between processes or careful design. I don't believe either one is applicable to your case.
However, unless you have a huge amount of objects in your game, you shouldn't need to use multiple cores for your scenario. The issue seems more one of algorithmic complexity.
You can improve the performance of your code in several ways:
Keep an index of entities by type (e.g. a dict from entity-type to set of entities, which you update as entities are created/removed), which would allow you to easily find all the "food" entities without scanning through all entities in the game.
Find the nearest food entity using a simple "min" operation (which is O(n)) instead of sorting all the foods by distance (which is O(n*logn)).
If this is still slow you can apply a culling technique, where you first filter foods to those within an easily-computed range (e.g. a rectangle around the player), then find the nearest one by applying the more expensive distance computation only to those.
Make loops tighter by avoiding checking unnecessary conditions inside them, and whenever possible using builtin selection/creation constructs rather than iterating through large lists of objects.
e.g. you can end up with something like:
def find_nearest_food(self):
food_entities = self._entities_by_type[Food]
nearest_food = min(food_entities, key=lambda entity: distance_sq(self, entity))
return nearest_food
def distance_sq(ent1, ent2):
# we don't need an expensive square root operation if we're just comparing distances
dx, dy = (ent1.x - ent2.x), (ent1.y - ent2.y)
return dx * dx + dy * dy
You can optimize further by keeping entity positions as NumPy vectors instead of separate x and y properties, which would allow you to use NumPy operations to calculate distance, e.g. distance_sq = (ent1.pos - ent2.pos)**2 or just np.linalg.norm for regular distance computation. This might also be useful for other vector arithmetic operations.

Faster method of evaluating a boolean expression as a string in Python

I have been working on this project for a couple months right now. The ultimate goal of this project is to evaluate an entire digital logic circuit similar to functional testing; just to give a scope of the problem. The topic I created here deals with the issue I'm having with performance of analyzing a boolean expression. For any gate inside a digital circuit, it has an output expression in terms of the global inputs. EX: ((A&B)|(C&D)^E). What I want to do with this expression is then calculate all possible outcomes and determine how much influence each input has on the outcome.
The fastest way that I have found was by building a truth table as a matrix and looking at certain rows (won't go into specifics of that algorithm as it's offtopic), the problem with that is once the number of unique inputs goes above 26-27 (something around that) the memory usage is well beyond 16GB (Max my computer has). You might say "Buy more RAM", but as every increase in inputs by 1, memory usage doubles. Some of the expressions I analyze are well over 200 unique inputs...
The method I use right now uses the compile method to take the expression as the string. Then I create an array with all of the inputs found from the compile method. Then I generate a list row by row of "True" and "False" randomly chosen from a sample of possible values (that way it will be equivalent to rows in a truth table if the sample size is the same size as the range and it will allow me to limit the sample size when things get too long to calculate). These values are then zipped with the input names and used to evaluate the expression. This will give the initial result, after that I go column by column in the random boolean list and flip the boolean then zip it with the inputs again and evaluate it again to determine if the result changed.
So my question is this: Is there a faster way? I have included the code that performs the work. I have tried regular expressions to find and replace but it is always slower (from what I've seen). Take into account that the inner for loop will run N times where N is the number of unique inputs. The outside for loop I limit to run 2^15 if N > 15. So this turns into eval being executed Min(2^N, 2^15) * (1 + N)...
As an update to clarify what I am asking exactly (Sorry for any confusion). The algorithm/logic for calculating what I need is not the issue. I am asking for an alternative to the python built-in 'eval' that will perform the same thing faster. (take a string in the format of a boolean expression, replace the variables in the string with the values in the dictionary and then evaluate the string).
#value is expression as string
comp = compile(value.strip(), '-', 'eval')
inputs = comp.co_names
control = [0]*len(inputs)
#Sequences of random boolean values to be used
random_list = gen_rand_bits(len(inputs))
for row in random_list:
valuedict = dict(zip(inputs, row))
answer = eval(comp, valuedict)
for column in range(len(row)):
row[column] = ~row[column]
newvaluedict = dict(zip(inputs, row))
newanswer = eval(comp, newvaluedict)
row[column] = ~row[column]
if answer != newanswer:
control[column] = control[column] + 1
My question:
Just to make sure that I understand this correctly: Your actual problem is to determine the relative influence of each variable within a boolean expression on the outcome of said expression?
OP answered:
That is what I am calculating but my problem is not with how I calculate it logically but with my use of the python eval built-in to perform evaluating.
So, this seems to be a classic XY problem. You have an actual problem which is to determine the relative influence of each variable within the a boolean expression. You have attempted to solve this in a rather ineffective way, and now that you actually “feel” the inefficiency (in both memory usage and run time), you look for ways to improve your solution instead of looking for better ways to solve your original problem.
In any way, let’s first look at how you are trying to solve this. I’m not exactly sure what gen_rand_bits is supposed to do, so I can’t really take that into account. But still, you are essentially trying out every possible combination of variable assignments and see if flipping the value for a single variable changes the outcome of the formula result. “Luckily”, these are just boolean variables, so you are “only” looking at 2^N possible combinations. This means you have exponential run time. Now, O(2^N) algorithms are in theory very very bad, while in practice it’s often somewhat okay to use them (because most have an acceptable average case and execute fast enough). However, being an exhaustive algorithm, you actually have to look at every single combination and can’t shortcut. Plus the compilation and value evaluation using Python’s eval is apparently not so fast to make the inefficient algorithm acceptable.
So, we should look for a different solution. When looking at your solution, one might say that more efficient is not really possible, but when looking at the original problem, we can argue otherwise.
You essentially want to do things similar to what compilers do as static analysis. You want to look at the source code and analyze it just from there without having to actually evaluate that. As the language you are analyzing is highly restricted (being only a boolean expression with very few operators), this isn’t really that hard.
Code analysis usually works on the abstract syntax tree (or an augmented version of that). Python offers code analysis and abstract syntax tree generation with its ast module. We can use this to parse the expression and get the AST. Then based on the tree, we can analyze how relevant each part of an expression is for the whole.
Now, evaluating the relevance of each variable can get quite complicated, but you can do it all by analyzing the syntax tree. I will show you a simple evaluation that supports all boolean operators but will not further check the semantic influence of expressions:
import ast
class ExpressionEvaluator:
def __init__ (self, rawExpression):
self.raw = rawExpression
self.ast = ast.parse(rawExpression)
def run (self):
return self.evaluate(self.ast.body[0])
def evaluate (self, expr):
if isinstance(expr, ast.Expr):
return self.evaluate(expr.value)
elif isinstance(expr, ast.Name):
return self.evaluateName(expr)
elif isinstance(expr, ast.UnaryOp):
if isinstance(expr.op, ast.Invert):
return self.evaluateInvert(expr)
else:
raise Exception('Unknown unary operation {}'.format(expr.op))
elif isinstance(expr, ast.BinOp):
if isinstance(expr.op, ast.BitOr):
return self.evaluateBitOr(expr.left, expr.right)
elif isinstance(expr.op, ast.BitAnd):
return self.evaluateBitAnd(expr.left, expr.right)
elif isinstance(expr.op, ast.BitXor):
return self.evaluateBitXor(expr.left, expr.right)
else:
raise Exception('Unknown binary operation {}'.format(expr.op))
else:
raise Exception('Unknown expression {}'.format(expr))
def evaluateName (self, expr):
return { expr.id: 1 }
def evaluateInvert (self, expr):
return self.evaluate(expr.operand)
def evaluateBitOr (self, left, right):
return self.join(self.evaluate(left), .5, self.evaluate(right), .5)
def evaluateBitAnd (self, left, right):
return self.join(self.evaluate(left), .5, self.evaluate(right), .5)
def evaluateBitXor (self, left, right):
return self.join(self.evaluate(left), .5, self.evaluate(right), .5)
def join (self, a, ratioA, b, ratioB):
d = { k: v * ratioA for k, v in a.items() }
for k, v in b.items():
if k in d:
d[k] += v * ratioB
else:
d[k] = v * ratioB
return d
expr = '((A&B)|(C&D)^~E)'
ee = ExpressionEvaluator(expr)
print(ee.run())
# > {'A': 0.25, 'C': 0.125, 'B': 0.25, 'E': 0.25, 'D': 0.125}
This implementation will essentially generate a plain AST for the given expression and the recursively walk through the tree and evaluate the different operators. The big evaluate method just delegates the work to the type specific methods below; it’s similar to what ast.NodeVisitor does except that we return the analyzation results from each node here. One could augment the nodes instead of returning it instead though.
In this case, the evaluation is just based on ocurrence in the expression. I don’t explicitely check for semantic effects. So for an expression A | (A & B), I get {'A': 0.75, 'B': 0.25}, although one could argue that semantically B has no relevance at all to the result (making it {'A': 1} instead). This is however something I’ll leave for you. As of now, every binary operation is handled identically (each operand getting a relevance of 50%), but that can be of course adjusted to introduce some semantic rules.
In any way, it will not be necessary to actually test variable assignments.
Instead of reinventing the wheel and getting into risk like performance and security which you are already in, it is better to search for industry ready well accepted libraries.
Logic Module of sympy would do the exact thing that you want to achieve without resorting to evil ohh I meant eval. More importantly, as the boolean expression is not a string you don;t have to care about parsing the expression which generally turns out to be the bottleneck.
You don't have to prepare a static table for computing this. Python is a dynamic language, thus it's able to interpret and run a code by itself during runtime.
In you case, I would suggest a soluation that:
import random, re, time
#Step 1: Input your expression as a string
logic_exp = "A|B&(C|D)&E|(F|G|H&(I&J|K|(L&M|N&O|P|Q&R|S)&T)|U&V|W&X&Y)"
#Step 2: Retrieve all the variable names.
# You can design a rule for naming, and use regex to retrieve them.
# Here for example, I consider all the single-cap-lettler are variables.
name_regex = re.compile(r"[A-Z]")
#Step 3: Replace each variable with its value.
# You could get the value with reading files or keyboard input.
# Here for example I just use random 0 or 1.
for name in name_regex.findall(logic_exp):
logic_exp = logic_exp.replace(name, str(random.randrange(2)))
#Step 4: Replace the operators. Python use 'and', 'or' instead of '&', '|'
logic_exp = logic_exp.replace("&", " and ")
logic_exp = logic_exp.replace("|", " or " )
#Step 5: interpret the expression with eval(exp) and output its value.
print "exporession =", logic_exp
print "expression output =",eval(logic_exp)
This would be very fast and take very little memory. For a test, I run the example above with 25 input variables:
exporession = 1 or 1 and (1 or 1) and 0 or (0 or 0 or 1 and (1 and 0 or 0 or (0 and 0 or 0 and 0 or 1 or 0 and 0 or 0) and 1) or 0 and 1 or 0 and 1 and 0)
expression output= 1
computing time: 0.000158071517944 seconds
According to your comment, I see that you are computing all the possible combinations instead of the output at a given input values. If so, it would become a typical NP-complete Boolean satisfiability problem. I don't think there's any algorithm that could make it by a complexity lower than O(2^N). I suggest you to search with the keywords fast algorithm to solve SAT problem, you would find a lot of interesting things.

In what contexts do programming languages make real use of an Infinity value?

So in Ruby there is a trick to specify infinity:
1.0/0
=> Infinity
I believe in Python you can do something like this
float('inf')
These are just examples though, I'm sure most languages have infinity in some capacity. When would you actually use this construct in the real world? Why would using it in a range be better than just using a boolean expression? For instance
(0..1.0/0).include?(number) == (number >= 0) # True for all values of number
=> true
To summarize, what I'm looking for is a real world reason to use Infinity.
EDIT: I'm looking for real world code. It's all well and good to say this is when you "could" use it, when have people actually used it.
Dijkstra's Algorithm typically assigns infinity as the initial edge weights in a graph. This doesn't have to be "infinity", just some arbitrarily constant but in java I typically use Double.Infinity. I assume ruby could be used similarly.
Off the top of the head, it can be useful as an initial value when searching for a minimum value.
For example:
min = float('inf')
for x in somelist:
if x<min:
min=x
Which I prefer to setting min initially to the first value of somelist
Of course, in Python, you should just use the min() built-in function in most cases.
There seems to be an implied "Why does this functionality even exist?" in your question. And the reason is that Ruby and Python are just giving access to the full range of values that one can specify in floating point form as specified by IEEE.
This page seems to describe it well:
http://steve.hollasch.net/cgindex/coding/ieeefloat.html
As a result, you can also have NaN (Not-a-number) values and -0.0, while you may not immediately have real-world uses for those either.
In some physics calculations you can normalize irregularities (ie, infinite numbers) of the same order with each other, canceling them both and allowing a approximate result to come through.
When you deal with limits, calculations like (infinity / infinity) -> approaching a finite a number could be achieved. It's useful for the language to have the ability to overwrite the regular divide-by-zero error.
Use Infinity and -Infinity when implementing a mathematical algorithm calls for it.
In Ruby, Infinity and -Infinity have nice comparative properties so that -Infinity < x < Infinity for any real number x. For example, Math.log(0) returns -Infinity, extending to 0 the property that x > y implies that Math.log(x) > Math.log(y). Also, Infinity * x is Infinity if x > 0, -Infinity if x < 0, and 'NaN' (not a number; that is, undefined) if x is 0.
For example, I use the following bit of code in part of the calculation of some log likelihood ratios. I explicitly reference -Infinity to define a value even if k is 0 or n AND x is 0 or 1.
Infinity = 1.0/0.0
def Similarity.log_l(k, n, x)
unless x == 0 or x == 1
k * Math.log(x.to_f) + (n-k) * Math.log(1.0-x)
end
-Infinity
end
end
Alpha-beta pruning
I use it to specify the mass and inertia of a static object in physics simulations. Static objects are essentially unaffected by gravity and other simulation forces.
In Ruby infinity can be used to implement lazy lists. Say i want N numbers starting at 200 which get successively larger by 100 units each time:
Inf = 1.0 / 0.0
(200..Inf).step(100).take(N)
More info here: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/
I've used it for cases where you want to define ranges of preferences / allowed.
For example in 37signals apps you have like a limit to project number
Infinity = 1 / 0.0
FREE = 0..1
BASIC = 0..5
PREMIUM = 0..Infinity
then you can do checks like
if PREMIUM.include? current_user.projects.count
# do something
end
I used it for representing camera focus distance and to my surprise in Python:
>>> float("inf") is float("inf")
False
>>> float("inf") == float("inf")
True
I wonder why is that.
I've used it in the minimax algorithm. When I'm generating new moves, if the min player wins on that node then the value of the node is -∞. Conversely, if the max player wins then the value of that node is +∞.
Also, if you're generating nodes/game states and then trying out several heuristics you can set all the node values to -∞/+∞ which ever makes sense and then when you're running a heuristic its easy to set the node value:
node_val = -∞
node_val = max(heuristic1(node), node_val)
node_val = max(heuristic2(node), node_val)
node_val = max(heuristic2(node), node_val)
I've used it in a DSL similar to Rails' has_one and has_many:
has 0..1 :author
has 0..INFINITY :tags
This makes it easy to express concepts like Kleene star and plus in your DSL.
I use it when I have a Range object where one or both ends need to be open
I've used symbolic values for positive and negative infinity in dealing with range comparisons to eliminate corner cases that would otherwise require special handling:
Given two ranges A=[a,b) and C=[c,d) do they intersect, is one greater than the other, or does one contain the other?
A > C iff a >= d
A < C iff b <= c
etc...
If you have values for positive and negative infinity that respectively compare greater than and less than all other values, you don't need to do any special handling for open-ended ranges. Since floats and doubles already implement these values, you might as well use them instead of trying to find the largest/smallest values on your platform. With integers, it's more difficult to use "infinity" since it's not supported by hardware.
I ran across this because I'm looking for an "infinite" value to set for a maximum, if a given value doesn't exist, in an attempt to create a binary tree. (Because I'm selecting based on a range of values, and not just a single value, I quickly realized that even a hash won't work in my situation.)
Since I expect all numbers involved to be positive, the minimum is easy: 0. Since I don't know what to expect for a maximum, though, I would like the upper bound to be Infinity of some sort. This way, I won't have to figure out what "maximum" I should compare things to.
Since this is a project I'm working on at work, it's technically a "Real world problem". It may be kindof rare, but like a lot of abstractions, it's convenient when you need it!
Also, to those who say that this (and other examples) are contrived, I would point out that all abstractions are somewhat contrived; that doesn't mean they are useful when you contrive them.
When working in a problem domain where trig is used (especially tangent) infinity is an answer that can come up. Trig ends up being used heavily in graphics applications, games, and geospatial applications, plus the obvious math applications.
I'm sure there are other ways to do this, but you could use Infinity to check for reasonable inputs in a String-to-Float conversion. In Java, at least, the Float.isNaN() static method will return false for numbers with infinite magnitude, indicating they are valid numbers, even though your program might want to classify them as invalid. Checking against the Float.POSITIVE_INFINITY and Float.NEGATIVE_INFINITY constants solves that problem. For example:
// Some sample values to test our code with
String stringValues[] = {
"-999999999999999999999999999999999999999999999",
"12345",
"999999999999999999999999999999999999999999999"
};
// Loop through each string representation
for (String stringValue : stringValues) {
// Convert the string representation to a Float representation
Float floatValue = Float.parseFloat(stringValue);
System.out.println("String representation: " + stringValue);
System.out.println("Result of isNaN: " + floatValue.isNaN());
// Check the result for positive infinity, negative infinity, and
// "normal" float numbers (within the defined range for Float values).
if (floatValue == Float.POSITIVE_INFINITY) {
System.out.println("That number is too big.");
} else if (floatValue == Float.NEGATIVE_INFINITY) {
System.out.println("That number is too small.");
} else {
System.out.println("That number is jussssst right.");
}
}
Sample Output:
String representation: -999999999999999999999999999999999999999999999
Result of isNaN: false
That number is too small.
String representation: 12345
Result of isNaN: false
That number is jussssst right.
String representation: 999999999999999999999999999999999999999999999
Result of isNaN: false
That number is too big.
It is used quite extensively in graphics. For example, any pixel in a 3D image that is not part of an actual object is marked as infinitely far away. So that it can later be replaced with a background image.
I'm using a network library where you can specify the maximum number of reconnection attempts. Since I want mine to reconnect forever:
my_connection = ConnectionLibrary(max_connection_attempts = float('inf'))
In my opinion, it's more clear than the typical "set to -1 to retry forever" style, since it's literally saying "retry until the number of connection attempts is greater than infinity".
Some programmers use Infinity or NaNs to show a variable has never been initialized or assigned in the program.
If you want the largest number from an input but they might use very large negatives. If I enter -13543124321.431 it still works out as the largest number since it's bigger than -inf.
enter code here
initial_value = float('-inf')
while True:
try:
x = input('gimmee a number or type the word, stop ')
except KeyboardInterrupt:
print("we done - by yo command")
break
if x == "stop":
print("we done")
break
try:
x = float(x)
except ValueError:
print('not a number')
continue
if x > initial_value: initial_value = x
print("The largest number is: " + str(initial_value))
You can to use:
import decimal
decimal.Decimal("Infinity")
or:
from decimal import *
Decimal("Infinity")
For sorting
I've seen it used as a sort value, to say "always sort these items to the bottom".
To specify a non-existent maximum
If you're dealing with numbers, nil represents an unknown quantity, and should be preferred to 0 for that case. Similarly, Infinity represents an unbounded quantity, and should be preferred to (arbitrarily_large_number) in that case.
I think it can make the code cleaner. For example, I'm using Float::INFINITY in a Ruby gem for exactly that: the user can specify a maximum string length for a message, or they can specify :all. In that case, I represent the maximum length as Float::INFINITY, so that later when I check "is this message longer than the maximum length?" the answer will always be false, without needing a special case.

Categories