Search code examples
pythongoogle-colaboratory

How can I test linearity (superposition) & shift-invariance in Python?


I'm new to Python & writing a program that takes a function:

X = np.linspace(0,50)
F1 = np.sin(X)

Tests whether the function is linear (as in, exhibits superposition):

for i in range(1,10):
  LT1 = i*(F1)
  X = i*X
  LT2 = F1
  if np.all(LT1) == np.all(LT2):
    Linear = 'This function is linear.'
  elif np.all(LT1) != np.all(LT2):
    Linear = 'This function is nonlinear.'
    break

And tests whether the function is shift-invariant:

for j in range(1,10):
  SI1 = (F1)-j
  X = X-j
  SI2 = F1
  if np.all(SI1) == np.all(SI2):
    SI = 'This function is shift-invariant.'
  elif np.all(SI1) != np.all(SI2):
    SI = 'This function is shift-variant.'
    break

But my code calls all functions, LSI or not, linear & shift-variant. Is there a better way to run these tests? I've seen linear regression offered as a means of testing linearity, but upon trying it with a sine function it misclassified the function as nonlinear. I have also been unable to find any guidance whatsoever on testing shift-invariance.


Solution

  • Lets first define all the required functionality

    import numpy as np
    
    def check_linearity(T, X, a, b):
      # T[a*x+b*x] = a*T[x] + b*T[x]
      LHS = T(a*x + b*x)
      RHS = a*T(x) + b*T(x)
      tolerence = 1e-4
      if np.sum(LHS-RHS) < tolerence:
        print('Linear System')
        return True
      else:
        print('Not a Linear System')
        return False
    
    def check_shift_invariance(T, X, tau):
      # T[X] = T[X-tau]
      LHS = T(X)
      RHS = T(X-tau)
      tolerence = 1e-4
      if np.sum(LHS-RHS) < tolerence:
        print('Shift Invariant System')
        return True
      else:
        print('Not a Shift Invariant System')
        return False
    
    def check_LSI(T, X, a, b, tau):
      flag1 = check_linearity(T, X, a, b)
      flag2 = check_shift_invariance(T, X, tau)
      if flag1== True and flag2==True:
        print('LSI system')
      else:
        print('not a LSI system') 
    

    Next, we define signal

    # Signal X in range [-1,1]
    X = np.linspace(-1,1,10)
    

    The, define System

    # Transformation T 
    T = lambda x: np.sin(x)
    

    Now lets see everything we defined in action

    a = 1
    b = 1
    tau = 2*np.pi
    # Check Linearity
    check_linearity(T, X, a, b);
    # Check Shift Invariance
    check_shift_invariance(T, X, tau);
    # Check LSI or not
    check_LSI(T, X, a, b, tau);
    

    You can easily define other systems like,

    T = lambda x: x
    T = lambda x:  np.sin(x) + np.cos(x)
    T = lambda x: x**2 + x + 2
    

    and so on