The Routh-Hurwitz Criterion: A Cornerstone of Control Systems Analysis

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

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

ما هو خط (روث هورويتز)؟

ويُعتبر المعيار، الذي يُسمى بعد إدوارد جون روث وأدولف هورويتز، شرطا ضروريا وكافيا لاستقرار نظام مؤقت للتغيرات، ولتعددية المقاييس ذات الطابع الخاص:

(مع صفر)

ويبني النظام صفيفة " روث " من المعاملات، وهو نظام مستقر، إذا كانت جميع العناصر في العمود الأول من الصفوف إيجابية، وأي تغييرات في العلامات تدل على وجود أعمدة غير مستقرة، ونقطة الصفر في العمود الأول أو صف كامل من الصفر تشير إلى استقرار هامشي أو وجود جذور متوازية.

ويستخدم هذا المعيار على نطاق واسع لأنه يتجنب حل التعددية نفسها ويعمل مباشرة مع المعامِلات، غير أن البناء اليدوي لتعددية المقاييس من الدرجة 5 أو أعلى يصبح مضجراً ومعرضاً للأخطاء، مما يجعل التشغيل الآلي ذا قيمة عالية.

لماذا تفقد الاستقرار الآلي؟

ويتيح التشغيل الآلي لإجراءات روث - هورويتز مزايا كبيرة في الأوساط الأكاديمية والصناعية على السواء:

  • Speed and efficiency:] A script can evaluate dozens of polynomials per second, enabling rapid iteration during controller tuning or system identification.
  • Accuracy:] Eliminates arithmetic mistakes that commonly occur when building the spectrum by hand, especially when dealing with fractional or symbolic coefficients.
  • Parameter sweeps:] Engineers can systematically vary gains, time constants, or other design parameters and immediately see the effect on stability boundaries.
  • Integration with larger simulations:] The stability check can be embedded in optimization cycles, Monte Carlo analyses, or automated design scripts.
  • Reproducibility:] Scripts provide a documented, version-controlled analysis that can be easily shared and audit.

وبإلغاء الحساب الروتيني لـ (بايتون)، يمكن للمهندسين التركيز على قرارات التصميم الأعلى المستوى وتفسير النتائج.

مؤسسات تشييد روث آري

وقبل كتابة القانون، من الضروري فهم الخوارزمية التي يجب أن يتبعها النص، نظراً لتعددية الشهادات.

  1. ترتيب المعاملات في صفين: يتضمن الصف الأول مضامين من السلطات (البدء من أعلى السلطة)، أما الصف الثاني فيتضمن معاملات من السلطات الغريبة، مثلاً بالنسبة لرقم 5 متعدد المقاييس + 1s4 +2s3 +3+4s +5، والصف الأول هو [0، 2، 4]، والصف الثاني هو [5].
  2. صفائح مدفوعة الأجر مع صفر لضمان تساوي الطول إذا لزم الأمر
  3. إجراء اختبارات لاحقة باستخدام الصيغة:

(حيث يكون العنصر الأول من الصف السابق)

اكرر حتى يكون للصفوف صفائح رقم 1

A crucial nuance: If a zero appears in the first column of a row, the standard formula fails. The Routh spectrum construction must handle special cases:

  • Zero in first column ( but not all zeros in the row):] replace the zero with a small positive number Y, continue construction, then examine the signs as ⁇ ⁇ 0.
  • Entire row of zeros:] This indicates the presence of symmetrically placed roots (e.g., complex conjugate on the imaginary axis, or couples of roots with counter signs). The auxiliary polynomial formed from the row above the zero row must be used to continue the array.

ويجب أن يكشف نص آلي قوي كلا القضيتين ويعالجهما على النحو المناسب.

تنفيذ مبدأ " روث - هورويتز " في بيتون

المكتبات والإنشاءات

سنستخدم [(FLT:0)] SymPy] لالرياضيات الرمزية و]NumPy] للحساب الرقمي، والرمزية ذات قيمة خاصة عندما تنطوي المعاملات على بارامترات (مثلاً، المكاسب غير المعروفة) ليست أرقامية.

التنفيذ الرقمي الأساسي

ويقبل النص الأبسط قائمة بالمعاملات العددية (اللوحة أو البروتر) ويبني صفيفة الروث باستخدام الخرطي العائم، ويورد أدناه نسخة مستكملة وموسعة من المدونة الأساسية:

import numpy as np

