LSR/env/lib/python3.6/site-packages/control/tests/delay_test.py
2020-06-04 17:24:47 +02:00

93 lines
3.4 KiB
Python

#!/usr/bin/env python -*-coding: utf-8-*-
#
# Test Pade approx
#
# Primitive; ideally test to numerical limits
from __future__ import division
import unittest
import numpy as np
from control.delay import pade
class TestPade(unittest.TestCase):
# Reference data from Miklos Vajta's paper "Some remarks on
# Padé-approximations", Table 1, with corrections. The
# corrections are to highest power coeff in numerator for
# (ddeg,ndeg)=(4,3) and (5,4); use Eq (12) in the paper to verify
# all for T = 1
ref = [
# dendeg numdeg den num
( 1, 1, [1,2], [-1,2]),
( 1, 0, [1,1], [1]),
( 2, 2, [1,6,12], [1,-6,12]),
( 2, 1, [1,4,6], [-2,6]),
( 3, 3, [1,12,60,120], [-1,12,-60,120]),
( 3, 2, [1,9,36,60], [3,-24,60]),
( 4, 4, [1,20,180,840,1680], [1,-20,180,-840,1680]),
( 4, 3, [1,16,120,480,840], [-4,60,-360,840]),
( 5, 5, [1,30,420,3360,15120,30240], [-1,30,-420,3360,-15120,30240]),
( 5, 4, [1,25,300,2100,8400,15120,], [5,-120,1260,-6720,15120]),
]
def testRefs(self):
"test reference cases for T=1"
T = 1
for dendeg, numdeg, refden, refnum in self.ref:
num, den = pade(T, dendeg, numdeg)
np.testing.assert_array_almost_equal_nulp(np.array(refden), den, nulp=2)
np.testing.assert_array_almost_equal_nulp(np.array(refnum), num, nulp=2)
def testTvalues(self):
"test reference cases for T!=1"
Ts = [1/53, 21.95]
for dendeg, numdeg, baseden, basenum in self.ref:
for T in Ts:
refden = T**np.arange(dendeg, -1, -1)*baseden
refnum = T**np.arange(numdeg, -1, -1)*basenum
refnum /= refden[0]
refden /= refden[0]
num, den = pade(T, dendeg, numdeg)
np.testing.assert_array_almost_equal_nulp(refden, den, nulp=2)
np.testing.assert_array_almost_equal_nulp(refnum, num, nulp=2)
def testErrors(self):
"ValueError raised for invalid arguments"
self.assertRaises(ValueError,pade,-1,1) # T<0
self.assertRaises(ValueError,pade,1,-1) # dendeg < 0
self.assertRaises(ValueError,pade,1,2,-3) # numdeg < 0
self.assertRaises(ValueError,pade,1,2,3) # numdeg > dendeg
def testNumdeg(self):
"numdeg argument follows docs"
# trivialish - interface check, not math check
T = 1
dendeg = 5
ref = [pade(T,dendeg,numdeg)
for numdeg in range(0,dendeg+1)]
testneg = [pade(T,dendeg,numdeg)
for numdeg in range(-dendeg,0)]
self.assertEqual(ref[:-1],testneg)
self.assertEqual(ref[-1], pade(T,dendeg,dendeg))
self.assertEqual(ref[-1], pade(T,dendeg,None))
self.assertEqual(ref[-1], pade(T,dendeg))
def testT0(self):
"T=0 always returns [1],[1]"
T = 0
refnum = [1.0]
refden = [1.0]
for dendeg in range(1, 6):
for numdeg in range(0, dendeg+1):
num, den = pade(T, dendeg, numdeg)
np.testing.assert_array_almost_equal_nulp(np.array(refnum), np.array(num))
np.testing.assert_array_almost_equal_nulp(np.array(refden), np.array(den))
if __name__ == '__main__':
unittest.main()