Calculating closest numbers numpy - python

I'm trying to calculate the closest numbers to 0 but couldn't get what I want so far.
I have a quite simple code;
y = 0.0
x = 0.1
while (y + x > y):
x = x/2.0
x*2
But I keep getting 0.0 as output. How can I fix this

I guess you want to Keep dividing until x becomes so small it becomes to zero (in floating point format). In the last iteration of your loop x becomes finally zero and the loop condition turnes out to be false:
0.0(y) + 0.0(x) > 0.0(y). At the last line you try to retrieve the x-value by multiplying by two. But x is already zero, so the result is also zero. Mathematically is makes total sense, but the floating point value is already zero at that point.
In order to keep the latest non-zero value use a second variable:
y = 0.0
x = 0.1
smallest_x = x
while (y + x > y):
smallest_x = x
x = x/2.0
x*2
Or alternatively you check beforehand if x becomes zero after divinding once more:
y = 0.0
x = 0.1
while (y + x/2.0 > y): //checking if the next division makes x to zero
x = x/2.0
x*2
Or take a different approach to get the smallest x:
x = 1.0
while (x/2.0 != 0):
x = x/2.0

You could simply use np.nextafter:
>>> np.nextafter(0, 1)
4.9406564584124654e-324

Maybe you just searching for minimal float number:
import sys
print(sys.float_info.min)

Related

Newton's method of succesive approximations

I was trying to build a program to based on the inputs use Newton's method of successive approximations and calculate the answer, using while and if statements, but after running the program, it only collects the input from the user and do not follow up with anything.
I would really appreciate some help.
x = float(input("Number you want to know, the square root of: "))
y = float(input("What is your guess ? "))
z = float
a = float
while (True):
if (abs(y - x) < 0.001):
print (y)
break
else:
z = (x / y)
a = ((z + y)/2)
y = a
Consider the case where you want to know the square root of 2. So x will be 2 and y will approach the correct answer. x never changes here, so when will abs(√2 - 2) even be less than 0.001? Then answer is never, which is why your code never exists the loop.
You should be comparing the previous estimate to the new estimate and stopping when the updated value is lower than you tolerance. For example:
x = 2
y = 1
while (True):
print (y)
a = ((x / y + y)/2)
if abs(y - a) < .000001: # has the estimate changed enough?
break
y = a
Will quickly converge, printing:
1
1.5
1.4166666666666665
1.4142156862745097
1.4142135623746899
you can try :
while(True):
if (abs(y*y - x) < 0.001)

Maximum value of given equation with range of x values

How can I find the maximum value of the following equation: Fp=(1000 + 9*(x**2) - (183)*x) Given values of x in the range of (1-10), using python. This is what I have tried already:
L= range(1, 11)
for x in L:
Fp=(1000 + 9*(x**2) - (183)*x)
Td=20 - 0.12*(x**2) + (4.2)*x
print(Fp, Td)
print(max(Fp))
Assuming that you have the set of natural numbers in mind, since you have a small range of numbers to check (only 10 numbers), the first approach would be to check the value of the equation for every number, save it in a list, and find the maximum of that list. Take a look at the code below.
max_list = []
for x in range(1,11):
Fp = (1000 + 9*(x**2) - (183)*x)
max_list.append(Fp)
print( max(max_list) )
Another more elegant approach is to analyze the equation. Since your Fp equation is a polynomial equation with the positive second power coeficent, you can assume that either the last element of the range is going to yield the maximum or the first.
So you only need to check those values.
value_range = (1,10)
Fp_first = 1000 + 9*(value_range[0]**2) - (183)*value_range[0]
Fp_last = 1000 + 9*(value_range[1]**2) - (183)*value_range[1]
max_val = max(Fp_first , Fp_last)
You could do it like this:-
def func(x):
return 1_000 + 9 * x * x - 183 * x
print(max([func(x) for x in range(1, 11)]))
The problem with your code is that you're taking the max of a scalar rather than of the values of Fp for each of the values of x.
For a small range of integer values of x, you can iterate over them as you do. And, if you only need the max value,
L = range(1, 11)
highest_Fp = 0 # ensured lower than any Fp value
for x in L:
Fp = (1000 + 9*(x**2) - (183)*x)
Td = 20 - 0.12*(x**2) + (4.2)*x
print(Fp, Td)
if Fp > highest_Fp:
highest_Fp = Fp
print(highest_Fp)