def routh_hurwitz_numeric(coeffs):
 """
 Construct the Routh array for a polynomial with numeric coefficients.
 coeffs: list of coefficients from highest power down (a0, a1, ..., an)
 Returns a tuple (array, stability: str) or raises ValueError if first element is zero.
 """
 if coeffs[0] <= 0:
 raise ValueError("Coefficient a0 must be positive for standard Routh-Hurwitz.")
 n = len(coeffs) - 1
 # Build first two rows
 row1 = np.array([coeffs[i] for i in range(0, n+1, 2)], dtype=float)
 row2 = np.array([coeffs[i] for i in range(1, n+1, 2)], dtype=float)
 # Pad to same length
 max_len = max(len(row1), len(row2))
 row1 = np.pad(row1, (0, max_len - len(row1)))
 row2 = np.pad(row2, (0, max_len - len(row2)))
 routh = [row1.tolist(), row2.tolist()]

 for i in range(2, n+1):
 if routh[-1][0] == 0:
 # Special case: zero in first column
 # Replace with small epsilon (here we modify the row)
 routh[-1][0] = 1e-10 # Use a tiny positive number
 # Mark that epsilon was used (for sign analysis)
 # For simplicity, we assume epsilon > 0; later we can refine
 row = []
 for j in range(len(routh[0]) - 1):
 a = routh[i-2][0]
 b = routh[i-2][j+1] if j+1 < len(routh[i-2]) else 0
 c = routh[i-1][0]
 d = routh[i-1][j+1] if j+1 < len(routh[i-1]) else 0
 if c == 0:
 row.append(0) # Not reached because we handled epsilon above
 else:
 row.append((c * b - a * d) / c)
 if all(abs(x) < 1e-12 for x in row):
 # Entire row of zeros -> handle auxiliary polynomial
 return handle_auxiliary_row(routh, row, coeffs)
 routh.append(row)
 # Check stability
 first_col = [routh[i][0] for i in range(n+1)]
 if all(x > 0 for x in first_col):
 return routh, "Stable"
 else:
 return routh, "Unstable"

def handle_auxiliary_row(routh, zero_row, coeffs):
 # Extract row above zero row (the one that generated the auxiliary polynomial)
 prev_row = routh[-1]
 # Build auxiliary polynomial from prev_row: s^? (using degrees)
 # This is a simplified placeholder; full implementation requires polynomial differentiation
 # For detail, see reference.
 # For now, we raise an error indicating advanced handling needed.
 raise NotImplementedError("Entire row of zeros: auxiliary polynomial method required. Consider using sympy implementation.")

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

التنفيذ الرمزي باستخدام الرمز

إن القدرات الحسابية والقصوية المعقولة للرمز في هذا الصدد تسمح بتناول قضايا الصف الأول والصف المساعد معالجة نظيفة ودقيقة، وهنا نسخة رمزية كاملة:

import sympy as sp

def routh_hurwitz_symbolic(coeffs):
 """
 coeffs: list of symbolic or numeric coefficients (a0, a1, ..., an), a0 > 0.
 Returns the Routh array (list of lists) and a stability message.
 """
 coeffs = [sp.sympify(c) for c in coeffs]
 n = len(coeffs) - 1
 # First two rows
 row1 = [coeffs[i] for i in range(0, n+1, 2)]
 row2 = [coeffs[i] for i in range(1, n+1, 2)]
 # Pad
 max_len = max(len(row1), len(row2))
 row1 += [0] * (max_len - len(row1))
 row2 += [0] * (max_len - len(row2))
 routh = [row1, row2]

 epsilon = sp.symbols('epsilon', positive=True)

 for i in range(2, n+1):
 prev_row1 = routh[i-2]
 prev_row2 = routh[i-1]
 first_prev = prev_row2[0]
 # Check for zero in first column
 if first_prev == 0:
 if all(x == 0 for x in prev_row2):
 # Entire row of zeros
 # Build auxiliary polynomial from previous row
 # Ex: if row above zero row is [a, b, c, ...] -> auxiliary poly: a*s^? + b*s^? + ...
 # Need to reconstruct degrees. Function robuster needed.
 # For brevity, we refer to the extended implementation.
 return routh, "Marginal stability detected; auxiliary polynomial needed"
 else:
 # Replace zero with epsilon
 prev_row2 = [epsilon if j == 0 else prev_row2[j] for j in range(len(prev_row2))]
 first_prev = epsilon
 new_row = []
 for j in range(len(prev_row1) - 1):
 a = prev_row1[0]
 b = prev_row1[j+1] if j+1 < len(prev_row1) else 0
 c = first_prev
 d = prev_row2[j+1] if j+1 < len(prev_row2) else 0
 if c == 0:
 value = 0
 else:
 value = (c * b - a * d) / c
 new_row.append(sp.simplify(value))
 # Simplify the row
 new_row = [sp.simplify(x) for x in new_row]
 routh.append(new_row)
 # After building row, if epsilon was used, take limit epsilon -> 0+
 # This simplifies the row to a numeric result if possible.
 if epsilon in sp.flatten([sp.preorder_traversal(x) for x in new_row]):
 new_row = [sp.limit(x, epsilon, 0) for x in new_row]
 routh[-1] = new_row

 # Check first column signs
 first_col = [routh[i][0] for i in range(n+1)]
 # If any symbol still present, cannot decide numerically; user must substitute.
 if any(sp.sympify(x).has(sp.Symbol) for x in first_col):
 return routh, "Indeterminate due to symbolic parameters; substitute numeric values."
 signs = [sp.sign(x) for x in first_col]
 if all(s == 1 for s in signs):
 return routh, "Stable"
 elif any(s == -1 for s in signs):
 return routh, "Unstable"
 else:
 return routh, "Marginal stability (zeros in first column)"

