تشغيل أكواد ماتلاب داخل بايثون باستخدام مكتبة oct2py: دمج قوة بايثون مع سهولة ماتلاب

يوضح هذا المقال كيفية تشغيل أكواد مشابهة لأكواد ماتلاب بسلاسة داخل بيئة بايثون، وذلك من خلال ربط أوكتاف (Octave) بمكتبة oct2py. سنتناول في هذا المقال إعداد بيئة العمل على جوجل كولاب، وتبادل البيانات بين مكتبة NumPy وأوكتاف، وكتابة واستدعاء ملفات .m، وعرض الرسوم البيانية المُولدة في أوكتاف داخل بايثون، بالإضافة إلى العمل مع أدوات الصناديق (Toolboxes)، والهياكل (Structs)، وملفات .mat. بهذه الطريقة، نحصل على مرونة بيئة بايثون مع الاستفادة من سهولة استخدام ونظام الحسابات القوي لماتلاب/أوكتاف في تدفق عمل واحد.

إعداد بيئة العمل وتثبيت المكتبات

نبدأ بإعداد أوكتاف والمكتبات الأساسية في جوجل كولاب، مع التأكد من توفر حزم Octave-Forge والتبعيات اللازمة في بايثون. نقوم بعد ذلك بتهيئة جلسة Oct2Py وتحديد دالة مساعدة لعرض الرسوم البيانية المُولدة في أوكتاف مباشرةً في تدفق عمل بايثون.

!apt-get -qq update
!apt-get -qq install -y octave gnuplot octave-signal octave-control > /dev/null
!python -m pip -q install 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("إصدار أوكتاف:", oc.eval("version"))

def show_png(path, title=None):
    img = Image.open(path)
    plt.figure(figsize=(5,4)); plt.imshow(img); plt.axis("off")
    if title: plt.title(title)
    plt.show()

تبادل البيانات والعمليات الأساسية

نقوم باختبار جسر الاتصال بين بايثون وأوكتاف من خلال تشغيل عمليات المصفوفات الأساسية، وتحليل القيم الذاتية، والتقييمات المثلثية مباشرةً في أوكتاف. ثم نتبادل مصفوفات NumPy مع أوكتاف لإجراء مرشح التفاف (Convolution Filter) والتحقق من شكله. أخيرًا، نوضح كيفية نقل قوائم بايثون إلى أوكتاف كمصفوفات خلوية (Cell Arrays)، وإنشاء هيكل (Struct)، واستعادته إلى بايثون لمشاركة البيانات بسلاسة.

print("n--- عمليات التقييم الأساسية ---")
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 ---")
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x) + 0.1*np.random.randn(x.size)
y_filt = oc.feval("conv", y, np.ones(5)/5.0, "same")
print("شكل y_filt:", np.asarray(y_filt).shape)

print("n--- الخلايا والهياكل ---")
cells = ["hello", 42, [1,2,3]]
oc.push("C", cells)
oc.eval("s = struct('name','Ada','score',99,'tags',{C});")
s = oc.pull("s")
print("الهيكل من أوكتاف إلى بايثون:", s)

كتابة واستدعاء ملفات .m

نقوم بكتابة دالة gradient_descent.m في أوكتاف، ونستدعيها من بايثون مع nout=2، ونؤكد استعادة الأوزان المعقولة وانخفاض الخسارة. ثم نقوم بعرض رسم بياني لجيب التمام المثبط (Damped Sine) في شكل أوكتاف خارج الشاشة، ونعرض ملف PNG المُحفظ داخل دفتر بايثون، مع الحفاظ على سلاسة تدفق العمل.

print("n--- كتابة واستدعاء ملفات .m ---")
gd_code = r"""
function [w, hist] = gradient_descent(X, y, alpha, iters)
% X: (n,m), y: (n,1). Adds bias; returns weights and loss history.
if size(X,2) == 0, error('X must be 2D'); end
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))
# ... (باقي الكود كما هو)

استخدام الحزم (Packages) وعرض الرسوم البيانية

نقوم بتحميل حزم الإشارة والتحكم (signal and control) لتصميم مرشح Butterworth في أوكتاف وعرض شكل الموجة المُرشحة في بايثون. كما نعمل مع مُعالجات الدوال (Function Handles) من خلال تقييم دالة تربيعية مجهولة في أوكتاف، ولضمان المتانة، نقوم بتعريف دالة quadfun.m المسماة والتي نستدعيها من بايثون، مما يُظهر كلاً من استدعاءات الدوال القائمة على المُعالجات واستدعاءات الدوال القائمة على الملفات في نفس التدفق.

تبادل ملفات .mat ومعالجة الأخطاء

نتبادل ملفات .mat بين بايثون وأوكتاف، ونؤكد على أن البيانات تتدفق في كلا الاتجاهين دون مشاكل. كما نقوم باختبار معالجة الأخطاء من خلال التقاط خطأ أوكتاف كاستثناء بايثون. بعد ذلك، نقوم بقياس أداء الجمع المُتجهي مقابل الجمع المُكرر (Loop) في أوكتاف، مما يُظهر ميزة الأداء للجمع المُتجهي. أخيرًا، نقوم بإنشاء خط أنابيب (Pipeline) متعدد الملفات يطبق الترشيح وكشف المغلف (Envelope Detection)، ويعيد الإحصائيات الرئيسية إلى بايثون، مما يُظهر كيفية تنظيم أكواد أوكتاف في مكونات قابلة لإعادة الاستخدام داخل تدفق عمل بايثون.

الخاتمة

يُظهر هذا المقال كيفية دمج ميزات أوكتاف المتوافقة مع ماتلاب مباشرةً في بايثون وجوجل كولاب. لقد قمنا بنجاح باختبار تبادل البيانات، والوظائف المُخصصة، وعرض الرسوم البيانية، واستخدام الحزم، وقياس أداء المعالجة، مما يُظهر إمكانية مزج تدفقات عمل ماتلاب/أوكتاف مع بايثون دون مغادرة دفتر الملاحظات. من خلال الجمع بين نقاط القوة لكلا البيئتين، نضع أنفسنا في وضع يسمح لنا بحل المشاكل بكفاءة أكبر ومرونة أكبر.

المصدر: MarkTechPost