converting floats to fractions

I’m writing in Python3.
I created two lists in my code and I want to ‘connect’ them in a loop as fractions. Is there any possibility to do it in another way than using Fractions library? Unfortunately I can’t use it because it’s the task requirement. The problem comes up when fraction is a floating point number (for example 1/3).
How can I solve this problem?
Here's an example:
p = [1,2,3]
q = [3,5,9]
frac = []
for i in p:
for j in q:
f = i/j
if f not in frac:
frac.append(f)
You can use the fractions.Fraction type.
import this using: from fractions import Fraction
cast your f equation f = p/q with Fraction; f = Fraction(p/q)
then use the string conversion as well; f = str(Fraction(p/q))
from fractions import Fraction
f = str(Fraction(p/q))
If I understood correctly your problem is not on "how to convert floats to fractions" but yes "how to get a string representation of fraction from arrays of numbers", right?
Actually you can do that in one line:
p = [1,2,3]
q = [3,5,9]
list(map(lambda pair: f"{pair[0]}/{pair[1]}", [(x, y) for x in p for y in q])))
Explaining:
map - receives a function and an iterator, passing each element of the iterator to that function.
[(x, y) for x in p for y in q] - this is a list comprehension, it is generating pairs of numbers "for each x in array p for each y in array q".
lambda pair - this is an anonymous function receiving an argument pair (which we know will be a tuple '(x, y)') and returns the string "x/y" (which is "pair[0]/pair[1]")
Optional procedures
Eliminate zeros in denominator
If you want to avoid impossible fractions (like anything over 0), the list comprehension should be this one:
[(x, y) for x in p for y in q if x != 0]
Eliminate duplicates
Also, if on top of that you want to eliminate duplicate items, just wrap the entire list in a set() operation (sets are iterables with unique elements, and converting a list to a set automatically removes the duplicate elements):
set([(x, y) for x in p for y in q if x != 0])
Eliminate unnecessary duplicate negative signs
The list comprehension is getting a little bigger, but still ok:
set([(x, y) if x>0 or y>0 else (-x,-y) for x in p for y in q if x != 0])
Explaining: if x>0 or y>0, this means that only one of them could be a negative number, so that's ok, return (x,y). If not, that means both of them are negative, so they should be positive, then return (-x,-y).
Testing
The final result of the script is:
p = [1, -1, 0, 2, 3]
q = [3, -5, 9, 0]
print(list(map(lambda pair: f"{pair[0]}/{pair[1]}", set([(x, y) if x>0 or y>0 else (-x,-y) for x in p for y in q if y != 0]))))
# output:
# ['3/-5', '2/-5', '1/5', '1/-5', '0/3', '0/9', '2/3', '2/9', '3/3', '-1/3', '-1/9', '0/5', '3/9', '1/3', '1/9']
(0.33).as_integer_ratio() could work for your problem. Obviously 0.33 would be replaced by whatever float.
Per this question,
def float_to_ratio(flt):
if int(flt) == flt:
return int(flt), 1
flt_str = str(flt)
flt_split = flt_str.split('.')
numerator = int(''.join(flt_split))
denominator = 10 ** len(flt_split[1])
return numerator, denominator
this is also a solution.
You can use a loop to figure out the fraction by the simple code below
x = 0.6725
a = 0
b = 1
while (x != a/b):
if x > a/b:
a += 1
elif x < a/b:
b += 1
print(a, b)
The result of a and b is going to be
269 400

Finding number of pythagorean triples in a list using python?