وهذه الصيغة الرمزية تعالج بشكل صحيح الصفر، ويمكن، بمنطق إضافي، إدارة الصفوف الكاملة من الصفر، وهي مثالية للتحليلات المميزة التي تحتوي فيها المعامل على متغيرات رمزية مثل .

معالجة "أكتيري ارو" من "زيرو"

(د) إذا ظهر صف من الصف الأول، يجب أن يتحول البناء الموحد إلى الطريقة البوليومية المساعدة، وتتكون البوليفيات الإضافية من الصف الذي يتجاوز الصف الصفري مباشرة، وتقابل معاملات هذا الصف حتى سلطات العزل إذا كان الصف الصفري في مؤشر غريب، وما إلى ذلك.

الاختبار والتقييم

ويجب اختبار أي نص آلي على الحالات المعروفة، وإنشاء جناح اختبار يغطي:

  • Stable polynomials (e.g., - ⁇ stable)
  • بوليلومات غير مستقرة (مثلاً، - غير مستقرة بسبب تغيير التوقيع)
  • Polynomials with zero in first column (e.g., - ⁇ marginal or unstable depending on roots)
  • Polynomials with an entire row of zeros (e.g., - ⁇ marginal)
  • (مثل الدرجة 10) للتحقق من الأداء.

مقارنة مع الحسابات اليدوية أو النواتج المعروفة من مكتبة المراقبة أو وظائف روث مكرسة.

الإدماج في تدفقات العمل الهندسي

بمجرد أن يُعتمد على النص، يُدمجه في بيئة بيتون أوسع:

البارامترات

استخدام نومبي أو باندا لتوليد شبكة من قيم البارامترات (مثلاً كسب كاف من صفر إلى 100) في كل قيمة، حساب معامل التعددية السمية (عن طريق وظيفة نقل النظام)، وإدارة عملية التحقق من الاستقرار، وتخزين النتيجة.

import numpy as np
import matplotlib.pyplot as plt
from control import tf, feedback

def check_stability_for_gain(K):
 # Example: unity feedback with plant G(s) = K/(s^3 + 3s^2 + 2s)
 G = tf([K], [1, 3, 2, 0])
 T = feedback(G, 1)
 poly = T.den[0][0] # denominator coefficients
 stable = routh_hurwitz_numeric(poly) # call your function
 return stable

Ks = np.linspace(0, 20, 100)
stable_list = [check_stability_for_gain(K) for K in Ks]
plt.plot(Ks, stable_list)
plt.xlabel('Gain K')
plt.ylabel('Stable (1) / Unstable (0)')
plt.show()

وتكشف هذه المؤامرة بسرعة عن هوامش الاستقرار (مثل هامش الربح الذي يتغير فيه الاستقرار).

التصميم الآلي

على سبيل المثال، استخدام البصّة، التفعيل للتقليل من وظيفة التكلفة مع اشتراط معيار (روث-هيرويتز) لإعادة "ستابل" النسخة الرمزية تسمح بإجراء تقييم خالٍ من التدرج

دمج مع مذكرات الجوبيتر

مفكرة الجوبيتر مثالية للتحليل التفاعلي، تُعدّل وظيفة (روث هورويتز) بطباعة (سيمبي) الجميلة لعرض الصفوف خطوة، مما يجعلها تعليمية ومُهينة.

الاعتبارات المسبقة

الدقة العددية

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

معالجة البارامترات الرمزية بالاستهلاك

وعندما تنطوي المعاملات على رموز )مثلا، K، UM(، يمكن أن ينتج النص تعبيرات تتطلب تحليلا يدويا للعلامات، واستخدام رموز )(SemPy 's مع افتراضات لتبسيطها استنادا إلى النطاقات المعروفة )مثل K > 0(.

التوازي

For large parameter sweeps, parallelize using or . Each stability check is independent.

الاستنتاج وأفضل الممارسات

(أتممتة عمليات التحقق من استقرار (روث-هيرويتز مع نصوص (بايتون تحول عملية يدوية مضنية إلى أداة سريعة وموثوقة ومكثفة

  • بدء بفهم واضح للخوارزمية، بما في ذلك الحالات الخاصة.
  • Use SymPy] for symbolic coefficients and exact handling of the zero-row case.
  • Use NumPy] for pure numeric polynomials when speed is preval.
  • اختبار تنفيذك بشكل كبير مع مجموعة متنوعة من التعددية
  • إدماج المهمة في خطوط تحليل أوسع نطاقاً للتصميم والتعظيم.

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

]Note:] The code provided in this article is for educational purposes. For production use, consider contributing to or adopting established packages such as the Python Control Systems Library, which includes well-tested Routh-Hurwitz and other stability analysis functions:

مع النصوص الموجودة في يدك، أنت الآن على استعداد لفحص استقرار آلي لنظم من أي ترتيب، تحرير طاقتك العقلية للتحديات الإبداعية لتصميم نظام التحكم.