Python Forum
TypeError: only size-1 arrays can be converted to Python scalars
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TypeError: only size-1 arrays can be converted to Python scalars
#1
Hi everyone,

Hope ye are all well.

I am extremely new to Python and have an assignment due tomorrow which I really struggled with, but happy at how much I have accomplished.

However, I am trying to plot the 3 functions for my newton raphson method. My first function was fine but the 2nd and 3rd one won't because of this error:

TypeError: only size-1 arrays can be converted to Python scalars

And I have been trying to fix it but not getting very war so any help would be greatly appreciated.
Here is the code I have written:

import numpy as np
import scipy as sc ##complex numbers
import matplotlib.pyplot as plt
import math as math

def newton_r(f, dfdx, x0, TOL, NO):
    
    n = 1
    print("n  \t   x_n  \t             x   \t           f_x     \t   dfdx_x  \t  ")
    print("%2.0f   \t  %2.10f " % (n, x0))
    
    x = f(x0) #evaluate function at initial guess and get output X
    while (np.abs(x) > TOL): 
        n = n + 1
        x = x0 - f(x0) / dfdx(x0)
        x0 = x ##bringing initial value up to a new point
        FX = f(x0)
        
        if FX == 0 or x < TOL:
            print("The root is %.10f at %d iterations." %(x0, n))
            return x0
        
          
        if (np.imag(x) != 0):
            print("Error: Trying to compute the square root of a negative number")
            break
        elif (n >= NO):
            print("Maximum number of steps reached")
            break
        
        print("%2.0f       %.10f           %.10f         %.10f       %.10f" % (n, x0, x, f(x0), dfdx(x0)))


f1 = lambda x: x**3 + 4*x**2 - 10
dfdx1 = lambda x: 3*x**2 + 8*x
    
f2 = lambda x: ((1/x) + (math.log(x + 1)) - 5)
dfdx2 = lambda x: (1/(x + 1) - 1/x**2)

f3 = lambda x: ((math.log(x)) + (math.exp(x)))
dfdx3 = lambda x: ((1/x) + (math.exp(x)))

##Question 1: Plot each function and all approximations of the root

## setup for f1
x1 = np.linspace(0.0, 3, 100) ##this is giving me an array(list) called x1 that's filled with 100 values
y1 = x1**3 + 4*x1**2 - 10/3*x1**2 + 8*x1  ##equally spaced between the intervals of 0.5 - 2

x2 = np.linspace(0.1, 3, 100)
y2 = ((1/x2) + (math.log((x2 + 1)) - 5) / (1/(x2 + 1)) - 1/(x2**2))

##x3 = np.linspace(0.2, 2, 100)
#y3 = ((math.log(x3)) + (math.exp(x3))) / ((1/x3) + (math.exp(x3)))


plt.figure(figsize =(10,5))
plt.subplot(3,2,1) ##setting dimensions of subplot
plt.plot(x1, y1, color='b')
plt.ylim(-10,60) ##setting y-axis scale
plt.axhline(0, color = 'k', lineWidth = 1.0) #this command will create an origin at y = 0
plt.axvline(0, color = 'k', lineWidth = 1.0) #this command will create a vertical line at x = 0
plt.ylabel('y1', color="r") ##y-axis label, with the text being the colour red
plt.xlabel('x',horizontalalignment='right', x=1.0, color="r")
plt.grid(True) ##setting grid lines
plt.tight_layout() ##better spacing between graphs, as they were on top of each other
!!!!FOR Y2 AND YS ABOVE IS WHERE THE ERROR IN MY CODE LAYS, WITH THE ABOVE MENTIONED ERROR. IF SOMEONE HAS ANY ADVICE ON HOW TO ADJUST AND RESOLVE THIS I CAN'T TELL YOU HOW GRATEFUL I WOULD BE.

Kind Regards,

Kate
buran write Oct-29-2020, 04:13 PM:
Please, use proper tags when post code, traceback, output, etc. This time I have added tags for you.
See BBcode help for more info.

Please, post the entire traceback that you get. We need to see that whole thing. Do not just give us the last line.
Take a time to read What to include in a post

Don't start multiple threads for the same thing. Please, don't use ALL CAPS. Post in the correct sub-forum.

