Programming Secant Method into Python - python-3.x

The sum of two numbers is 20. If each number is added to its square root, the product of the two sums is 155.55. Use Secant Method to approximate, to within 10^(-4), the value of the two numbers.

Based on http://campus.murraystate.edu/academic/faculty/wlyle/420/Secant.htm
#inital guess
x1 = 10
x2 = 50
Epsilon = 1e-4
#given function
def func(x):
return abs(x)**0.5 * (abs(x)+20)**0.5 - 155.55
y1 = func(x1)
y2 = func(x2)
#loop max 20 times
for i in range(20):
ans = x2 - y2 * (x2-x1)/(y2-y1)
y3 = func(ans)
print("Try:{}\tx1:{:0.3f}\tx2:{:0.3f}\ty3:{:0.3f}".format(i,x1, x2, y3))
if (abs(y3) < Epsilon):
break
x1, x2 = x2, ans
y1, y2 = y2, y3
print("\n\nThe numbers are: {:0.3f} and {:0.3f}".format(ans, ans+20))

Based on Your Title
This code works well in most of the cases. Taken from Secant Method Using Python (Output Included)
# Defining Function
def f(x):
return x**3 - 5*x - 9
# Implementing Secant Method
def secant(x0,x1,e,N):
print('\n\n*** SECANT METHOD IMPLEMENTATION ***')
step = 1
condition = True
while condition:
if f(x0) == f(x1):
print('Divide by zero error!')
break
x2 = x0 - (x1-x0)*f(x0)/( f(x1) - f(x0) )
print('Iteration-%d, x2 = %0.6f and f(x2) = %0.6f' % (step, x2, f(x2)))
x0 = x1
x1 = x2
step = step + 1
if step > N:
print('Not Convergent!')
break
condition = abs(f(x2)) > e
print('\n Required root is: %0.8f' % x2)
# Input Section
x0 = input('Enter First Guess: ')
x1 = input('Enter Second Guess: ')
e = input('Tolerable Error: ')
N = input('Maximum Step: ')
# Converting x0 and e to float
x0 = float(x0)
x1 = float(x1)
e = float(e)
# Converting N to integer
N = int(N)
#Note: You can combine above three section like this
# x0 = float(input('Enter First Guess: '))
# x1 = float(input('Enter Second Guess: '))
# e = float(input('Tolerable Error: '))
# N = int(input('Maximum Step: '))
# Starting Secant Method
secant(x0,x1,e,N)

Related

Nott getting same result when trying to get slope from 2 points

