map values to a specific range - python

Let say we have some angular values from -inf to +inf as input.
I'd like to map them between only -180 and +180.
How could I properly achieve that?
Here's what I've found so far:
(i-180)%360-180
It works fine, but it maps +180 to -180 which I would like to be +180->+180.
Technically it's the same for my purpose so it's not a big deal, but it would be aesthetically better.
I'm working with Python but it doesn't really matter here.

If you don't value mathematical aestheticism as much, I think this could work
def f(i):
x = i % 360
if x > 180:
x -= 360
elif x == 180 and i < 0:
x = -x
return x

Suppose you have values in the range -inf to inf in a list sampleList[].
You need to map the values in sampleList[] in range -180 to 180. Lets name the new list of mapped elements as mappedList[]
Consider x as element in sampleList[]
Consider y as element in mappedList[]
Consider maxSL as maximum of sampleList[] and
minSL as minimum of sampleList[]
Therefore,
y = ((x - minSL)(((180-(-180))/(maxSL - minSL))) + (-180)

Related

Sum of two squares in Python

I have written a code based on the two pointer algorithm to find the sum of two squares. My problem is that I run into a memory error when running this code for an input n=55555**2 + 66666**2. I am wondering how to correct this memory error.
def sum_of_two_squares(n):
look=tuple(range(n))
i=0
j = len(look)-1
while i < j:
x = (look[i])**2 + (look[j])**2
if x == n:
return (j,i)
elif x < n:
i += 1
else:
j -= 1
return None
n=55555**2 + 66666**2
print(sum_of_two_squares(n))
The problem Im trying to solve using two pointer algorithm is:
return a tuple of two positive integers whose squares add up to n, or return None if the integer n cannot be so expressed as a sum of two squares. The returned tuple must present the larger of its two numbers first. Furthermore, if some integer can be expressed as a sum of two squares in several ways, return the breakdown that maximizes the larger number. For example, the integer 85 allows two such representations 7*7 + 6*6 and 9*9 + 2*2, of which this function must therefore return (9, 2).
You're creating a tuple of size 55555^2 + 66666^2 = 7530713581
So if each element of the tuple takes one byte, the tuple will take up 7.01 GiB.
You'll need to either reduce the size of the tuple, or possibly make each element take up less space by specifying the type of each element: I would suggest looking into Numpy for the latter.
Specifically for this problem:
Why use a tuple at all?
You create the variable look which is just a list of integers:
look=tuple(range(n)) # = (0, 1, 2, ..., n-1)
Then you reference it, but never modify it. So: look[i] == i and look[j] == j.
So you're looking up numbers in a list of numbers. Why look them up? Why not just use i in place of look[i] and remove look altogether?
As others have pointed out, there's no need to use tuples at all.
One reasonably efficient way of solving this problem is to generate a series of integer square values (0, 1, 4, 9, etc...) and test whether or not subtracting these values from n leaves you with a value that is a perfect square.
You can generate a series of perfect squares efficiently by adding successive odd numbers together: 0 (+1) → 1 (+3) → 4 (+5) → 9 (etc.)
There are also various tricks you can use to test whether or not a number is a perfect square (for example, see the answers to this question), but — in Python, at least — it seems that simply testing the value of int(n**0.5) is faster than iterative methods such as a binary search.
def integer_sqrt(n):
# If n is a perfect square, return its (integer) square
# root. Otherwise return -1
r = int(n**0.5)
if r * r == n:
return r
return -1
def sum_of_two_squares(n):
# If n can be expressed as the sum of two squared integers,
# return these integers as a tuple. Otherwise return <None>
# i: iterator variable
# x: value of i**2
# y: value we need to add to x to obtain (i+1)**2
i, x, y = 0, 0, 1
# If i**2 > n / 2, then we can stop searching
max_x = n >> 1
while x <= max_x:
r = integer_sqrt(n-x)
if r >= 0:
return (i, r)
i, x, y = i+1, x+y, y+2
return None
This returns a solution to sum_of_two_squares(55555**2 + 66666**2) in a fraction of a second.
You do not need the ranges at all, and certainly do not need to convert them into tuples. They take a ridiculous amount of space, but you only need their current elements, numbers i and j. Also, as the friendly commenter suggested, you can start with sqrt(n) to improve the performance further.
def sum_of_two_squares(n):
i = 1
j = int(n ** (1/2))
while i < j:
x = i * i + j * j
if x == n:
return j, i
if x < n:
i += 1
else:
j -= 1
Bear in mind that the problem takes a very long time to be solved. Be patient. And no, NumPy won't help. There is nothing here to vectorize.

How to find the distance between two elements in a 2D array

Let's say you have the grid:
list = [[-,O,-,-,O,-,],
[O,-,-,-,-,O],
[O,O,-,-,X,-],
[-,-,O,-,-,-]]
How would you get the coordinates of all O's that are within a distance of 3 from X?
From what I saw in other answers, using scipy.spatial.KDTree.query_ball_point seemed like a common approach but I was unable to figure out how to adapt it to my use case. One possible idea I had was to store every coordinate of the list such as
coords=[[0,0],[0,1]...] and then use the scipy method and pass in the coordinate of the X and the searching distance. And then once I received the list of possible coordinates, I then iterate through the list and check which ones are equal to O. I was wondering, however, if there was a more efficient or more optimized solution I could use. Any help would be greatly appreciated.
You don't need to make it too complicate by using Scipy. This problem can easily done by help of mathematics.
Equation of coordinate inside circle is x^2 + y^2 <= Radius^2, so just check coordinate that inside the circle.
list = [[-,O,-,-,O,-,],
[O,-,-,-,-,O],
[O,O,-,-,X,-],
[-,-,O,-,-,-]]
X_coor = #Coordinate of X, in this case y = 2, x = 4
d = #Maximum distance from X in this case d = 3
total = 0
O_coor = [] #Store coordinate of all O near X
for y in range(max(0, X_coor.y - d), min(list.length - 1, X_coor.y + d)):
for x in range(max(0, X_coor.x - sqrt(d**2 - (y - X_coor.y)**2)), min(list.length - 1, X_coor.x + sqrt(d**2 - (y - X_coor.y)**2))):
if list[y][x] == "O":
total++
O_coor.append([x, y])
print(total)
print(O_coor)
It a long code, but you can ask me parts that you don't understand.
Note: This solution check only coordinate in circle area not entire list, so even if you have large list this still very fast.

How do I evaluate this equation in z3 for python

I'm trying to evaluate a simple absolute value inequality like this using z3.
x = Int("x")
y = Int("y")
def abs(x):
return If(x >= 0,x,-x)
solve(abs( x / 1000 - y / 1000 ) < .01, y==1000)
The output is no solution every time. I know this is mathematically possible, I just can't figure out how z3 does stuff like this.
This is a common gotcha in z3py bindings. Constants are "promoted" to fit into the right type, following the usual Python methodology. But more often than not, it ends up doing the wrong conversion, and you end up with a very confusing situation.
Since your variables x and y are Int values, the comparison against .01 forces that constant to be 0 to fit the types, and that's definitely not what you wanted to say. The general advice is simply not to mix-and-match arithmetic like this: Cast this as a problem over real-values, not integers. (In general SMTLib doesn't allow mixing-and-matching types in numbers, though z3py does. I think that's misguided, but that's a different discussion.)
To address your issue, the simplest thing to do would be to wrap 0.01 into a real-constant, making the z3py bindings interpret it correctly. So, you'll have:
from z3 import *
x = Int("x")
y = Int("y")
def abs(x):
return If(x >= 0,x,-x)
solve(abs( x / 1000 - y / 1000 ) < RealVal(.01), y==1000)
Note the use of RealVal. This returns:
[x = 1000, y = 1000]
I guess this is what you are after.
But I'd, in general, recommend against using conversions like this. Instead, be very explicit yourself, and cast this as a problem, for instance, over Real values. Note that your division / 1000 is also interpreted in this equation as an integer division, i.e., one that produces an integer result. So, I'm guessing this isn't really what you want either. But I hope this gets you started on the right path.
Int('a') < 0.01 is turned (rightly or wrongly) into Int('a') < 0 and clearly the absolute value can never be smaller than 0.
I believe you want Int('a') <= 0 here.
Examples:
solve(Int('a') < 0.01, Int('a') > -1)
no solution
solve(Int('a') <= 0.01, Int('a') > -1)
[a = 0]
Int('a') < 0.01
a < 0

