I have an expression for a complex function as follows:
f(z) = 1/jwC + (R1(1+jwC1) + R2(1+jwC2))/(1+jwR1C1)(1+jwR2C2)
where j = sqrt(-1)
How do I compute f(z) in Python, given the values of w, R1, R2, C, C1, C2 and then seperate out the real and imaginary portions of f(z)?
Complex numbers are one of the standard types in Python.
So you could just write:
#!/usr/bin/env python3
def f(w, R1, R2, C, C1, C2):
return 1 / (1j * w * C) + (R1 * (1 + 1j * w * C1) + R2 * (
1 + 1j * w * C2)) / ((1 + 1j * w * R1 * C1) * (1 + 1j * w * R2 * C2))
result = f(w=1000, R1=100, R2=200, C=100.0e-9, C1=100.0e-9, C2=200.0e-9)
print(result)
print(result.real)
print(result.imag)
(NB: please check the math epxression yourself, since I didn't verify if the results are actually correct. I may have misinterpreted your equation or made a typo.)
Related
I have a problem using sympy.
I have to plot regions that satisfies few inequalities.
There are 3 parameters u, c, and q, which are all between (0,1), and I want to see how the region changes as one parameter varies.
In the code below, I fixed one parameter 'q', to see which parameters 'u' and 'c' satisfy the inequalities.
Currently, I have to manually change the fixed value q to a different float to see how region changes.
Is there any way I can use sliders to see how the region changes continuously?
Thank you.
I'm new to python and plotting.
It doesn't have to be Sympy, matplotlib, or plotly as long as my needs are satisfied.
Here is the code I wrote below
import sympy
from sympy import And, symbols, plot_implicit
u, c = symbols('u c')
q = 0.5
m2 = 2 * sympy.sqrt(c*q*u)
k2 = (m2 - 2 * c) / m2
a2 = (m2 * (m2 - 2 * c)) / (2 * c * q)
b2 = (m2 ** 2 - c * ( 1 + q ) * m2) / (2 * c * q)
t3 = u - c + 1
k3 = (q * t3 - sympy.sqrt(c * q * t3 + 1 - c))/(q * t3 + 1 - c)
a3 = (2 * c * k3 ) / (q * (1 - k3)**2)
b3 = (u - c - ((c * (k3 **2)) / (q * ((1 - k3)**2)))) / ( 1- k3)
d3 = (- 1 + ((1 - k3) / c) - ((1 - k3)*(u - c - (u - c - ((c * (k3 **2)) / (q * ((1 - k3)**2)))))) / c ) * (1 - k3)
m3 = (2 * c * d3) / ((1 - k3)**2)
p1 = plot_implicit(And( 2 * (1 - u) < 1, u > (c + 4 + sympy.sqrt(c**2 + 8*c)) / 8 , u >= (4*q + c + sympy.sqrt(c**2 + 8 * q * c)) / (8 * q)), x_var = (u, 0, 1), y_var = (c, 0, 1), line_color = 'red', show=False)
p2 = plot_implicit(And( b2 + m2 <=1 , a2 > 0, u>c ), x_var = (u,0,1), y_var = (c, 0, 1), line_color = 'green', show=False)
p3 = plot_implicit(And(u>c, k3>0, d3>0, b3>a3, b3+m3 <=1, k3+d3 < 1) , x_var = (u, 0, 1), y_var = (c, 0, 1), show = False)
p1.append(p2[0])
p1.append(p3[0])
p1.show()
Any references or skeleton code will help.
Thank you
I'm going to use the following libraries:
SymPy Plot Backend for data generation. This package is capable of creating interactive plots with sliders. However, this functionality is not yet implemented for plot_implicit. Nonetheless, I'll use it to create the numerical data to be plotted.
Matplotlib, in particular I'm going to follow the slider demo.
Note that you are plotting boolean expressions (created with sympy's And). Consequently, the ImplicitSeries used to generate the numerical data will use an adaptive algorithm, which is slow! So, whenever you'll move the slider you will have to wait a few seconds for the update to be rendered on the screen.
from sympy import *
from spb import *
from spb.series import ImplicitSeries
from spb.backends.matplotlib import _matplotlib_list
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import numpy as np
u, c, q = symbols('u c q')
init_q = 0.5
m2 = 2 * sqrt(c*q*u)
k2 = (m2 - 2 * c) / m2
a2 = (m2 * (m2 - 2 * c)) / (2 * c * q)
b2 = (m2 ** 2 - c * ( 1 + q ) * m2) / (2 * c * q)
t3 = u - c + 1
k3 = (q * t3 - sqrt(c * q * t3 + 1 - c))/(q * t3 + 1 - c)
a3 = (2 * c * k3 ) / (q * (1 - k3)**2)
b3 = (u - c - ((c * (k3 **2)) / (q * ((1 - k3)**2)))) / ( 1- k3)
d3 = (- 1 + ((1 - k3) / c) - ((1 - k3)*(u - c - (u - c - ((c * (k3 **2)) / (q * ((1 - k3)**2)))))) / c ) * (1 - k3)
m3 = (2 * c * d3) / ((1 - k3)**2)
i1 = And( 2 * (1 - u) < 1, u > (c + 4 + sqrt(c**2 + 8*c)) / 8 , u >= (4*q + c + sqrt(c**2 + 8 * q * c)) / (8 * q))
i2 = And( b2 + m2 <=1 , a2 > 0, u>c )
i3 = And(u>c, k3>0, d3>0, b3>a3, b3+m3 <=1, k3+d3 < 1)
def compute_inequality(i, val):
# generate numerical data for matplotlib fill method
i = i.subs(q, val)
s = ImplicitSeries(i, (u, 0, 1), (c, 0, 1))
return _matplotlib_list(s.get_data()[0])
# create the figure and initialize the regions
fig, ax = plt.subplots()
region1, = ax.fill(*compute_inequality(i1, init_q))
region2, = ax.fill(*compute_inequality(i2, init_q))
region3, = ax.fill(*compute_inequality(i3, init_q))
# adjust the main plot to make room for the sliders
fig.subplots_adjust(left=0.25, bottom=0.25)
# Make a horizontal slider to control the frequency.
ax_q = fig.add_axes([0.25, 0.1, 0.65, 0.03])
q_slider = Slider(
ax=ax_q,
label='q',
valmin=0,
valmax=5,
valinit=init_q,
)
# The function to be called anytime a slider's value changes
def update(val):
region1.set_xy(np.c_[compute_inequality(i1, val)])
region2.set_xy(np.c_[compute_inequality(i2, val)])
region3.set_xy(np.c_[compute_inequality(i3, val)])
fig.canvas.draw_idle()
# register the update function with each slider
q_slider.on_changed(update)
plt.show()
I am trying to solve the double integral of this complicated function. The function contains 3 symbolic variables which are defined with sympy.symbols. My goal is to integrate the function with respect to only two of the variables. sym.integrate run for 2 hours with no results to show. I tried numerical integration with scipy.integrate.dblquad. But I am having troubles which I suspect is due to the third symbolic variable. Is there a way to do this.
Problem summarized.
sym.symbols('x y z')
My_function(x,y,z)
Integrate My_function with respect to x and y (Both from 0 to inf i.e. definite integral).
Thank you in advance
h, t, w, r, q = sym.symbols('h t w r q') # Define symbols
wn = 2.0
alpha = 1.76
beta = 1.59
a0 = 0.7
a1 = 0.282
a2 = 0.167
b0 = 0.07
b1 = 0.3449
b2 = -0.2073
psi = 0.05
F_H = 1.0 - sym.exp(-(h / alpha) ** beta)
mu_h = a0 + a1 * h ** a2
sig_h = b0 + b1 * sym.exp(b2 * h)
F_TIH = (1 / 2) * (1 + sym.erf((sym.log(t) - mu_h) / (sig_h * sym.sqrt(2))))
f_h = sym.diff(F_H, h)
f_tzIhs = sym.diff(F_TIH, t)
f_S = f_h * f_tzIhs
H = (1.0 - (w / wn) ** 2.0 + 1.0j * 2.0 * psi * w / wn) ** (-1.0)
S_eta_h_t = h ** 2.0 * t / (8.0 * pi ** 2.0) * (w * t / (2.0 * pi)) ** (-5.0) * sym.exp(-1.0 / pi * (w * t / (2.0 * pi)) ** (-4.0))
S_RIS_hu_tu = abs(H) ** 2.0 * S_eta_h_t
m0_s = sym.integrate((w ** 0 * S_RIS_hu_tu), (w, 0, np.inf))
m0_s.doit()
m2_s = sym.integrate((w ** 2 * S_RIS_hu_tu), (w, 0, np.inf))
m2_s.doit()
v_rIs = 1 / (2 * pi) * sym.sqrt(m2_s / m0_s) * sym.exp(-r ** 2 / (2 * m0_s))
fun = v_rIs * f_S
# The integral I am trying to solve is a function of h,t and r.
integ_ht = sym.integrate(fun,(h,0,np.inf),(t,0,np.inf))
I am trying to compile some Python C extensions for both Windows and Linux. The most time consuming part of my program seems to be a for loop with a significant amount of simple calculations. When running it on Linux, it is about 2x slower than on Windows. Adding -O2 or -O3 seems to help a little bit, but not much. Are there any other optimization methods that would get it to a comparable speed?
The compiler I'm using is GCC: gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Here is the python equivalent. The C code is using a loop instead of numpy operations:
def cf(sigma, kappa, theta, rho, s0, v0, r, ttm, n,
alpha = 1.0, delta = 0.01, lambda_ = 0.002, u = -0.5):
x = np.log(s0)
phi = np.arange(n) * delta - 1j*(alpha + 1)
qq = kappa - 1j * rho * sigma * phi
d = np.sqrt(qq ** 2 + sigma ** 2 * phi ** 2 + 1j * sigma ** 2 * phi)
c = (qq - d) / (qq + d)
cc = 1j * phi * r * ttm + ((kappa * theta) / sigma ** 2) * \
((qq - d) * ttm - 2 * np.log((-c * np.exp(-d * ttm) + 1) / (1 - c)))
dd = ((qq - d) / sigma ** 2) * (1 - np.exp(-d * ttm)) / (-c * np.exp(-d * ttm)+1)
f = np.exp(cc + dd * v0 + 1j * phi * x)
return f
Say I have the following expression which I would like to integrate over the variable z from 0 to L.
import sympy as sp
mdot, D, R, alpha, beta, xi, mu0, q, cp, Tin, L = sp.symbols("\dot{m}, D, R, alpha, beta, xi, mu_0, q, c_p, T_in, L", real=True, positive=True, constant=True)
z = sp.symbols("z", real=True, positive=True)
n = sp.Symbol("n", real=True)
firstexpr = 8 * mdot**2 * R / (sp.pi**2 * D**5) * (alpha + beta * (sp.pi * D * mu0 / (4 * mdot))**xi * (q * z / (mdot * cp) + Tin)**(n * xi)) * (q * z / (mdot * cp) + Tin)
res1 = sp.integrate(firstexpr, (z, 0, L), conds="none")
This will take forever: I had to stop the computation after 10 minutes on my pc without getting an answer.
Situation improves dramatically if I rewrite my expression so that it contains only the minimum number of constant symbols, integrating it, and finally substituting the original symbols:
a = 8 * mdot**2 * R / (sp.pi**2 * D**5)
b = beta * (sp.pi * D * mu0 / (4 * mdot))**xi
c = q / (mdot * cp)
_a, _b, _c = sp.symbols("a, b, c", real=True, positive=True, constant=True)
secondexpr = _a * (alpha + _b * (_c * z + Tin)**(n * xi)) * (_c * z + Tin)
res2 = sp.integrate(secondexpr, (z, 0, L), conds="none")
sp.simplify(res2.subs([(_a, a), (_b, b), (_c, c)]))
Why is sympy taking extremely long time in the first case? Did I miss some assumption in the creation of my symbols?
This may seem like a silly question, but I am a bloody newby in Python (and in programming). I am running a physics simulation that involves many (~10 000) 2x2 matrices that I store in an array. I call these matrices M and the array T in the code below. Then I simply want to compute the product of all of these matrices. This is what I came up with, but it looks ugly and it would be so much work for 10000+ 2x2 matrices. Is there a simpler way or an inbuilt function that I could use?
import numpy as np
#build matrix M (dont read it, just an example, doesnt matter here)
def M(k1 , k2 , x):
a = (k1 + k2) * np.exp(1j * (k2-k1) * x)
b = (k1 - k2) * np.exp(-1j * (k1 + k2) * x)
c = (k1 - k2) * np.exp(1j * (k2 + k1) * x)
d = (k1 + k2) * np.exp(-1j * (k2 - k1) * x)
M = np.array([[a , b] , [c , d]])
M *= 1. / (2. * k1)
return M
#array of test matrices T
T = np.array([M(1,2,3), M(3,3,3), M(54,3,9), M(33,11,42) ,M(12,9,5)])
#compute the matrix product of T[0] * T[1] *... * T[4]
#I originally had this line of code, which is wrong, as pointed out in the comments
#np.dot(T[0],np.dot(T[1], np.dot(T[2], np.dot(T[2],np.dot(T[3],T[4])))))
#it should be:
np.dot(T[0], np.dot(T[1], np.dot(T[2],np.dot(T[3],T[4]))))
Not very NumPythonic, but you could do:
reduce(lambda x,y: np.dot(x,y), T, np.eye(2))
Or more concisely, as suggested
reduce(np.dot, T, np.eye(2))