Run MATLAB-Style Code Inside Python by Connecting Octave with the oct2py Library
In this tutorial, we discover how we are able to seamlessly run MATLAB-style code inside Python by connecting Octave with the oct2py library. We arrange the setting on Google Colab, alternate knowledge between NumPy and Octave, write and name .m information, visualize plots generated in Octave inside Python, and even work with toolboxes, structs, and .mat information. By doing this, we acquire the flexibility of Python’s ecosystem whereas persevering with to leverage the acquainted syntax and numerical energy of MATLAB/Octave in a single workflow. Check out the FULL CODES here.
!apt-get -qq replace
!apt-get -qq set up -y octave gnuplot octave-signal octave-control > /dev/null
!python -m pip -q set up oct2py scipy matplotlib pillow
from oct2py import Oct2Py, Oct2PyError
import numpy as np, matplotlib.pyplot as plt, textwrap
from scipy.io import savemat, loadmat
from PIL import Image
oc = Oct2Py()
print("Octave model:", oc.eval("model"))
def show_png(path, title=None):
img = Image.open(path)
plt.determine(figsize=(5,4)); plt.imshow(img); plt.axis("off")
if title: plt.title(title)
plt.present()
We start by organising Octave and important libraries in Google Colab, making certain that we have now Octave-Forge packages and Python dependencies prepared. We then initialize an Oct2Py session and outline a helper perform so we are able to show Octave-generated plots straight in our Python workflow. Check out the FULL CODES here.
print("n--- Basic eval ---")
print(oc.eval("A = magic(4); A"))
print("eig(A) diag:", oc.eval("[V,D]=eig(A); diag(D)'"))
print("sin(pi/4):", oc.eval("sin(pi/4)"))
print("n--- NumPy alternate ---")
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x) + 0.1*np.random.randn(x.measurement)
y_filt = oc.feval("conv", y, np.ones(5)/5.0, "similar")
print("y_filt form:", np.asarray(y_filt).form)
print("n--- Cells & Structs ---")
cells = ["hello", 42, [1,2,3]]
oc.push("C", cells)
oc.eval("s = struct('identify','Ada','rating',99,'tags',{C});")
s = oc.pull("s")
print("Struct from Octave -> Python:", s)
We take a look at the bridge between Python and Octave by operating primary matrix operations, eigenvalue decomposition, and trigonometric evaluations straight in Octave. We then alternate NumPy arrays with Octave to carry out a convolution filter and confirm its form. Finally, we reveal find out how to push Python lists into Octave as cell arrays, construct a struct, and retrieve it again into Python for seamless knowledge sharing. Check out the FULL CODES here.
print("n--- Writing and calling .m information ---")
gd_code = r"""
perform [w, hist] = gradient_descent(X, y, alpha, iters)
% X: (n,m), y: (n,1). Adds bias; returns weights and loss historical past.
if measurement(X,2) == 0, error('X have to be 2D'); finish
n = rows(X);
Xb = [ones(n,1), X];
m = columns(Xb);
w = zeros(m,1);
hist = zeros(iters,1);
for t=1:iters
yhat = Xb*w;
g = (Xb'*(yhat - y))/n;
w = w - alpha * g;
hist(t) = (sum((yhat - y).^2)/(2*n));
endfor
endfunction
"""
with open("gradient_descent.m","w") as f: f.write(textwrap.dedent(gd_code))
np.random.seed(0)
X = np.random.randn(200, 3)
true_w = np.array([2.0, -1.0, 0.5, 3.0])
y = true_w[0] + X @ true_w[1:] + 0.3*np.random.randn(200)
w_est, hist = oc.gradient_descent(X, y.reshape(-1,1), 0.1, 100, nout=2)
print("Estimated w:", np.ravel(w_est))
print("Final loss:", float(np.ravel(hist)[-1]))
print("n--- Octave plotting -> PNG -> Python show ---")
oc.eval("x = linspace(0,2*pi,400); y = sin(2*x) .* exp(-0.2*x);")
oc.eval("determine('seen','off'); plot(x,y,'linewidth',2); grid on; title('Damped Sine (Octave)');")
plot_path = "/content material/oct_plot.png"
oc.eval(f"print('{plot_path}','-dpng'); shut all;")
show_png(plot_path, title="Octave-generated Plot")
We write a customized gradient_descent.m in Octave, name it from Python with nout=2, and make sure that we get well affordable weights and a reducing loss. We then render a damped sine plot in an off-screen Octave determine and show the saved PNG inline in our Python pocket book, preserving the complete workflow seamless. Check out the FULL CODES here.
print("n--- Packages (sign/management) ---")
signal_ok = True
strive:
oc.eval("pkg load sign; pkg load management;")
print("Loaded: sign, management")
besides Oct2PyError as e:
signal_ok = False
print("Could not load sign/management, skipping package deal demo.nReason:", str(e).splitlines()[0])
if signal_ok:
oc.push("t", np.linspace(0,1,800))
oc.eval("x = sin(2*pi*5*t) + 0.5*sin(2*pi*40*t);")
oc.eval("[b,a] = butter(4, 10/(800/2)); xf = filtfilt(b,a,x);")
xf = oc.pull("xf")
plt.determine(); plt.plot(xf); plt.title("Octave sign package deal: filtered"); plt.present()
print("n--- Function handles ---")
oc.eval("""
f = @(z) z.^2 + 3*z + 2;
vals = feval(f, [0 1 2 3]);
""")
vals = oc.pull("vals")
print("f([0,1,2,3]) =", np.ravel(vals))
quadfun_code = r"""
perform y = quadfun(z)
y = z.^2 + 3*z + 2;
finish
"""
with open("quadfun.m","w") as f: f.write(textwrap.dedent(quadfun_code))
vals2 = oc.quadfun(np.array([0,1,2,3], dtype=float))
print("quadfun([0,1,2,3]) =", np.ravel(vals2))
We load the sign and management packages so we are able to design a Butterworth filter in Octave and visualize the filtered waveform again in Python. We additionally work with perform handles by evaluating an nameless quadratic inside Octave and, for robustness, outline a named quadfun.m that we name from Python, displaying each handle-based and file-based perform calls in the similar movement. Check out the FULL CODES here.
print("n--- .mat I/O ---")
data_py = {"A": np.arange(9).reshape(3,3), "label": "demo"}
savemat("demo.mat", data_py)
oc.eval("load('demo.mat'); A2 = A + 1;")
oc.eval("save('-mat','demo_from_octave.mat','A2','label');")
again = loadmat("demo_from_octave.mat")
print("Keys from Octave-saved mat:", checklist(again.keys()))
print("n--- Error dealing with ---")
strive:
oc.eval("no_such_function(1,2,3);")
besides Oct2PyError as e:
print("Caught Octave error as Python exception:n", str(e).splitlines()[0])
print("n--- Simple Octave benchmark ---")
oc.eval("N = 2e6; a = rand(N,1);")
oc.eval("tic; s1 = sum(a); television = toc;")
t_vec = float(oc.pull("television"))
oc.eval("tic; s2 = 0; for i=1:size(a), s2 += a(i); finish; tl = toc;")
t_loop = float(oc.pull("tl"))
print(f"Vectorized sum: {t_vec:.4f}s | Loop sum: {t_loop:.4f}s")
print("n--- Multi-file pipeline ---")
pipeline_m = r"""
perform out = mini_pipeline(x, fs)
strive, pkg load sign; catch, finish
[b,a] = butter(6, 0.2);
y = filtfilt(b,a,x);
y_env = abs(hilbert(y));
out = struct('rms', sqrt(imply(y.^2)), 'peak', max(abs(y)), 'env', y_env(1:10));
finish
"""
with open("mini_pipeline.m","w") as f: f.write(textwrap.dedent(pipeline_m))
fs = 200.0
sig = np.sin(2*np.pi*3*np.linspace(0,3,int(3*fs))) + 0.1*np.random.randn(int(3*fs))
out = oc.mini_pipeline(sig, fs, nout=1)
print("mini_pipeline -> keys:", checklist(out.keys()))
print("RMS ~", float(out["rms"]), "| Peak ~", float(out["peak"]), "| env head:", np.ravel(out["env"])[:5])
print("nAll sections executed. You at the moment are operating MATLAB/Octave code from Python!")
We alternate .mat information between Python and Octave, confirming that knowledge flows each methods with out points. We additionally take a look at error dealing with by catching an Octave error as a Python exception. Next, we benchmark vectorized versus looped summations in Octave, displaying the efficiency fringe of vectorization. Finally, we constructed a multi-file pipeline that applies filtering and envelope detection, returning key statistics to Python, which demonstrates how we are able to manage Octave code into reusable elements inside our Python workflow.
In conclusion, we see how we are able to combine Octave’s MATLAB-compatible options straight into Python and Colab. We efficiently take a look at knowledge alternate, customized features, plotting, package deal utilization, and efficiency benchmarking, demonstrating that we are able to combine MATLAB/Octave workflows with Python with out leaving our pocket book. By combining the strengths of each environments, we put ourselves ready to resolve issues extra effectively and with better flexibility.
Check out the FULL CODES here. Feel free to take a look at our GitHub Page for Tutorials, Codes and Notebooks. Also, be happy to comply with us on Twitter and don’t overlook to hitch our 100k+ ML SubReddit and Subscribe to our Newsletter.
The submit Run MATLAB-Style Code Inside Python by Connecting Octave with the oct2py Library appeared first on MarkTechPost.