How do I handle mixed input to a Python function, ie: 5x?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • TMS
    New Member
    • Sep 2006
    • 119

    #1

    How do I handle mixed input to a Python function, ie: 5x?

    I'm working through the bisection method to find the root of a function. I'm asking patience (yet again) because I haven't used this method for a while. I found the formula on wikipedia.

    Pseudocode is as follows:

    start loop
    Do While (xR - xL) > epsilon

    'calculate midpoint of domain
    xM = (xR + xL) / 2

    'Find f(xM)
    If ((f(xL) * f(xM)) > 0 Then
    'throw away left half
    xL = xM
    else
    'throw away right half
    xR = xM
    End If
    Loop

    I'm trying to make my way through this and I have some questions about how Python handles an equation like 5x^8 - 3x^4 + x - 2? If I try it from the shell I get an error message from the x since its with the 5, so I assume it confused about what I'm asking.

    A friend told me to use eval(function) but I'm not sure how to use it in my code, or if it is even the best way to go.

    Mind you, this is a starting point. There will be MANY more questions before I'm done with this assignment.

    The function is to look like this:

    def root_find(f, xLo, xHi, eps)

    So, if I test the above so that f = 5x**8 - 3x**4 + x - 2. by saying y0 = f(xLo) I will get an error, right? How do I format the input so the function will use it? Am I even asking the right question? (I'm so lost!)


    thank you for helping
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    Originally posted by TMS
    I'm working through the bisection method to find the root of a function. I'm asking patience (yet again) because I haven't used this method for a while. I found the formula on wikipedia.

    Pseudocode is as follows:

    start loop
    Do While (xR - xL) > epsilon

    'calculate midpoint of domain
    xM = (xR + xL) / 2

    'Find f(xM)
    If ((f(xL) * f(xM)) > 0 Then
    'throw away left half
    xL = xM
    else
    'throw away right half
    xR = xM
    End If
    Loop

    I'm trying to make my way through this and I have some questions about how Python handles an equation like 5x^8 - 3x^4 + x - 2? If I try it from the shell I get an error message from the x since its with the 5, so I assume it confused about what I'm asking.

    A friend told me to use eval(function) but I'm not sure how to use it in my code, or if it is even the best way to go.

    Mind you, this is a starting point. There will be MANY more questions before I'm done with this assignment.

    The function is to look like this:

    def root_find(f, xLo, xHi, eps)

    So, if I test the above so that f = 5x**8 - 3x**4 + x - 2. by saying y0 = f(xLo) I will get an error, right? How do I format the input so the function will use it? Am I even asking the right question? (I'm so lost!)


    thank you for helping
    I always start off by assuming the x == 1 in order to simplify things at the outset. This makes 5x == 5, etc. Then, after the function is working, you can add the x to the parameter list and do things like (5 * x)**8. Of course, if you are trying to solve for x then things are a lot more complicated, but if you can work it out on paper you should be able to forulate the appropriate algorithm.
    Whether you use eval() or not (eval() is just another way of giving the interpeter text to work on) you basically have two things that go into the formula: variables which have names and values (ie a = 1) and literals (ie "hello") all of which must be assigned before they can be evaluated.

    Comment

    • TMS
      New Member
      • Sep 2006
      • 119

      #3
      thank you... as always you are a life saver!!! And you make it look so easy (never mind that it is).

      TMS

      Comment

      • bartonc
        Recognized Expert Expert
        • Sep 2006
        • 6478

        #4
        Originally posted by TMS
        thank you... as always you are a life saver!!! And you make it look so easy (never mind that it is).

        TMS
        Any time... really!

        Comment

        • TMS
          New Member
          • Sep 2006
          • 119

          #5
          ok, wait.

          If my function is (and I'm only trying to see that 5*x is handled properly)

          Code:
          def root_find(f, xLo, xHi, eps):
              y1 = f(xLo)
          print y1
          and I test it with:

          s = root_find(5*x, -1, 1, .0001)
          print s
          Nothing happens. It doesn't print, it doesn't do anything. Is there something else I must do to get it to process the function that is entered for f? Again, thank you for your patience with me.

          TMS

          Comment

          • bartonc
            Recognized Expert Expert
            • Sep 2006
            • 6478

            #6
            Originally posted by TMS
            ok, wait.

            If my function is (and I'm only trying to see that 5*x is handled properly)

            Code:
            def root_find(f, xLo, xHi, eps):
                y1 = f(xLo)
            print y1
            and I test it with:

            s = root_find(5*x, -1, 1, .0001)
            print s
            Nothing happens. It doesn't print, it doesn't do anything. Is there something else I must do to get it to process the function that is entered for f? Again, thank you for your patience with me.

            TMS
            That's funny. You should have gotten two errors. First:

            >>> def root_find(f, xLo, xHi, eps):
            ... y1 = f(xLo)
            ... print y1
            ...
            >>> s = root_find(5*x, -1, 1, .0001)
            >>> s = root_find(5*x, -1, 1, .0001)
            File "<console>" , line 1, in ?
            ''' exceptions.Name Error : name 'x' is not defined '''

            because x has not yet been assigned a value.
            >>> x = 1
            Fixed error #1. Then:

            >>> s = root_find(5*x, -1, 1, .0001)
            File "<console>" , line 1, in ?
            File "<console>" , line 3, in root_find
            ''' exceptions.Type Error : 'int' object is not callable '''
            >>>

            Because
            ... y1 = f(xLo)
            syntax says "call f with xLo as the argument".
            you want f**xLo, right?

            also you missed one indent and the return:

            Code:
            def root_find(f, xLo, xHi, eps):
                y1 = f**xLo
                return y1
            If you don't put the return in there, the function will return None.

            >>> s = root_find(5*x, -1, 1, .0001)
            >>> print s
            0.2
            >>>

            By the way, are using IDLE to edit and run this?

            Comment

            • TMS
              New Member
              • Sep 2006
              • 119

              #7
              yes. I am just running the module.

              What I'm trying to do is start with 5*x and then go to 5*x**3. So, xLo should be x for one iteration, then when that works, xHi would be next. In otherwords, I'm starting really small to get the find_root algorithm going.

              When I say f(xLo) I am wanting it to map xLo into x, so if f = 5x and xLo = -1, I should get a -5 back. It is my understanding of the bisection method that you solve using xLo in the equation, then try it using xHi. Then you divide the two answers by 2 to get the mid. That allows you to get closer to epsilon. Am I way off base?

              tms

              Comment

              • bartonc
                Recognized Expert Expert
                • Sep 2006
                • 6478

                #8
                Originally posted by TMS
                yes. I am just running the module.

                What I'm trying to do is start with 5*x and then go to 5*x**3. So, xLo should be x for one iteration, then when that works, xHi would be next. In otherwords, I'm starting really small to get the find_root algorithm going.

                When I say f(xLo) I am wanting it to map xLo into x, so if f = 5x and xLo = -1, I should get a -5 back. It is my understanding of the bisection method that you solve using xLo in the equation, then try it using xHi. Then you divide the two answers by 2 to get the mid. That allows you to get closer to epsilon. Am I way off base?

                tms
                No you're not off base. I had read "5x^8 - 3x^4 + x - 2" not the algorithm when I wrote that. Psuedocode translates very nicely into python. In fact, I write in python now where I used to use psuedocode. Although the parentheses are a bit confusing, in the example,
                start loop
                Do While (xR - xL) > epsilon

                'calculate midpoint of domain
                xM = (xR + xL) / 2

                'Find f(xM)
                If ((f(xL) * f(xM)) > 0 Then
                'throw away left half
                xL = xM
                else
                'throw away right half
                xR = xM
                End If
                Loop
                the python would look something like this:
                Code:
                def f(arg):
                    arg = arg * 1   # re-assignment is perfectly fine.
                    return arg   # do any math you want to here
                
                def FindRoot(f, x, L, R, e):
                    xL = x * L
                    xR = x * R
                    while (xR  - xL) > e:
                        xM = (xR  + xL) / 2.0   # python is a bit funny aboud dividing ints vs floats
                        if (f(xL) * f(xM) > 0:
                            xL = xM
                        else:
                            xR = xM
                
                print FindRoot(f, 5, -1, 1, .0001)

                Comment

                • bvdet
                  Recognized Expert Specialist
                  • Oct 2006
                  • 2851

                  #9
                  A recent thread http://www.thescripts.com/forum/thread583573.html may provide a partial solution to you. I wrote a simple script that incorporates some of the functions and classes from it:
                  Code:
                  # 5x^3-3x^2+x-2
                  d = Doublet(Monome(5,3,0),Doublet(Monome(-3,2,0),Doublet(Monome(1,1,0),Doublet(Monome(-2,0,0), None))))
                  print d
                  
                  def solve(d, vx, vy = 1.0):
                      r = 0.0
                      for m in iterDoub(d):
                          r += m.coeff*float(vx)**m.expoX*float(vy)**m.expoY
                      return r        
                  
                  def bisection(d, U, L, e):
                      if solve(d, U) > 0 and solve(d, L) < 0:
                          while abs(U - L) > e:
                              M = (U+L)/2
                              if solve(d, M)*solve(d,U) > 0:
                                  U = M
                              else:
                                  L = M
                              print U, L
                          return U,L
                      else:
                          return "Invalid arguments. f(U) must be > 0 and f(L) must be < 0."
                  
                  print bisection(d, 1.0, -1.0, 0.00001)
                  Output:
                  Code:
                  >>> 5(x^3)-3(x^2)+x-2
                  1.0 0.0
                  1.0 0.5
                  1.0 0.75
                  1.0 0.875
                  0.9375 0.875
                  0.90625 0.875
                  0.890625 0.875
                  0.890625 0.8828125
                  0.88671875 0.8828125
                  0.88671875 0.884765625
                  0.8857421875 0.884765625
                  0.88525390625 0.884765625
                  0.885009765625 0.884765625
                  0.884887695313 0.884765625
                  0.884887695313 0.884826660156
                  0.884857177734 0.884826660156
                  0.884857177734 0.884841918945
                  0.884857177734 0.88484954834
                  (0.884857177734375, 0.88484954833984375)

                  Comment

                  • TMS
                    New Member
                    • Sep 2006
                    • 119

                    #10
                    Ok, but I'm still confused about how Python handles the 5x**8. The x is not defined, so there is an error. You defined f with a function, but later you added a variable to FindRoot(f, x, L, R, e). My function is assigned by the teacher and is as follows:
                    find_root(f, xLo, xHi, eps). I can only have 4 variables. Does your def f(arg) attempt to solve that problem?


                    Code:
                    def f(arg):
                        arg = arg * 1   # re-assignment is perfectly fine.
                        return arg   # do any math you want to here
                    
                    def FindRoot(f, x, L, R, e):
                        xL = x * L
                        xR = x * R
                        while (xR  - xL) > e:
                            xM = (xR  + xL) / 2.0   # python is a bit funny aboud dividing ints vs floats
                            if (f(xL) * f(xM) > 0:
                                xL = xM
                            else:
                                xR = xM
                    
                    print FindRoot(f, 5, -1, 1, .0001)

                    Comment

                    • TMS
                      New Member
                      • Sep 2006
                      • 119

                      #11
                      Originally posted by bvdet
                      A recent thread http://www.thescripts.com/forum/thread583573.html may provide a partial solution to you.
                      I looked over that link. There is a lot of information, but I understand very little of it. For example, the Doublet(Monome. ..) part. Doublet is part of what module? It isn't defined so I get an error message.

                      Again, I'm starting at the very beginning of this assignment, and not necessarily trying to write the functions complete yet (its due on Wednesday!!!). I want to understand this:
                      If my teacher runs my module and find_root is defined like this:

                      find_root(f, xLo, xHi, eps):

                      and the teacher enters this:

                      find_root(5x**3 + 2x**2-x+1, -3, 4, .0001)

                      how do I help Python understand that x is defined by xLo and then xHi. In order to solve for the root, if I understand bisection correctly, I use xLo to find y0, and xHi to find y1 by using it like this:

                      y0 = 5(xLo)**3 + 2(xLo)**2 - (xLo) + 1
                      y1 = 5(xHi)**3 + 2(xHi)**2 - (xHi) + 1

                      If it is still higher than eps, then I divide by 2... etc. But in order to begin I have to map xLo into x. And in order to do that, I have to get Python to know what to do with an x that is undefined.

                      Perhaps I am not reducing my question far enough? I do appreciate all the help, and I definitely appreciate the help on the functions. I just can't get there until I understand how to communicate with Python what to do with a variable that will be defined through the process.

                      Thank you, thank you... for your patience.

                      Comment

                      • bartonc
                        Recognized Expert Expert
                        • Sep 2006
                        • 6478

                        #12
                        Originally posted by TMS
                        Ok, but I'm still confused about how Python handles the 5x**8. The x is not defined, so there is an error. You defined f with a function, but later you added a variable to FindRoot(f, x, L, R, e). My function is assigned by the teacher and is as follows:
                        find_root(f, xLo, xHi, eps). I can only have 4 variables. Does your def f(arg) attempt to solve that problem?


                        Code:
                        def f(arg):
                            arg = arg * 1   # re-assignment is perfectly fine.
                            return arg   # do any math you want to here
                        
                        def FindRoot(f, x, L, R, e):
                            xL = x * L
                            xR = x * R
                            while (xR  - xL) > e:
                                xM = (xR  + xL) / 2.0   # python is a bit funny aboud dividing ints vs floats
                                if (f(xL) * f(xM) > 0:
                                    xL = xM
                                else:
                                    xR = xM
                        
                        print FindRoot(f, 5, -1, 1, .0001)
                        What I've done here is give an example of how this MIGHT be done. Hence "someting like this". Please make an attempt at writing the function according to your assignment and I'll help you debug it. I believe that you will learn much more this way rather than just being given the answer.

                        Comment

                        • TMS
                          New Member
                          • Sep 2006
                          • 119

                          #13
                          Originally posted by bartonc
                          What I've done here is give an example of how this MIGHT be done. Hence "someting like this". Please make an attempt at writing the function according to your assignment and I'll help you debug it. I believe that you will learn much more this way rather than just being given the answer.
                          I don't want you to write the function (arggggg) I've been working on this since Wednesday night. I can't find a way for python to interpret the x when I put 5x as the value of f. That is all I'm looking for. I can get through the pseudocode... its this one thing I'm hung up on. I've been reading, searching... I don't understand how to tell Python that I will eventually define x when it is in the format of 5x**8. Thats all I've been asking all along. If I sound exasperated its because I am. Believe me, I don't go to the boards unless I'm really stuck. I even emailed my teacher (before I tried the board) and he hasn't responded.

                          I must be asking the question wrong.

                          Comment

                          • bartonc
                            Recognized Expert Expert
                            • Sep 2006
                            • 6478

                            #14
                            Originally posted by TMS
                            I don't want you to write the function (arggggg) I've been working on this since Wednesday night. I can't find a way for python to interpret the x when I put 5x as the value of f. That is all I'm looking for. I can get through the pseudocode... its this one thing I'm hung up on. I've been reading, searching... I don't understand how to tell Python that I will eventually define x when it is in the format of 5x**8. Thats all I've been asking all along. If I sound exasperated its because I am. Believe me, I don't go to the boards unless I'm really stuck. I even emailed my teacher (before I tried the board) and he hasn't responded.

                            I must be asking the question wrong.
                            how about
                            Code:
                            fiveX = 5 * x
                            ?

                            Comment

                            • TMS
                              New Member
                              • Sep 2006
                              • 119

                              #15
                              Originally posted by bartonc
                              how about
                              Code:
                              fiveX = 5 * x
                              ?
                              no, because x is undefined.

                              My teacher will be testing my assignment. He will use something like this:

                              find_root(5x**3 +2x**2+x+1, -3, 4, .0006)

                              I have to find a way to process that statement, where f is defined as 5x**3+2x**2+x+1 , but will (through the function) define x with xLo and then later with xHi. I get an error saying that x is not defined. It won't let me pass this right now because I'm missing something, obviously :(

                              It is probably so obvious to python programmers who have been programming in python for a while, but I'm not getting it, which is why I'm being so persistent. I really want to understand what I'm missing.

                              Comment

                              Working...