I'm trying to make something that would give me the slope and y-intercept from 2 points. Sometimes it would give me the correct values, but other times it would give me something close to correct but wrong.
Anyone know any thing that I could have done wrong? (Also, I feel like I should say that I'm just now starting to learn python)
y2 = input('Y2: ')
y1 = input('Y1: ')
x2 = input('X2: ')
x1 = input('X1: ')
y2 = float(y2)
y1 = float(y1)
x2 = float(x2)
x1 = float(x1)
over = y2-y1
under = x2-x1
m = over/under
y = float(y2)
x = float(x2)
m = float(m)
ym = y-m
b = ym/x
print(f'Y = {m}x + {b}')
it appears as though the mathematics for the intercept b is incorrect.
it would be logical to use the x1, y1 coordinate with the slope to generate b.
assume that you want to find x0, y0 where y0 = b. Then you would do a similar calculation (already having calculated m before as you correctly did).
So (y1-b) / x1 = m. and you can just rearrange this to get:
b = y1 - m*x1.
So this works:
x1, y1 = 1, 1
x2, y2 = 2, 2
over = y2-y1
under = x2-x1
m = over/under
b = y1 - m*x1
print(f'Y = {m}x + {b}')
returns this:
Y = 1.0x + 0.0

2101. Detonate the Maximum Bombs, why is one code optimized than another

I am trying to solve https://leetcode.com/problems/detonate-the-maximum-bombs/
the accepted solution is https://www.youtube.com/watch?v=mEB2y5_Aoos
'''
class Solution:
def maximumDetonation(self, bombs) -> int:
adj,m = defaultdict(list), len(bombs)
def canDetonate(b1,b2):
x1,y1,r1 = b1
x2,y2,r2 = b2
return (x1 - x2) ** 2 + (y1 - y2) ** 2 <= r1 ** 2
for i in range(m):
for j in range(m):
if i==j:
continue
if canDetonate(bombs[i],bombs[j]):
adj[i].append(j)
def dfs(node, seen):
seen.add(node)
for nei in adj[node]:
if nei not in seen:
dfs(nei, seen)
ctr = 0
for idx, bomb in enumerate(bombs):
seen = set()
dfs(idx,seen)
ctr = max(ctr,len(seen))
return ctr
'''
and solution I came up with is as follows:
'''
class Solution:
def isReachable(self, i1, i2, bombs) -> bool:
x1, y1, r1 = bombs[i1]
x2, y2, r2 = bombs[i2]
sol = (x1 - x2) ** 2 + (y1 - y2) ** 2 <= r1 ** 2
return sol
def maximumDetonation(self, bombs) -> int:
maxBombs = 0
def dfs(i, visited):
nonlocal maxBombs
#if bomb visited, return otherwise add to visited.
if i in visited:
return
visited.add(i)
for index in range(len(bombs)):
#for each unvisited bomb, running dfs on all other bombs.
if index not in visited and self.isReachable(i, index, bombs):
dfs(index, visited)
maxBombs = max(maxBombs, len(visited))
for i in range(len(bombs)):
#for each node i am running dfs to check how many bombs explode.
visit = set()
dfs(i, visit)
return maxBombs
'''
both solutions give correct answers for all test cases but I am wondering why their solution is more optimised than mine, as I am doing essentially the same thing. My solution keeps getting time limits exceeding error.

How could I solve the wrong that is generated from my line of sight checking?

I'm using the line of sight algorithm for a path planning problem, and I'm here checking its work, but as shown in the below picture that the line of sight checking is giving wrong results. The black tiles are paths that are checked by the line of sight, the function should also check tiles on (1,1) but it is not. How could I fix these errors?
The python code
import numpy as np
import matplotlib.pyplot as plt
grid = [[0,0,0,0,0,0,0,0],
[0,1,1,0,0,1,1,0],
[0,0,0,0,0,0,0,0],
[0,1,1,0,0,1,1,0],
[0,0,0,0,0,0,0,0]]
start, goal = (0,0), (3,2)
def lineOfSight(p, s):
x0 = p[0]
y0 = p[1]
x1 = s[0]
y1 = s[1]
dy = y1 - y0
dx = x1 - x0
f = 0
if dy < 0:
dy = -dy
sy = -1
else:
sy = 1
if dx < 0:
dx = -dx
sx = -1
else:
sx = 1
result = []
if dx >= dy:
while x0 != x1:
f = f + dy
i1 = x0 + int((sx-1)/2)
i2 = y0 + int((sy-1)/2)
if f >= dx:
result.append((i1,i2))
y0 = y0 + sy
f = f - dx
if f != 0:
result.append((i1,i2))
if dy == 0:
result.append((i1, y0))
result.append((i1, y0-1))
x0 = x0 + sx
else:
while y0 != y1:
f = f + dx
i1 = x0 + int((sx-1)/2)
i2 = y0 + int((sy-1)/2)
if f >= dy:
result.append((i1, i2))
x0 = x0 + sx
f = f - dy
if f != 0:
print((i1, i2))
if dx == 0:
result.append((x0, i2))
result.append((x0-1, i2))
y0 = y0 + sy
return result
check = lineOfSight(start,goal)
def getSquare(point):
x = [point[1], point[1]+1]
y0 = [-point[0], -point[0]]
y1 = [-(point[0]+1), -(point[0]+1)]
return (x,y0,y1)
checked = []
for xy in check:
checked.append(getSquare(xy))
plt.plot(start[1], -start[0], 'sb', label="Start Point")
plt.plot(goal[1], -goal[0], 'sg', label="Goal Point")
maxRow = len(grid)
maxCol = len(grid[0])
listRow = [-i for i in range(maxRow+1)]
listCol = [i for i in range(maxCol+1)]
xHorizontal, yHorizontal = np.meshgrid(listCol, [[0],[-maxRow]])
yVertical, xVertical = np.meshgrid(listRow, [[0],[maxCol]])
plt.plot(xHorizontal, yHorizontal, color='black')
plt.plot(xVertical, yVertical, color='black')
for square in checked:
x, y0, y1 = square
plt.fill_between(x,y0,y1, color='black')
plt.plot([start[1], goal[1]], [-start[0], -goal[0]], '-g')
plt.axis('equal')
plt.show()

How to make algorithm of counting big negative numbers faster?

I was trying to do a program which can take square matrix of any size and find two any square submatrixes(they shouldn't overlap), whose qualities are the closest. So every elementary square in matrix has a quality(any number). The problem is algorithm is too slow with processing matrixes 100*100 containing big negative numbers(-10^8).
from collections import defaultdict
from math import fsum
from itertools import islice, count
def matrix():
matritsa = list()
koord = list()
ssum = 0
diff = defaultdict(list)
size = int(input()) #size of the matrix
for line in range(size):
matritsa += list(map(int,input().split())) #filling the matrix
Q1,Q2 = map(int,input().split()) #quality range
for i in range(len(matritsa)):
element = matritsa[i]
if Q1 <= element and element <= Q2: #checking if an element is in range
koord.append([element, i//size, i%size, 1]) #coordinates of 1*1 elements
for razmer in range(2,size): #taking squares of 2+ size
#print("Razmer: ",razmer)
for a in range(len(matritsa)):
(x,y) = a//size,a%size #coordinates of the left top square
if y + razmer > size:
continue
ssum = 0
for b in range(x,x+razmer):
ssum += sum(matritsa[b*size+y:b*size+(y+razmer)])
if Q1 <= ssum and ssum <= Q2: #checking if it is in quality range
koord.append([ssum,x,y,razmer])
#print(koord)
#print("Coordinate: {0},{1}; ssum: {2}".format(x,y,ssum))
if x + razmer == size and y + razmer == size:
#print("Final: {0},{1}".format(x,y))
break
g = 0
temp = len(koord)
while g != temp:
(value1,x1,y1,a) = koord[g]
for i in range(g,temp - 1):
(value2,x2,y2,b) = koord[i+1]
if y1 >= y2 + b or y2 >= y1 + a:
diff[abs(value1 - value2)].append([value1,value2])
if x1 >= x2 + b or x2 >= x1 + a:
diff[abs(value1 - value2)].append([value1,value2])
g += 1
minimum = min(diff.keys())
if minimum == 0:
print(*max(diff[minimum]))
elif len(diff[minimum]) > 1:
maximum = sum(diff[minimum][0])
result = diff[minimum][0]
for pair in diff[minimum]:
if sum(pair) > maximum:
maximum = sum(pair)
result = pair
The problem is in this part
g = 0
temp = len(koord)
print(temp)
while g != temp:
(value1,x1,y1,a) = koord[g]
for i in range(g,temp - 1):
(value2,x2,y2,b) = koord[i+1]
if y1 >= y2 + b or y2 >= y1 + a:
diff[abs(value1 - value2)].append([value1,value2])
if x1 >= x2 + b or x2 >= x1 + a:
diff[abs(value1 - value2)].append([value1,value2])
g += 1

TypeError: a float is required in python 3

I have a Python3 script as follows:
import math
Value_1 = float(input("what's the X1 value?")), float(input("what's the X2 value?"))
Value_2 = float(input("what's the Y1 value?")), float(input("what's the Y2 value?"))
equation =(math.sqrt(math.sqrt(Value_1)+ math.sqrt(Value_2)))
print (equation)
with this output
what's the X1 value?3.0
what's the X2 value?12.0
what's the Y1 value?10.0
what's the Y2 value?110.0
Then the program return this error:
TypeError Traceback (most recent call last)
<ipython-input-15-cc8d8b28ff67> in <module>()
5
6
----> 7 equation = float(math.sqrt(math.sqrt(Value_1)+ math.sqrt(Value_2)))
8
9 print (equation)
TypeError: a float is required
I have tried to use all tips for other questions but error persist. Any tips?
no one cares about my question but I figure out it by myself. Here we go:
import math
x1 = float(input("what's the X1 value?"))
x2 = float (input("what's the X2 value?"))
print (x2 - x1)
xdiff = abs (x2 - x1)
print (xdiff)
y1 = float(input("what's the y1 value?"))
y2 = float (input("what's the y2 value?"))
ydiff = abs(y2 - y1)
print (ydiff)
math.sqrt(math.pow(xdiff,2) + math.pow(ydiff,2))
What is the problem?
By assigning to inputs to Value_1, separated by a comma, you are defining a tuple. As a short example for this:
In [1]: tup = 42, 23
In [2]: type(tup)
Out[2]: tuple
However, the math.sqrt function requires a float value as input, not a tuple.
How to solve this
You can use tuple unpacking to keep the structure of your original post intact:
import math
# read in x and y value of the first point and store them in a tuple
point_1 = float(input("What is the x value of point 1? ")), float(input("What is the y value of point 1? "))
# read in x and y value of the second point and store them in a tuple
point_2 = float(input("What is the x value of point 2? ")), float(input("What is the y value of point 2? "))
# This is where the tuple unpacking happens.
# After this you have the x and y values
# of the points in their respective variables.
p1_x, p1_y = point_1
p2_x, p2_y = point_2
# At this point you can use point_1 when you need both x and y value of
# of the first point. If you need only the x or y value you can use the
# unpacked coordinates saved in p1_x and p1_y respectively.
x_diff = abs(p1_x - p2_x)
y_diff = abs(p1_y - p2_y)
distance = math.sqrt(math.pow(x_diff, 2) + math.pow(y_diff, 2))
print("Distance of {} and {} is {}".format(point_1, point_2, distance))
As you can see above it can be helpful to save the information for the point as a tuple first and then use the unpacked coordinates at at a different point.
I hope this sheds some light on what happened.

Resources