mkoijn
Structural
- Jan 7, 2003
- 28
The following code is part of a program I've cobbled together to extract modal parameters from multiple frf's, it extracts the polynomial coeffiients. It's adapted from the diamond modal toolbox and I'm running it in GNU Octave which is an open source matlab clone.
The problem I'm having is that I run out of memeory when I use more than about 40 frf's ( using synthesised data consisting of 5 modes, 190 points per frf), also at 40 frf's it's taking about 2 minutes to calculate the polynomial coefficients ( 1GHz processor,380Mb ram). The function rpcoeffs is pretty much as it came from diamond
Has anyone an idea why this is happening? Does it react similarly in Matlab? any help would be gratefully received
If anyone would like to try it,the input arguments for rpcoeffs are as follows:
h = matrix of frf's arranged in columns
wi= vector of frequencies for frf's
m= order of numerator polynomial ( I used number of modes*2-1+4 for extra terms)
n=order of denominator polynomial (number of modes*2)
function [A,B] = rpcoeffs(h,wi,m,n)
% Usage: [A,B] = rpcoeffs(h,wi,m,n)
% List of variables:
% m = order of numerator polynomial
% n = order of denomenator polynomial
% L = number of frequency bins to curve fit
% h = FRF matrix values at selected frequencies
% wi = vector of frequencies to use (indexed 1 to L)
% Pnum, Pden = matrices of complex orthogonal Forsythe Polynomials (one-sided)
% row i = ith frequency
% column j = (j-1)th order polynomial
% qnum = weights for numerator Forsythe poly. (m+1 x 1)
% qden = weights for denomenator Forsythe poly. (n+1 x 1)
%
%
% Normalize frequency variables
% and make FRF curve 2-sided
j = sqrt(-1);
L1 = length(wi);
wmax = wi(L1);
wi = wi/wmax;
wi = [-wi(L1:-1:1);wi];
xi = j*wi;
h = [conj(h(L1:-1:1,
);h];
L = length(wi);
nh = size(h,2); % Total number of FRFs to Curve-fit
%
% Generate Orthogonal Forsythe Polynomials
%
% Numerator Polynomials
qnum = ones(L,1); % numerator poly. weights
[Pnum,unum,vnum] = forsythe(xi,qnum,m);
% Denomenator Polynomials
qden = zeros(L,1);
for i = 1:L,
qden(i) = max(svd(h(i,
)); % Use CMIF as denomenator poly. weights
end
[Pden,uden,vden] = forsythe(xi,qden,n);
%
% Form matrices for Least-Squares solution
%
P = Pnum;
SOLROW = zeros(L*nh,(m+1)*nh + n);
WCUM = zeros(L*nh,1);
for hc = 1:nh,
T = zeros(L,n);
for i = 1:n,
T
,i) = Pden
,i) .* h
,hc);
end
W = h
,hc) .* Pden
,n+1);
SOLROW((hc-1)*L + 1 : hc*L , (hc-1)*(m+1) + 1 : hc*(m+1)) = P;
SOLROW((hc-1)*L + 1 : hc*L , (m+1)*nh + 1 : (m+1)*nh + n) = -T;
WCUM((hc-1)*L + 1 : hc*L,1 ) = W;
end
%
% Solve for the Forsythe polynomial coefficients
%
SOL = SOLROW \ WCUM;
for hc = 1:nh,
C
,hc) = SOL((hc-1)*(m+1) + 1: hc*(m+1));
end
D = [SOL((m+1)*nh + 1
m+1)*nh + n);1];
%
% Convert Forsythe Poly. coefficients back to normal poly. coeffs.
%
bkm_num = bkm_comp(m,unum,vnum);
bkm_den = bkm_comp(n,uden,vden);
for hc = 1:nh,
% Numerator
for k = 0:m,
C1(k+1) = 0;
for mm = k:m,
C1(k+1) = C1(k+1) + C(mm+1,hc) * bkm_num(k+1,mm+1);
end
C1(k+1) = C1(k+1) / wmax^k;
end
A
,hc) = real(C1(length(C1):-1:1))';
end
% Denomenator
for k = 0:n,
D1(k+1) = 0;
for mm = k:n,
D1(k+1) = D1(k+1) + D(mm+1) * bkm_den(k+1,mm+1);
end
D1(k+1) = D1(k+1) / wmax^k;
end
B = real(D1(length(D1):-1:1))';
return
_____________________________________________
function [P,u,v] = forsythe(xi,q,m)
L = length(xi);
P = zeros(L,m+1);
u = zeros(m+1,1);
v = zeros(m+1,1);
%
% Define zero-th order poly.
%
P
,1) = ones(L,1);
%
% Define first order poly.
%
d(1) = sum( P
,1).^2 .* q.^2);
u(2) = sum( xi .* P
,1).^2 .* q.^2) / d(1);
P
,2) = (xi - u(2)) .* P
,1);
%
% Define higher-order polys.
%
for k = 3
m+1),
d(k-1) = sum( P
,k-1).^2 .* q.^2);
v(k-1) = sum( xi .* P
,k-1) .* P
,k-2) .* q.^2) / d(k-2);
u(k) = sum( xi .* P
,k-1).^2 .* q.^2) / d(k-1);
P
,k) = (xi - u(k)) .* P
,k-1) - v(k-1) .* P
,k-2);
end
d(m+1) = sum( P
,m+1).^2 .* q.^2);
return
________________________________________________________________
function bkm = bkm_comp(mmax,u,v)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for k = 0:mmax,
for m = k:mmax
% First, call bkmcheck to see if recursion formula applies
bv = bkmcheck(k,m);
if bv == -1,
bv1 = bkmcheck(k-1,m-1);
bv2 = bkmcheck(k,m-1);
bv3 = bkmcheck(k,m-2);
if bv1 == -1,
bkm1 = bkm(k,m);
else
bkm1 = bv1;
end
if bv2 == -1,
bkm2 = bkm(k+1,m);
else
bkm2 = bv2;
end
if bv3 == -1,
bkm3 = bkm(k+1,m-1);
else
bkm3 = bv3;
end
bkm(k+1,m+1) = bkm1 - u(m+1)*bkm2 - v(m)*bkm3;
else
bkm(k+1,m+1) = bv;
end
end
end
return
__________________________________________________________________
function bv = bkmcheck(k,m)
%
% Name: bkmcheck
%
% Usage: bv = bkmcheck(k,m)
%
% Description: Subroutine of bkm_comp -- checks
% value of k and m to see which
% formula applies
%
if k < 0 | k > m,
bv = 0;
elseif k == m,
bv = 1;
else
bv = -1; % Need to use full formula (or do table lookup)
end
return
The problem I'm having is that I run out of memeory when I use more than about 40 frf's ( using synthesised data consisting of 5 modes, 190 points per frf), also at 40 frf's it's taking about 2 minutes to calculate the polynomial coefficients ( 1GHz processor,380Mb ram). The function rpcoeffs is pretty much as it came from diamond
Has anyone an idea why this is happening? Does it react similarly in Matlab? any help would be gratefully received
If anyone would like to try it,the input arguments for rpcoeffs are as follows:
h = matrix of frf's arranged in columns
wi= vector of frequencies for frf's
m= order of numerator polynomial ( I used number of modes*2-1+4 for extra terms)
n=order of denominator polynomial (number of modes*2)
function [A,B] = rpcoeffs(h,wi,m,n)
% Usage: [A,B] = rpcoeffs(h,wi,m,n)
% List of variables:
% m = order of numerator polynomial
% n = order of denomenator polynomial
% L = number of frequency bins to curve fit
% h = FRF matrix values at selected frequencies
% wi = vector of frequencies to use (indexed 1 to L)
% Pnum, Pden = matrices of complex orthogonal Forsythe Polynomials (one-sided)
% row i = ith frequency
% column j = (j-1)th order polynomial
% qnum = weights for numerator Forsythe poly. (m+1 x 1)
% qden = weights for denomenator Forsythe poly. (n+1 x 1)
%
%
% Normalize frequency variables
% and make FRF curve 2-sided
j = sqrt(-1);
L1 = length(wi);
wmax = wi(L1);
wi = wi/wmax;
wi = [-wi(L1:-1:1);wi];
xi = j*wi;
h = [conj(h(L1:-1:1,
L = length(wi);
nh = size(h,2); % Total number of FRFs to Curve-fit
%
% Generate Orthogonal Forsythe Polynomials
%
% Numerator Polynomials
qnum = ones(L,1); % numerator poly. weights
[Pnum,unum,vnum] = forsythe(xi,qnum,m);
% Denomenator Polynomials
qden = zeros(L,1);
for i = 1:L,
qden(i) = max(svd(h(i,
end
[Pden,uden,vden] = forsythe(xi,qden,n);
%
% Form matrices for Least-Squares solution
%
P = Pnum;
SOLROW = zeros(L*nh,(m+1)*nh + n);
WCUM = zeros(L*nh,1);
for hc = 1:nh,
T = zeros(L,n);
for i = 1:n,
T
end
W = h
SOLROW((hc-1)*L + 1 : hc*L , (hc-1)*(m+1) + 1 : hc*(m+1)) = P;
SOLROW((hc-1)*L + 1 : hc*L , (m+1)*nh + 1 : (m+1)*nh + n) = -T;
WCUM((hc-1)*L + 1 : hc*L,1 ) = W;
end
%
% Solve for the Forsythe polynomial coefficients
%
SOL = SOLROW \ WCUM;
for hc = 1:nh,
C
end
D = [SOL((m+1)*nh + 1
%
% Convert Forsythe Poly. coefficients back to normal poly. coeffs.
%
bkm_num = bkm_comp(m,unum,vnum);
bkm_den = bkm_comp(n,uden,vden);
for hc = 1:nh,
% Numerator
for k = 0:m,
C1(k+1) = 0;
for mm = k:m,
C1(k+1) = C1(k+1) + C(mm+1,hc) * bkm_num(k+1,mm+1);
end
C1(k+1) = C1(k+1) / wmax^k;
end
A
end
% Denomenator
for k = 0:n,
D1(k+1) = 0;
for mm = k:n,
D1(k+1) = D1(k+1) + D(mm+1) * bkm_den(k+1,mm+1);
end
D1(k+1) = D1(k+1) / wmax^k;
end
B = real(D1(length(D1):-1:1))';
return
_____________________________________________
function [P,u,v] = forsythe(xi,q,m)
L = length(xi);
P = zeros(L,m+1);
u = zeros(m+1,1);
v = zeros(m+1,1);
%
% Define zero-th order poly.
%
P
%
% Define first order poly.
%
d(1) = sum( P
u(2) = sum( xi .* P
P
%
% Define higher-order polys.
%
for k = 3
d(k-1) = sum( P
v(k-1) = sum( xi .* P
u(k) = sum( xi .* P
P
end
d(m+1) = sum( P
return
________________________________________________________________
function bkm = bkm_comp(mmax,u,v)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for k = 0:mmax,
for m = k:mmax
% First, call bkmcheck to see if recursion formula applies
bv = bkmcheck(k,m);
if bv == -1,
bv1 = bkmcheck(k-1,m-1);
bv2 = bkmcheck(k,m-1);
bv3 = bkmcheck(k,m-2);
if bv1 == -1,
bkm1 = bkm(k,m);
else
bkm1 = bv1;
end
if bv2 == -1,
bkm2 = bkm(k+1,m);
else
bkm2 = bv2;
end
if bv3 == -1,
bkm3 = bkm(k+1,m-1);
else
bkm3 = bv3;
end
bkm(k+1,m+1) = bkm1 - u(m+1)*bkm2 - v(m)*bkm3;
else
bkm(k+1,m+1) = bv;
end
end
end
return
__________________________________________________________________
function bv = bkmcheck(k,m)
%
% Name: bkmcheck
%
% Usage: bv = bkmcheck(k,m)
%
% Description: Subroutine of bkm_comp -- checks
% value of k and m to see which
% formula applies
%
if k < 0 | k > m,
bv = 0;
elseif k == m,
bv = 1;
else
bv = -1; % Need to use full formula (or do table lookup)
end
return