You managed to break so many forum rules in no time.
Reply
#2
Use np.log instead of math.log.
I also removed not used imports.

Also the line "import math as math" is useless.
First you import math and then math is renamed to math.
Then use f-strings or str.format instead of the % formatting.
Don't assign lambda (anonymous function) to a name. Use def for function definition instead.
Lambdas are used for example in place as an argument of a function call for example:
some_data = [("y", 10), ("a", 20)]
some_data_sorted_by_second_key = sorted(some_data, key=lambda x: x[1])
Here your modified code.
I haven't changed the rest. This is your task.

import math

import matplotlib.pyplot as plt
import numpy as np


def newton_r(f, dfdx, x0, TOL, NO):
    """
    Provide a description
    """

    n = 1
    print("n  \t   x_n  \t             x   \t           f_x     \t   dfdx_x  \t  ")
    print("%2.0f   \t  %2.10f " % (n, x0))

    x = f(x0)  # evaluate function at initial guess and get output X
    while np.abs(x) > TOL:
        n = n + 1
        x = x0 - f(x0) / dfdx(x0)
        x0 = x  ##bringing initial value up to a new point
        FX = f(x0)

        if FX == 0 or x < TOL:
            print("The root is %.10f at %d iterations." % (x0, n))
            return x0

        if np.imag(x) != 0:
            print("Error: Trying to compute the square root of a negative number")
            break
        elif n >= NO:
            print("Maximum number of steps reached")
            break

        print(
            "%2.0f       %.10f           %.10f         %.10f       %.10f"
            % (n, x0, x, f(x0), dfdx(x0))
        )
        # old style formatting was used 15 years ago
        # now we've the format method of str
        # and f-strings


# named functions should be defined with def
# using lambdas is not the right way if you assing it to a name


f1 = lambda x: x ** 3 + 4 * x ** 2 - 10
dfdx1 = lambda x: 3 * x ** 2 + 8 * x

f2 = lambda x: ((1 / x) + (math.log(x + 1)) - 5)
dfdx2 = lambda x: (1 / (x + 1) - 1 / x ** 2)

f3 = lambda x: ((math.log(x)) + (math.exp(x)))
dfdx3 = lambda x: ((1 / x) + (math.exp(x)))

##Question 1: Plot each function and all approximations of the root

## setup for f1
x1 = np.linspace(
    0.0, 3, 100
)  ##this is giving me an array(list) called x1 that's filled with 100 values
y1 = (
    x1 ** 3 + 4 * x1 ** 2 - 10 / 3 * x1 ** 2 + 8 * x1
)  ##equally spaced between the intervals of 0.5 - 2

x2 = np.linspace(0.1, 3, 100)
y2 = (1 / x2) + (np.log((x2 + 1)) - 5) / (1 / (x2 + 1)) - 1 / (x2 ** 2)

##x3 = np.linspace(0.2, 2, 100)
# y3 = ((math.log(x3)) + (math.exp(x3))) / ((1/x3) + (math.exp(x3)))


plt.figure(figsize=(10, 5))
plt.subplot(3, 2, 1)  ##setting dimensions of subplot
plt.plot(x1, y1, color="b")
plt.ylim(-10, 60)  ##setting y-axis scale
plt.axhline(0, color="k", lineWidth=1.0)  # this command will create an origin at y = 0
plt.axvline(
    0, color="k", lineWidth=1.0
)  # this command will create a vertical line at x = 0
plt.ylabel("y1", color="r")  ##y-axis label, with the text being the colour red
plt.xlabel("x", horizontalalignment="right", x=1.0, color="r")
plt.grid(True)  ##setting grid lines
plt.tight_layout()  ##better spacing between graphs, as they were on top of each other

plt.show()
   
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Image data cannot be converted to float rakeshd3 1 7,050 Mar-17-2020, 08:01 AM
Last Post: buran
  Fixing arrays output in Python WLST script pkbash 2 3,985 Feb-28-2019, 06:20 PM
Last Post: pkbash
  Python arrays abdullahali 3 3,140 Oct-31-2018, 12:51 AM
Last Post: LeSchakal
  parameter in function being involuntarily converted to str?? juliabrushett 8 4,562 Jul-03-2018, 04:23 PM
Last Post: gruntfutuk

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020