UPDATE as of 04/06/2026
END UPDATE
Command-line utility "aqtinstall" enables plotting in Python 3.14.3t by automating the installation of Qt binaries (e.g., PyQt6 ) , which are required by libraries like Matplotlib to render interactive graphs. It serves as a command-line alternative to the official Qt installer, facilitating the setup of necessary GUI frameworks, often in CI environments or specific Python versions. Dependency Management: It resolves and installs the required Qt components, allowing pip install matplotlib to function correctly for creating interactive plots. Version Compatibility: It can install specific, prebuilt Qt binaries compatible with the latest Python versions, such as 3.14, by targeting the required OS and compiler. Integration: The installed Qt libraries allow Matplotlib plots to be embedded directly into GUI applications, providing interactive, zoomable, and pannable figures.
$ sudo apt update
$ sudo apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev git gcc
$ curl -fsSL https://pyenv.run | bash
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ source ~/.bashrc
List versions: pyenv install --list
$ pyenv install 3.14.3t
Set global version
For python3.14.3t instead of PyQt6 install
$ pip install aqtinstall
in virtual environment of python3.14.3t
$ mkdir MULTITHREAD
$ cd MULTITHREAD
$ python3.14t -m venv .env
$ source .env/bin/activate
$ pip install aqtinstall
$ pip install --upgrade pip
$ pip install numpy matplotlib cxroots
import numpy as np
from cxroots import Circle
import threading
import logging
import os
import sys
# Silence internal library logs
logging.getLogger('cxroots').setLevel(logging.ERROR)
def analyze_circle(radius, f, df, t_vals):
"""Worker function to analyze a specific radius in parallel."""
# 1. Manual Integration
contour_points = radius * np.exp(1j * t_vals)
fz = f(contour_points)
dfz = df(contour_points)
integrand = dfz / fz
dz = np.diff(contour_points, append=contour_points[0])
manual_count = int(np.round((np.sum(integrand * dz) / (2j * np.pi)).real))
# 2. cxroots Calculation (Redirecting stdout to keep it clean)
with open(os.devnull, 'w') as fnull:
old_stdout = sys.stdout
sys.stdout = fnull
try:
C = Circle(0, radius)
roots = C.roots(f, df)
finally:
sys.stdout = old_stdout
# Thread-safe printing of results
output = (
f"\n--- Results for Radius {radius} ---\n"
f"Manual Count: {manual_count} zeros\n"
f"{roots}\n"
)
print(output)
if __name__ == "__main__":
f = lambda z: z**13 + 5*z + 2
df = lambda z: 13*z**12 + 5
t_vals = np.linspace(0, 2 * np.pi, 1000)
print("The Argument Principle and Logarithmic Derivative (Parallel 3.14.3t)")
print("f(z) = z**13 + 5*z + 2\n")
# Define tasks for radius 3 and radius 1
t1 = threading.Thread(target=analyze_circle, args=(3, f, df, t_vals))
# Start parallel execution
t1.start()
# Wait for completion
t1.join()
import numpy as np
from cxroots import Circle
import os
import matplotlib.pyplot as plt
import threading
import logging
import sys
# 1. Silence all library logging (cxroots, Matplotlib, Qt)
logging.getLogger('cxroots').setLevel(logging.ERROR)
os.environ["QT_LOGGING_RULES"] = "*.debug=false;qt.qpa.fonts.warning=false"
def count_zeros_worker(f, df, contour_points):
# Perform math
fz, dfz = f(contour_points), df(contour_points)
integrand = dfz / fz
dz = np.diff(contour_points, append=contour_points[0])
count = int(np.round((np.sum(integrand * dz) / (2j * np.pi)).real))
# Only this prints to console
# print(f"Number of zeros (Manual): {count}")
def find_roots_worker(f, df, res):
# Silence stdout locally to hide cxroots progress bars/info
with open(os.devnull, 'w') as fnull:
old_stdout = sys.stdout
sys.stdout = fnull
try:
C = Circle(0, 4)
roots = C.roots(f, df)
finally:
sys.stdout = old_stdout
res['roots'] = roots
print(f"Number of zeros (cxroots): {len(roots.roots)}")
if __name__ == "__main__":
f = lambda z: z**13 + 5*z + 2
df = lambda z: 13*z**12 + 5
t_vals = np.linspace(0, 2 * np.pi, 1000)
circle_pts = 4 * np.exp(1j * t_vals)
shared_res = {}
# Parallel threads in 3.14.3t
t1 = threading.Thread(target=count_zeros_worker, args=(f, df, circle_pts))
t2 = threading.Thread(target=find_roots_worker, args=(f, df, shared_res))
t1.start()
t2.start()
t1.join()
t2.join()
# Show final plot
if 'roots' in shared_res:
shared_res['roots'].show()
❯ cat complexThreaded08.py
import os
import numpy as np
import matplotlib.pyplot as plt
from cxroots import Circle
from concurrent.futures import ThreadPoolExecutor
# Silence Qt warnings
os.environ["QT_LOGGING_RULES"] = "*.debug=false;qt.qpa.fonts.warning=false"
def count_zeros_task(f, df, contour_points):
"""Calculates zeros via the Argument Principle."""
fz, dfz = f(contour_points), df(contour_points)
integrand = dfz / fz
dz = np.diff(contour_points, append=contour_points[0])
integral = np.sum(integrand * dz)
return int(np.round((integral / (2j * np.pi)).real))
def find_roots_task(contour, f, df):
"""Calculates specific root locations using cxroots."""
return contour.roots(f, df)
# 1. Setup Data
f = lambda z: 4*z**5 + 4*z**3 - 4*z + 9
df = lambda z: 20*z**4 + 12*z**2 - 4
t = np.linspace(0, 2 * np.pi, 1000)
circle_pts = 4 * np.exp(1j * t)
C = Circle(0, 4)
print("Starting concurrent calculations...")
# 2. Parallel Execution
with ThreadPoolExecutor() as executor:
# Submit both tasks to run simultaneously
future_count = executor.submit(count_zeros_task, f, df, circle_pts)
future_roots = executor.submit(find_roots_task, C, f, df)
# Retrieve results (this waits for each to finish)
zero_count = future_count.result()
roots_result = future_roots.result()
# 3. Output and Visualization
print(f"\nVerification (Argument Principle): {zero_count} zeros found.")
print(f"Detailed Root Analysis:\n{roots_result}")
# Plotting must happen on the main thread
roots_result.show()
plt.show()
import os
import numpy as np
import matplotlib.pyplot as plt
from cxroots import Circle
from concurrent.futures import ThreadPoolExecutor
# Silence Qt warnings
os.environ["QT_LOGGING_RULES"] = "*.debug=false;qt.qpa.fonts.warning=false"
def count_zeros_task(f, df, contour_points):
"""Calculates zeros via the Argument Principle."""
fz, dfz = f(contour_points), df(contour_points)
integrand = dfz / fz
dz = np.diff(contour_points, append=contour_points[0])
integral = np.sum(integrand * dz)
return int(np.round((integral / (2j * np.pi)).real))
def find_roots_task(contour, f, df):
"""Calculates specific root locations using cxroots."""
return contour.roots(f, df)
# 1. Setup Data
f = lambda z: z**13 + 5*z + 2
df = lambda z: 13*z**12 + 5
t = np.linspace(0, 2 * np.pi, 1000)
circle_pts = 4 * np.exp(1j * t)
C = Circle(0, 4)
print("Starting concurrent calculations...")
# 2. Parallel Execution
with ThreadPoolExecutor() as executor:
# Submit both tasks to run simultaneously
future_count = executor.submit(count_zeros_task, f, df, circle_pts)
future_roots = executor.submit(find_roots_task, C, f, df)
# Retrieve results (this waits for each to finish)
zero_count = future_count.result()
roots_result = future_roots.result()
# 3. Output and Visualization
print(f"\nVerification (Argument Principle): {zero_count} zeros found.")
print(f"Detailed Root Analysis:\n{roots_result}")
# Plotting must happen on the main thread
roots_result.show()
plt.show()




No comments:
Post a Comment