Transfer function estimation using scipy (Levenberg-Marquardt search) via user defined parameters

85 views Asked by At

I am trying to create a python3 application (in PyQt5) for transfer function estimation (which I have already estimated it via Matlab System Identification, so I know how it should look like with specific parameters) which the user is importing csv input/output data, and defining (which are the same as in Matlab):

  • number of zeros and poles
  • Continuous or discrete
  • initial conditions to be estimated by the algorithm or be randomly generated
  • maximum iterations
  • tolerance

The program is giving a transfer function but it is nowhere close to the output data also the first coefficients of the zeros and poles are always 1 (for 1 zero and 2 poles). If it is needed the sample time is 5 seconds.

Could you please suggest anything at this point? Any variant of the code would be appreciated as well.


def estimate_lm():
    try:
        num_zeros = int(entry_zeros.text())
        num_poles = int(entry_poles.text())
        time_type = entry_time.text()
        init_conditions = entry_init_cond.text()
        max_iterations = int(entry_iterations.text())
        tolerance = float(entry_tolerance.text())

        def transfer_function(params, t):
            zeros = params[:num_zeros]
            poles = params[num_zeros:]
            tf = TransferFunction(zeros, poles)
            lti_sys = lti(tf.num, tf.den)  # Create LTI system from transfer function
            _, output_estimate, _ = lti_sys.output(U=self.input_data, T=t)  # Calculate output
            return output_estimate

        def cost_function(params, t, y):
            return transfer_function(params, t) - y

        initial_guess = np.ones(num_zeros + num_poles)
        result = least_squares(cost_function, initial_guess, args=(np.arange(len(self.input_data)), self.output_data),
                            method='lm', max_nfev=max_iterations, ftol=tolerance)
        print(result)

        self.params = result.x
        self.num_zeros = num_zeros
        self.num_poles = num_poles
        print("Estimation completed using LM method")
    except Exception as e:
        print(f"Error in estimation: {e}")

This is the result of estimation:

enter image description here

I have tried many methods including hard-coded parameters but the result does not change!

0

There are 0 answers