Python feedback loop in order to obtain a specific amount of points in a range about a median

I have a list x of number values.
To begin, I specify a range. I want to grab values from x that lie within this range. The range of values would be ±R from the median of x. I want to adjust R to obtain a specific amount of values N. The only way I can see of achieving this is through some kind of feedback loop. What would be a quick and efficient way of getting closest to N as possible?
eg.
x = ['3','5','1','2','4']
I want the range of values from 3-R<3<3+R as 3 is the median. Let's say N = 3. The obtained values would be ['2','3','4'] with R worked as as 1.
EXAMPLE CODE:
N = 3
x = ['3','5','1','2','4']
R = 1
n = some number to allow room for error
y = values of x in range ±R from median
while len(y) > N+n or len(y) < N-n:
if len(y) > N+n:
R -= ADJUST VALUE PROPORTIONAL TO ERROR HERE?
if len(y) < N-n:
R += ADJUST VALUE PROPORTIONAL TO ERROR HERE?
y = values of x in range ±R from median (update y list with new R)
Naively, I'd try kind of a Bolzano theorem approach. You get the median, then the value that is furthest from the median, and call the distance between them L0. That will include all the points, of course. Then you divide L0 by 2 and check how many points lie within the interval. Is it still too many or too little?
If too many, L0=L and L = L0/2.
If they are too few, L=(L0+L)/2.
Thus, you will bracket into a solution recursively.

Python: Coordinate Conversion

I have a slice of a set of lists of coordinates a[:,4]. It is in astronomical coordinates, which I'd like to convert to decimal. However, it currently doesn't work for negative astronomical coordinates. I currently have:
if any(a[:,4] < 0 ):
b[:,1] = a[:,4] - a[:,5]/60 - a[:,6]/3600 - a[:,7]/360000
else:
b[:,1] = a[:,4] + a[:,5]/60 + a[:,6]/3600 + a[:,7]/360000
print b
The aim of this is to get it to identify if the coordinate is negative or not from the a[:,4] coordinate and then process the other coordinates one way if it is negative, and the other way if it is positive. However, the "if any" line doesn't appear to be working.
For example, -09:24:40.25 should convert to -9.41118, but it currently converts to -8.58882, as the negative "hours" coordinate is then having the arcminute, arcsecond and milliarcsecond coordinates added to it, instead of them being subtracted.
I'm not sure what I'm doing wrong.
Thanks!
You can't use the any function like that assuming you're using a python list, as it takes an iterable and returns true if ANY of that iterable is true
a < 0
won't return an iterable
replace it with
[i < 0 for i in a[:,4]]
or
map(lambda x: x < 0 ,a[:,4])
so that the if statement becomes
if any(map(lambda x: x < 0,a[:,4])):
or
if any([i < 0 for i in a[:,4]])

Categories