Ask Your Question
1

How to obtain decimal value from .solve() ?

asked 2020-03-06 23:53:57 +0100

RyanG gravatar image
var('n')
f(x,n) = -x^-1 + (1.097e7)*((1/(n-1)^2) - (1/n^2))

for i in range (2,10):
    L = f(x,i).solve(x)
    print(L)

[x == (1/8227500)]

[x == (9/13712500)]

....

How can I have this display a float value for x, rather than a fraction?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2020-03-07 19:04:06 +0100

dsejas gravatar image

Hello, @RyanG! There are a couple of ways to do what you want.

  1. You could use the N() function with the right hand side (rhs) of your solutions:

    var('n')
    f(x,n) = -x^-1 + (1.097e7)*((1/(n-1)^2) - (1/n^2))
    
    for i in range (2,10):
        L = f(x,i).solve(x)
        print(N(L[0].rhs()))
    

    Let me explain the last line. Sage's solve() command returns a list of solutions. In this particular case, there only one solution, so we access that with L[0] (of course, if there was a second solution, it would be accessed with L[1], etc.). Now that solution has the form x == <some_number>, so we access that <some_number> with the rhs() command (of course, lhs() would access the variable x). Finally, we use the N() function in order to have a numerical approximation.

    I must point out that this method will work only when there is a unique solution. If there were many solutions---like with a polynomial of degree two or three---, this code should be modified in order to deal with that. (If you need that more general code, feel free to ask, and I can send it to you.)

    You can improve the output as follows:

    var('n')
    f(x,n) = -x^-1 + (1.097e7)*((1/(n-1)^2) - (1/n^2))
    
    for i in range (2,10):
        L = f(x,i).solve(x)
        print(L[0].lhs(), '=', N(L[0].rhs()))
    
  2. Sage has a find_root() function that works numerically, instead of symbolically as solve() does. You have to give it two arguments: the limits of the interval where you assume the root will be. You can "guesstimate" such interval by plotting your functions or simply use a crazy interval like $[0,100]$.

    In this particular case, you roots seem to be in $[0,1]$, but I will use the interval $[0,10]$ just to be sure:

    var('n')
    f(x,n) = -x^-1 + (1.097e7)*((1/(n-1)^2) - (1/n^2))
    
    for i in range (2,10):
        L = f(x,i).find_root(0,10)
        print('x =', L)
    

    Of course, this method has the disadvantage that only finds one root per call. If there were more than one solution for any of your functions, only one would be found. But, again, in this particular case, your functions have only one root.

I hope this helps!

edit flag offensive delete link more

Comments

2

If solve returns [x==<value>] and you store this in L, you can extract <value> with L[0].rhs(), as explained by @dsejas, or x.subs(L). Even more, if solve returns more than one solution, you can get all of them with a loop of the form for sol in L:. Likewise, it is equivalent N(number) to n(number) or number.n(). Hence, an alternative, complete code that prints all the solutions in decimal form would be:

for i in range (2,10):
    print("i=",i)
    L = f(x,i).solve(x)
    for sol in L:
        print(x.subs(sol).n())
Juanjo gravatar imageJuanjo ( 2020-03-07 19:53:58 +0100 )edit

Thank for your such a thorough explanation! As someone new to Sage it means a lot when others are willing to break down and explain trivial issues like this.

RyanG gravatar imageRyanG ( 2020-03-08 17:37:12 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2020-03-06 23:53:57 +0100

Seen: 1,727 times

Last updated: Mar 07 '20