I am trying to write a program about Simpson's Law.What I am trying to do is use as error as shown in this picture:
.
In the code i write the Ih is my f1 and Ih/2 is my f2.If the error doesnt happen then the steps get halved.
However I get this error
Traceback (most recent call last):
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\example.py", line 22, in <module>
sim2 = simps(f2, x2)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 436, in simps
return simpson(y, x=x, dx=dx, axis=axis, even=even)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 542, in simpson
last_dx = x[slice1] - x[slice2]
IndexError: index -1 is out of bounds for axis 0 with size 0
Process finished with exit code 1
My code is
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, int(N/2))
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = int(N/2)
print(sim1)
I wasnt expecting any error,and basically expecting to calculate correctly.
When you reduce the grid step by half h -> h/2, the number of grid steps in turn grows N -> 2 * N, so you have to make two changes in your code:
Define x2 to have twice as many elements as x1
x2 = np.linspace(a, b, 2 * N)
Update N to be twice it was on the previous iteration
N = 2 * N
The resulting code would be
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, 2 * N)
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = 2 * N
print(sim1)
And this prints the value
87.9765411043221
with error consistent with the threshold
abs(sim1 - sim2) = 4.66441463231604e-9
#DmitriChubarov's solution is correct. However, your implementation is very inefficient: it does double the work it needs to. Also, simps is deprecated, you should be using proper exponential notation, and your function expression can be simplified. For an equivalent error-free algorithm that still doubles the input array length on each iteration but doesn't throw away the intermediate result,
import numpy as np
from scipy.integrate import simpson
a = 0
b = 2*np.pi
N = 100
ra = 0.1 # ρα
R = 0.05
fa = np.radians(35) # φα
za = 0.4
aa = np.linalg.norm((ra, R, za))
error = 5e-9
sim1 = np.nan
while True:
x = np.linspace(a, b, N)
f = (aa**2 - 2*ra*R*np.cos(x - fa))**-1.5
sim2 = simpson(f, x)
if np.abs(sim1 - sim2) < error:
break
sim1 = sim2
N *= 2
print(sim1)
When I modified your code by adding two lines to print(len(x1), len(f1)) and print(len(x2), len(f2)), I got these results:
Output:
length of x1 and f1: 100 100
length of x2 and f2: 50 50
length of x1 and f1: 50 50
length of x2 and f2: 25 25
length of x1 and f1: 25 25
length of x2 and f2: 12 12
length of x1 and f1: 12 12
length of x2 and f2: 6 6
length of x1 and f1: 6 6
length of x2 and f2: 3 3
length of x1 and f1: 3 3
length of x2 and f2: 1 1
length of x1 and f1: 1 1
length of x2 and f2: 0 0
as you can see the length decreases each loop because N decreases and ends with an empty list length of x2 and f2: 0 0 and this causes the error you have had. To fix the issue of 'the empty list' I suggest that you duplicate N; this means using N*2 instead of N/2.
Related
I am trying to calculate an integral using Simpson's Rule formula.The catch is that the value of the integral is the one that satisfies the following condition:You find the Ih and Ih/2.If the absolute of (Ih-Ih/2)<error the loop is complete.Otherwise you repeat the process with half the h,which means it calculates the absolute of (Ih/2-Ih/4) and so on and so on.
while True:
###Ih part
h = (b - a) / N
y1 = np.linspace(a, b, N)
Ez11 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
I11 = (h/3) * (Ez11[0] + 2*sum(Ez11[:N-2:2]) \
+ 4*sum(Ez11[1:N-1:2]) + Ez11[N-1])
#####Ih/2 part
h = (b-a)/(2*N)
y2 = np.linspace(a, b, 2*N)
Ez22 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
print(Ez22)
I22 = (h/ 3) * (Ez22[0] + 2 * sum(Ez22[:N - 2:2]) \
+ 4 * sum(Ez22[1:N - 1:2]) + Ez22[N - 1])
# error condition I1=Ih I2=Ih/2
if np.abs(I11 - I22) < error:
break
else:
N = 2*N # h/2
print(np.abs(I11 - I22))
As far as I can tell,my approach should be correct.However the loop goes on and on,never to stop.
My code is as follows:
import numpy as np
from scipy.integrate import simps
import scipy.integrate as integrate
import scipy.special as special
# variables
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi / 180) # φα
za = 0.4
Q = 10 ** (-6)
k = 9 * 10 ** 9
aa = np.sqrt(ra ** 2 + R ** 2 + za ** 2)
error = 0.55 * 10 ** (-8)
h=(b-a)/N
I1 = np.nan
I11 = np.nan
#Simpsons section
############ Ez
#automated Simpson
while True:
###Ih part
y1 = np.linspace(a, b, N)
Ez1 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
print(len(Ez1))
I1 = simps(Ez1, y1)
#####Ih/2 part
y2 = np.linspace(a, b, 2*N)
Ez2 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
I2 = simps(Ez2, y2)
# error condition I1=Ih I2=Ih/2
if np.abs(I1 - I2) < error:
break
else:
N *= 2 # h/2
#custom-made Simpson
N = 100
while True:
###Ih part
h = (b - a) / N
y1 = np.linspace(a, b, N)
Ez11 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
I11 = (h/3) * (Ez11[0] + 2*sum(Ez11[:N-2:2]) \
+ 4*sum(Ez11[1:N-1:2]) + Ez11[N-1])
#####Ih/2 part
h = (b-a)/(2*N)
y2 = np.linspace(a, b, 2*N)
Ez22 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
print(Ez22)
I22 = (h/ 3) * (Ez22[0] + 2 * sum(Ez22[:N - 2:2]) \
+ 4 * sum(Ez22[1:N - 1:2]) + Ez22[N - 1])
# error condition I1=Ih I2=Ih/2
if np.abs(I11 - I22) < error:
break
else:
N = 2*N # h/2
print(np.abs(I11 - I22))
print(I1)
print(I11)
Simpson's Rule is as follows:
After a while it's stuck in this situation
The 5.23 part is the absolute diff of those 2 which shouldnt be that high.
I recently started learning programing and Python.
Now I've been trying to convert a list of coordinates x,y to latitude and longitude. I searched and found a method in python in this post: How to convert from UTM to LatLng in python or Javascript
But when I try to apply the function to a list of floats from a dataframe I get an error:" cannot convert the series to <class 'float'> ".
What could I be doing wrong?
My code:
import math
def utmToLatLng(zone, easting, northing, northernHemisphere=True):
if not northernHemisphere:
northing = 10000000 - northing
a = 6378137
e = 0.081819191
e1sq = 0.006739497
k0 = 0.9996
arc = northing / k0
mu = arc / (a * (1 - math.pow(e, 2) / 4.0 - 3 * math.pow(e, 4) / 64.0 - 5 * math.pow(e, 6) / 256.0))
ei = (1 - math.pow((1 - e * e), (1 / 2.0))) / (1 + math.pow((1 - e * e), (1 / 2.0)))
ca = 3 * ei / 2 - 27 * math.pow(ei, 3) / 32.0
cb = 21 * math.pow(ei, 2) / 16 - 55 * math.pow(ei, 4) / 32
cc = 151 * math.pow(ei, 3) / 96
cd = 1097 * math.pow(ei, 4) / 512
phi1 = mu + ca * math.sin(2 * mu) + cb * math.sin(4 * mu) + cc * math.sin(6 * mu) + cd * math.sin(8 * mu)
n0 = a / math.pow((1 - math.pow((e * math.sin(phi1)), 2)), (1 / 2.0))
r0 = a * (1 - e * e) / math.pow((1 - math.pow((e * math.sin(phi1)), 2)), (3 / 2.0))
fact1 = n0 * math.tan(phi1) / r0
_a1 = 500000 - easting
dd0 = _a1 / (n0 * k0)
fact2 = dd0 * dd0 / 2
t0 = math.pow(math.tan(phi1), 2)
Q0 = e1sq * math.pow(math.cos(phi1), 2)
fact3 = (5 + 3 * t0 + 10 * Q0 - 4 * Q0 * Q0 - 9 * e1sq) * math.pow(dd0, 4) / 24
fact4 = (61 + 90 * t0 + 298 * Q0 + 45 * t0 * t0 - 252 * e1sq - 3 * Q0 * Q0) * math.pow(dd0, 6) / 720
lof1 = _a1 / (n0 * k0)
lof2 = (1 + 2 * t0 + Q0) * math.pow(dd0, 3) / 6.0
lof3 = (5 - 2 * Q0 + 28 * t0 - 3 * math.pow(Q0, 2) + 8 * e1sq + 24 * math.pow(t0, 2)) * math.pow(dd0, 5) / 120
_a2 = (lof1 - lof2 + lof3) / math.cos(phi1)
_a3 = _a2 * 180 / math.pi
latitude = 180 * (phi1 - fact1 * (fact2 + fact3 + fact4)) / math.pi
if not northernHemisphere:
latitude = -latitude
longitude = ((zone > 0) and (6 * zone - 183.0) or 3.0) - _a3
return (latitude, longitude)
import pandas as pd
df = pd.read_csv('Coord_rj.csv')
x = df['x']
y = df['y']
for i in range(len(df)):
lati,longi = utmToLatLng(23,x,y, False)
What my data looks like:
x y
529025.0 7422210.0
529114.0 7422343.0
545227.0 7435702.0
545582.0 7435741.0
The error:
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_7368/1776418913.py in <module>
1 for i in range(len(df)):
----> 2 lati,longi = utmToLatLng(23,x,y, False)
3
~\AppData\Local\Temp/ipykernel_7368/3107957551.py in utmToLatLng(zone, easting, northing, northernHemisphere)
20 cc = 151 * math.pow(ei, 3) / 96
21 cd = 1097 * math.pow(ei, 4) / 512
---> 22 phi1 = mu + ca * math.sin(2 * mu) + cb * math.sin(4 * mu) + cc * math.sin(6 * mu) + cd * math.sin(8 * mu)
23
24 n0 = a / math.pow((1 - math.pow((e * math.sin(phi1)), 2)), (1 / 2.0))
~\anaconda3\lib\site-packages\pandas\core\series.py in wrapper(self)
183 if len(self) == 1:
184 return converter(self.iloc[0])
--> 185 raise TypeError(f"cannot convert the series to {converter}")
186
187 wrapper.__name__ = f"__{converter.__name__}__"
TypeError: cannot convert the series to <class 'float'>
When you're reading in your input file you're assigning all of the first column to a variable, and all of the second column to a variable:
>>> import pandas as pd
>>> df = pd.read_csv('Coord_rj.csv')
>>> df
x y
0 529025.0 7422210.0
1 529114.0 7422343.0
2 545227.0 7435702.0
3 545582.0 7435741.0
>>> df['x']
0 529025.0
1 529114.0
2 545227.0
3 545582.0
Name: x, dtype: float64
>>> df['y']
0 7422210.0
1 7422343.0
2 7435702.0
3 7435741.0
Name: y, dtype: float64
When you call your function you're passing the entire column to it for x and y, rather than just a row.
Try this instead:
for i in range(len(df)):
lati,longi = utmToLatLng(23, x[i], y[i], False)
Hi I make some derivative Program on Python, but the result isn't same as what i expected,
This is the result as what i want to be :
f(x) = x^2 - 8x + 25
f'(x) = 2x -8
0 = 2x - 8
8 = 2x
4 = x
x = 4
i want x to be equal to 4
and here's the code :
import sympy as sp
from sympy import *
p = 8
m = 25
f = x**2 - p*x + m
f_prime = f.diff(x)
f = lambdify(x, f)
f_prime = lambdify(x, f_prime)
f_prime(2)
the result is -4
how to solve this problem?
Thankyou
You have to define x as a symbolic variable (otherwise code will not compile), lambdify f_prime and solve the equation f_prime(x) = 0
from sympy import *
p = 8
m = 25
x = symbols('x')
f = x**2 - p*x + m
f_prime = f.diff(x)
print (f_prime)
f_prime = lambdify(x, f_prime)
print(solve(f_prime(x))[0])
2*x - 8
4
Getting wrong output for this equation. Can someone review my code?
from math import cos
from math import sin
from math import pi
a0 = int(input("a0:"))
b0 = int(input("b0:"))
N = int(input("N:"))
L = int(input("L:"))
X = int(input("X:"))
n = 0
an = a0
bn = b0
y=0
for i in range(N):
an = an + 10 # since our first value would An = A0 +10 , we could just loop the values by adding 10 to it
bn = bn * 10
y= an * cos((n*pi*X/(L))) + bn*(sin(n*pi*X/(L)))
print(y)
y= an * cos((n*pi*X/(L))) + bn*(sin(n*pi*X/(L)))
There's never any change in the n variable! Given that n starts (and remains) at 0, you always calculate
an * cos(0) + bn * sin(0) == an * 1 + bn * 0 == an
Furthermore you need to add the result to the y variable, not just assign it. And you need to prime the y variable with a0.
an = a0
bn = b0
c = 0
d = pi * X / L # precalculating for efficiency
y = a0
for i in range(N):
an = an + 10
bn = bn * 10
c = c + d
y = y + an * cos(c) + bn * sin(c)
print(y)
I am trying to plot various data including complex vectors.Thanks to contributors see answers https://stackoverflow.com/a/64480659/13953414, i managed to generate the dataframes but i get stuck when i want to add some additional calculations. i get an error :
df['T_depth'] = (math.sqrt(D / (4 * (math.pi) * frequency)) / 1e-6),
TypeError: only size-1 arrays can be converted to Python scalars
all calculations starting from T_depth are not executed due to a format issue. the function were vectorized but yet I cannot execute and save the df.
from mpmath import *
import numpy as np
import cmath
import math
import pandas as pd
mp.dps = 15; mp.pretty = True
a = mpf(0.25)
b = mpf(0.25)
z = mpf(0.75)
frequency = np.arange(1, 50, 10) # frequency range
bh = np.arange(10e-6, 35e-6, 10e-6) #10e-6 # width
print(bh)
D = 1e-6 #7.8e-4 # diffusivity
gamma = 0.5772 # Euler constant
# Cartesian product of input variables
idx = pd.MultiIndex.from_product([bh, frequency], names=["bh", "frequency"])
df = pd.DataFrame(index=idx).reset_index()
# Omega is vectorized naturally.
omega = (df["bh"].values**2 * df["frequency"].values) * (2 * math.pi / D)
# vectorize meijerg() only, so other operations won't interrupt with this
def f_u(omega_elem):
# u = (-j/(math.pi * omega_elem)) * meijerg([[1, 3/2], []], [[1, 1], [0.5, 0]], j*omega_elem)
return (-j/(math.pi * omega_elem)) * meijerg([[1, 3/2], []], [[1, 1], [0.5, 0]], j*omega_elem)
f_u_vec = np.vectorize(f_u, otypes=[np.complex128]) # output complex
u = f_u_vec(omega)
def asympt(omega_elem):
return (4/(math.pi))*(-(1/2)*np.log(omega_elem) + 3/2 - gamma - j*((math.pi)/4))
asympt_vec = np.vectorize(asympt, otypes=[np.complex128]) # output complex
v = asympt_vec(omega)
#is it possible to merge these 2 aforementioned operation in one method?
df["Re"] = np.real(u)
df["Im"] = np.imag(u)
df["asympt_R"] = np.real(v)
df["asympt_Im"] = np.imag(v)
# the following operations cannot be executed
df['T_depth'] = (math.sqrt(D / (4 * (math.pi) * frequency)) / 1e-6)
df['amplitude'] = math.sqrt(np.real(u)**2 + np.imag(u)**2)
df['phase'] = math.degrees(math.atan(np.imag(u) / np.real(u)))
df['thermal_freq'] = 2 * (math.pi) * frequency
print(df)
np.vectorize can return multiple "columns" as a tuple of arrays. Here I showcase how to add a "column" to the vectorized function and how to rearrange them.
def f_u(omega_elem):
val1 = (-j / (math.pi * omega_elem)) * meijerg([[1, 3 / 2], []], [[1, 1], [0.5, 0]], j * omega_elem)
asympt = (4 / (math.pi)) * (-(1 / 2) * np.log(omega_elem) + 3 / 2 - gamma - j * ((math.pi) / 4))
return val1, asympt
# return a tuple of array. Remember to assign two otypes.
f_u_vec = np.vectorize(f_u, otypes=[np.complex128, np.complex128])
tup = f_u_vec(omega) # tuple of arrays: (val1, asympt)
df["Re"] = np.real(tup[0]) # val1
df["Im"] = np.imag(tup[0])
df["asympt_R"] = np.real(tup[1]) # asympt
df["asympt_Im"] = np.imag(tup[1])
# result
df
Out[94]:
bh frequency Re Im asympt_R asympt_Im
0 0.00001 1 5.868486 -0.999374 5.868401 -1.0
1 0.00001 11 4.342982 -0.994876 4.341854 -1.0
2 0.00001 21 3.932365 -0.991121 3.930198 -1.0
3 0.00001 31 3.685457 -0.987696 3.682257 -1.0
4 0.00001 41 3.508498 -0.984488 3.504268 -1.0
5 0.00002 1 4.986257 -0.997867 4.985859 -1.0
6 0.00002 11 3.463849 -0.983559 3.459311 -1.0
7 0.00002 21 3.056269 -0.972212 3.047656 -1.0
8 0.00002 31 2.812349 -0.962168 2.799715 -1.0
9 0.00002 41 2.638332 -0.952979 2.621726 -1.0