The orthogonal rational approximation (ORA) algorithm allows users to fit a rational function to known frequency-dependent data from simulations or measurements. This algorithm is implemented in MATLAB®.
This function works with Touchstone® .SnP files (ex. .s2p, s10p, etc.).
To use these files:
- Copy and paste the numfit, denfit, and ORA files and save them in the same folder as numfit.m, denfit.m, and ORA.m
- Call the ORA function from a MATLAB® .m file with the Touchstone® file name as an input. For example: ora(“myFileHere.s2p”, [1 1; 1 2; 2 1; 2 2], 30, 30, 20)
- Run the MATLAB file.
MATLAB is a registered trademark of The MathWorks, Inc. (http://www.mathworks.com)
Please cite:
Ma, A, Engin, AE. Orthogonal rational approximation of transfer functions for high-frequency circuits. Int J Circ Theor Appl. 2022; 1– 13. doi:10.1002/cta.3488
Creative Commons License:
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.
Download Files:
clear all; close all; clc; % Orthogonal Rational Approximation (ORA) % San Diego State University % Revision Date: 09-09-2024 % Ma, A, Engin, AE. Orthogonal rational approximation of transfer functions for high-frequency circuits. % Int J Circ Theor Appl. 2022; 1- 13. doi:10.1002/cta.3488 file = 'st4_01.s2p'; %Touchstone .snp data file param_indices = [1 1; 1 2]; %ex: S11, S12 = [1 1; 1 2] % ----------------------------------------------- % % ----------------------------------------------- % % ----------------------------------------------- % touch = sparameters(file); params = touch.Parameters; frequency = touch.Frequencies; p=size(touch.Parameters,1); params_extracted = []; for i=1:length(param_indices(:,1)) params_extracted = [params_extracted squeeze(params(param_indices(i,1),param_indices(i,2),:))]; end w = frequency .* 2 .* pi; %rad/s x = 1j .* w; minPoles = 30; maxPoles = 50; numberOfPoles = minPoles:1:maxPoles; rms_error_ORA_iter = zeros(length(numberOfPoles), 1); error_ORA_iter = zeros(length(numberOfPoles), length(param_indices)); for i=1:length(numberOfPoles) [poles_ora, fit_ora, myss_ora, err_ora] = ora(touch, param_indices, numberOfPoles(i), numberOfPoles(i), 20); error_ORA_iter = abs(fit_ora-params_extracted); rms_error_ORA_iter(i, 1) = err_ora; end % ------------------ Figures ------------------- % figure for m=1:length(param_indices(:,1)) semilogy(frequency, abs(params_extracted(:, m)), 'LineWidth', 1, 'Color', 'b'); if m == 1 hold on; end semilogy(frequency, abs(fit_ora(:, m)), '--', 'LineWidth', 1, 'Color', 'r'); semilogy(frequency,error_ORA_iter(:,m), '--', 'Color', '#808080', 'LineWidth', 1); end hold off; xlabel('Frequency [Hz]') ylabel('Magnitude') legend("Data", "ORA", "Deviation"); title('Data') axes1 = gca; set(axes1,'FontSize',14); figure semilogy(numberOfPoles, rms_error_ORA_iter); xlabel('Poles') ylabel('rms error') title('Error') legend('ORA') axes2 = gca; set(axes2,'FontSize',14);