Pagini: [1]   În jos
  Imprimă  
Ajutor Subiect: Why is your bisection search wrong  (Citit de 7996 ori)
0 Utilizatori şi 1 Vizitator pe acest subiect.
Cosmin
Echipa infoarena
Nu mai tace
*****

Karma: 351
Deconectat Deconectat

Mesaje: 1.799



Vezi Profilul
« : Mai 19, 2014, 06:49:33 »

http://www.infoarena.ro/blog/your-bisection-search-is-wrong
Memorat
DaeMoohn
Strain


Karma: 0
Deconectat Deconectat

Mesaje: 1



Vezi Profilul
« Răspunde #1 : Mai 19, 2014, 09:46:31 »

The relative error concept looks interesting
Memorat
MciprianM
Nu mai tace
*****

Karma: 87
Deconectat Deconectat

Mesaje: 324



Vezi Profilul
« Răspunde #2 : Mai 19, 2014, 10:47:12 »

Hello!

I have a few questions and observations.

First of all, when I first tried to solve this problem, instead of using the simple thing that you did for applying the algorithm to negative numbers, I tried to complicate things by using (-MAX, MAX) range. That was not such a good idea, but it led me to finding that lo + (hi - lo) might overflow too. Namely, if lo is low enough(and negative too) and hi is hi enough, then hi - lo will turn into an large number that could overflow. So hi - lo is good enough, if hi and lo are greater than or equal to 0. In general, always check the range of values that can occur as inputs and check whether the outputs and the intermediate values fit the type.

Second, could you please specify how do we compute that magic constant(120) that you used for the number of iterations? Are there any risks, if that number is too high (besides TLE, smth like roundoff errors)? As an example, my python interpreter shows 999999999999.3113 as a result for cubicRoot(1e36); the exact result would be 1e12. The difference is greater than 0.1

Third, who considered float is a good enough default type for real numbers?

How does this algorithm perform for really small, really large and really close too zero numbers(close to the limits of what the type can hold)?

Thanks!

L.E.: Just noticed the "Tomek" addition to the text. My C++ compiler says that 3.4028235e+038 is the max value for float(numeric_limits<float>::max()).
Memorat
Cosmin
Echipa infoarena
Nu mai tace
*****

Karma: 351
Deconectat Deconectat

Mesaje: 1.799



Vezi Profilul
« Răspunde #3 : Mai 19, 2014, 10:50:08 »

As you can see Tomek already pointed out that for large numbers my number of iterations is bad and you need about 1100 steps instead of 120. Will add a paragraph about that tomorrow. It's 2am here Smile. I think python doesn't have floats it uses doubles.
Memorat
MciprianM
Nu mai tace
*****

Karma: 87
Deconectat Deconectat

Mesaje: 324



Vezi Profilul
« Răspunde #4 : Mai 19, 2014, 10:56:08 »

Sorry!

I didn't see that comment when I started writing my comment. Also, there are also other questions in my comment that I would like you to address besides that tomorrow.

Thank you and have a good night.

L.E.: It looks like in python it is called float(as in floating type), but it has the value range of C++'s double: [2.2250738585072014e-308, 1.7976931348623157e+308]. So it might be that in python there's, in fact, only "double".
« Ultima modificare: Mai 19, 2014, 11:04:19 de către Marginean Ninu Ciprian » Memorat
Cosmin
Echipa infoarena
Nu mai tace
*****

Karma: 351
Deconectat Deconectat

Mesaje: 1.799



Vezi Profilul
« Răspunde #5 : Mai 19, 2014, 14:06:30 »

I think your only question left unanswered is the one about the behavior for really small numbers and really large numbers. I see that the code returns reasonable results for c = 1e+305 and c = 1e-305 and the results are equal to those of pow(c, 1.0/3).
Memorat
raduberinde
Strain
*

Karma: 13
Deconectat Deconectat

Mesaje: 26



Vezi Profilul
« Răspunde #6 : Mai 19, 2014, 17:15:33 »

When you are interested in guaranteeing relative error, doesn't it make more sense to use the geometric mean as the midpoint, i.e. sqrt(low*high) ?   (equivalent to "regular" binary search of ln(x))
Memorat
Cosmin
Echipa infoarena
Nu mai tace
*****

Karma: 351
Deconectat Deconectat

Mesaje: 1.799



Vezi Profilul
« Răspunde #7 : Mai 19, 2014, 23:23:19 »

@Radu yes, good point, binary searching on the logarithm works. Also it converges faster, especially on large numbers. In fact it takes 64 steps since now at each step you find a bit of the answer. But it's a bit of a cheat since I mentioned using only +,-,*,/
« Ultima modificare: Mai 19, 2014, 23:37:13 de către Cosmin Negruseri » Memorat
rgrig
De-al casei
***

Karma: 46
Deconectat Deconectat

Mesaje: 144



Vezi Profilul WWW
« Răspunde #8 : Mai 20, 2014, 02:07:49 »

You made me implement this :p
I did it quickly, so very likely I have bugs.

Python3:
Cod:
from math import frexp

def cube(y):
  return y * y * y

def cr_subunit(x):
  assert (0 <= x and x <= 1)
  delta = 1
  y = 0
  while cube(y) != cube(y + delta):
    delta /= 2
    if cube(y + delta) < x:
      y += delta
  return y

cr_two = 1.2599210498948731647672106072782283505702

def cr_powtwo_nn(e):
  if e == 0:
    return 1
  x = cr_powtwo_nn(e // 2)
  x = x * x
  if e % 2 == 1:
    x *= cr_two
  return x

def cr_powtwo(e):
  if e >= 0:
    return cr_powtwo_nn(e)
  else:
    return 1/cr_powtwo_nn(-e)

def cr_pos(x):
  m, e = frexp(x)
  return cr_subunit(m) * cr_powtwo(e)

def cr(x):
  if x > 0:
    return cr_pos(x)
  else:
    return -cr_pos(-x)
Memorat
Cosmin
Echipa infoarena
Nu mai tace
*****

Karma: 351
Deconectat Deconectat

Mesaje: 1.799



Vezi Profilul
« Răspunde #9 : Mai 20, 2014, 02:35:46 »

haha, neat. good job. looks reasonable to me.
Memorat
madno
Strain


Karma: 0
Deconectat Deconectat

Mesaje: 1



Vezi Profilul
« Răspunde #10 : Martie 07, 2016, 19:31:21 »

Just a small typo, I think you meant:

"while abs(c - lo * lo * lo) >= 1e-3:"
Memorat
Pagini: [1]   În sus
  Imprimă  
 
Schimbă forumul:  

Powered by SMF 1.1.19 | SMF © 2006-2013, Simple Machines