Back to General discussions forum
The Problem asks us to find a solution for an equation. And I tried to use sympy solver however its not working. Here is my code
from sympy.solvers import solve
from sympy import Symbol
import sympy
x = sympy.Symbol('x')
A, B, C, D = 0.59912051, 0.64030348, 263.33721367, 387.92069617
equation = solve((A * x) + (B * sympy.sqrt(x**3)) - (C * sympy.exp(-x / 50)) - D).evalf()
print(equation)
I kind of used brute force.
So I did not understand. What kind of an approach should I use ? I read the given text however I feel lost.
Thanks
Arman, hello!
And I tried to use sympy solver however its not working
Not sure what you may mean by "not working", this may work... but...
Using "sympy" for this task is what we call "overengineering" :)
The problem has no trick of any kind, just "implement it". You see it is called "Binary Search" so it is supposed to be solved by binary search.
The problem statement has a link to some explanatory article... You want Math function example part from this article. Hope this helps!
Thank you Rodion :)
I looked at the binary search and I understand the idea now.
However theres one problem. For instance if the answer for one set of data is
38.8211731863 12.6143430488 61.1255485034 25.9768946287 76.9095343872 12.773444563
I am getting
38.8211731746 12.6143430483 61.1255485427 25.9768946362 76.9095343326 12.5000000000
I have a problem in my last data and this happens all the time, for different sets of data. Any idea why the last element goes like that but others not ?
If you want I can share my code here ? If its not against the rules
Well, it seems you've put a couple of strange things into your algorithm. Speaking strictly it is not the algorithm you want :)
This is confusing for me:
num1, num2 = 0, 100
for i in range(10**4):
we need not that many iterations. moreover it may lead to precision loss (could be seen on some values if reducing amount of iterations).
Now also curious thing:
if abs(func(num1)) > abs(func(num2)):
Why "abs"? and why testing ends? - this definitely is not the correct conditional, though definitely it may work sometimes. :)
Just take func
value in the middle between num1
and num2
- your condition should rely only upon this
single value.
For each type of data I should have one larger value then 0 and one less value. However for each case A,B,C,D values are different so just taking 0 and 100 for each case gave me incorrect result I guess.
So I should change the values of num1 and num2 to get achieve a correct algorithm ?
You are right that I put the the num values twice..
I thought that increasing the range increases the accuracy at some level. It actually doesn't after a point so you are right. I ll decreaese the range
I put abs because sometimes func can be return negative values and we are checking the closeness of func(x) to 0. So according to this I thought that If I put
if (func(num1)) > (func(num2)):
it can take 100 > -50 however actually -50 is closer to zero. I did not understand "why the testing end" part that you asked to me..
I ll re-upload my code again.
Now my code works in every 3 out of 2 cases. I dont understand it... I should use abs otherwise I cannot get correct answer.
I thought that increasing the range increases the accuracy
Well, as this is "binary" search and the range is reduced twice on every step, we get great accuracy just after few dozen steps. However, if you continue, due to finite representation of numbers, num1 becomes equal to num2 and when you sum them and divide by two, it can become slightly reduced for some values...
After 30
iterations we have num2-num1 = 100 / (2^30)
i.e. about 1e-7
...
Now about algorithm - what you do is more like somewhat broken mix of Newton's algorithm with Binary search :)
See, we know that function is monotonous, so it is:
func(num1)
func(num2)
Let us use value mid = (num1+num2)/2
- the middle coordinate of the range. Let us check func(mid)
;
num1
and mid
. Hence we should reduce range to the left half, i.e. num2 = mid
...mid
and num2
, so we
shoul choose other half, i.e. num1 = mid
...However, if you continue, due to finite representation of numbers, num1 becomes equal to num2 and when you sum them and divide by two, it can become slightly reduced for some values..."
I never noticed that could be the case thanks for your tip
I also understand the algorithm. It's actually very useful... A fun problem to solve.
Thanks for helping me :)
Hello! I have problem with this task. I think my code (below) is right but my answers is different from yours a little bit. I suppose this is because of some calculation algorithms in my programm and computer and I don't know how to fix it unfortunately.
Could you please check my code? If it's right please help me to pass this problem. Thank you in advance.
import math
filename = 'binary_search.txt'
with open(filename) as f:
nums = f.readlines()
for i in range(len(nums)):
nums[i] = nums[i].rstrip()
nums[i] = nums[i].split()
for n in nums:
for i in range(len(n)):
n[i] = float(n[i])
for n in nums:
y = 0
z = 100
while True:
x = (z + y) / 2
a = n[0] * x + n[1] * math.sqrt(x**3) - n[2] * math.exp(-x/50) - n[3]
if a < 0:
y = x
else:
z = x
if len(str(x)) >= 15:
print(x, end=' ')
break
my answers = 73.590087890625 41.900634765625 your answers = 73.595368554162 41.899174957955
Hi Friend!
I think your solution is correct but doesn't calculate for enough iterations so the answer is not very precise
if len(str(x)) >= 15:
that is most queer ending condition I ever seen :) Just change it to something more reasonable and most surely you'll get right answers!