I am coding a solution for a problem where the code will find the number of Pythagorean triples in a list given a list a. However, when I submit my code to the auto-grader, there are some test cases where my code fails, but I have no idea what went wrong. Please help me point out my mistake.....
def Q3(a):
lst = [i ** 2 for i in a]
lst.sort()
ans = 0
for x in lst:
for y in lst:
if (x + y) in lst:
ans += 1
return ans // 2
"Pythagorean triples" are integer solutions to the Pythagorean Theorem, for example, 32+42=52. Given a list of positive integers, find the number of Pythagorean triplets. Two Pythagorean triplets are different if at least one integer is different.
Implementation
· Implement a function Q3(A), where the A is a list of positive integers. The size of list A is up to 250.
· There are no duplicates in the list A
· This function returns the number of Pythagorean triplets.
Sample
· Q3( [3,4,6,5] ) = 1
· Q3( [4,5,6] ) = 0
Simple but not very efficient solution would be to loop through the list of numbers in the range (I have taken number from 1 to 100 for instance) in 3 nested for loops as below. But it would be slower as for 100 elements, it needs to have 100^3 operations
triplets = []
for base in range(1,101):
for height in range(1,101):
for hypotenuse in range(1,101):
# check if forms a triplet
if hypotenuse**2 == base**2 + height**2:
triplets.append(base, height, hypotenuse)
This can be made slightly more efficient (there are better solutions)
by calculating hypotenuse for each base and height combination and then check if the hypotenuse is an Integer
triplets = []
for base in range(1,101):
for height in range(1,101):
hypotenuse = math.sqrt(base**2 + height**2)
# check if hypotenuse is integer by ramiander division by 1
if hypotenuse%1==0:
triplets.append(base, height, hypotenuse)
# the above solution written a list comprehension
a = range(1,101)
[(i,j,math.sqrt(i*i+j*j)) for i in a for j in a if math.sqrt(i*i+j*j)%1==0]
If you consider (3,4,5) and (3,5,4) as different, use a set instead of list and get the len(triplets_set) in the end
Problem 1: Suppose your input is
[3,4,5,5,5]
Though it's somewhat unclear in your question, my presumption is that this should count as three Pythogorean triples, each using one of the three 5s.
Your function would only return 1.
Problem 2: As Sayse points out, your "triple" might be trying to use the same number twice.
You would be better off using itertools.combinations to get distinct combinations from your squares list, and counting how many suitable triples appear.
from itertools import combinations
def Q3(a):
squares = [i**2 for i in a]
squares.sort()
ans = 0
for x,y,z in combinations(squares, 3):
if x + y == z:
ans += 1
return ans
Given the constraints of the input you now added to your question with an edit, I don't think there's anything logically wrong with your implementation. The only type of test cases that your code can fail to pass has to be performance-related as you are using one of the slowest solutions by using 3 nested loops iterating over the full range of the list (the in operator itself is implemented with a loop).
Since the list is sorted and we want x < y < z, we should make y start from x + 1 and make z start from y + 1. And since given an x, the value of x depends on the value of y, for each given y we can increment z until z * z < x * x + y * y no longer holds, and if z * z == x * x + y * y at that point, we've found a Pythagorean triple. This allows y and z to sweep through the values above x only once and therefore reduces the time complexity from O(n^3) to O(n^2), making it around 40 times faster when the size of the list is 250:
def Q3(a):
lst = [i * i for i in sorted(a)]
ans = 0
for x in range(len(lst) - 2):
y = x + 1
z = y + 1
while z < len(lst):
while z < len(lst) and lst[z] < lst[x] + lst[y]:
z += 1
if z < len(lst) and lst[z] == lst[x] + lst[y]:
ans += 1
y += 1
return ans

Adding two given floating point numbers in Python?

How would I create a method with Python to add floating point numbers that are in a list, without using libraries?. The teacher gave us this code, and I didn't understand it, could anyone else give me another example?
def msum(iterable):
"Full precision summation using multiple floats for intermediate values"
partials = [] # sorted, non-overlapping partial sums
for x in iterable:
i = 0
for y in partials:
if abs(x) < abs(y):
x, y = y, x
hi = x + y
lo = y - (hi - x)
if lo:
partials[i] = lo
i += 1
x = hi
partials[i:] = [x]
return sum(partials, 0.0)
A version of the Kahan algorithm in python would look like this:
def msum(input):
sum = 0.0
c = 0.0
for x in input:
y = x - c
t = sum + y
c = (t - sum) - y
sum = t
return sum
And what does "without using other libraries" even mean? Of course you could just have
def msum(input):
return sum(input)

Categories