📄 ranmull.pas
字号:
{ **********************************************************************
* Program RANMULL.PAS *
* Version 1.4d *
* (c) J. Debord, February 2003 *
**********************************************************************
This program simulates a multi-lognormal distribution. The mean vector
and variance-covariance matrix are stored in a data file with the
following structure:
Line 1 : Name of distribution.
Line 2 : Size of distribution (N), e.g. 2 for bi-lognormal
Line 3 to (N + 2) : Means and standard deviations.
Next lines : Correlation coefficients, in
lower triangular matrix form.
The file RANMULL.DAT is an example data file.
The results are stored in an output file (one random vector by line).
********************************************************************** }
program ranmull;
uses
fmath, randnum, matrices, stat;
const
NSIM = 400; { Number of simulations }
var
Name : String; { Name of distribution }
N : Integer; { Dimension of distribution }
M : TVector; { Mean vector of original lognormal distribution }
V : TMatrix; { Variance-covariance matrix of original lognormal dist. }
M0 : TVector; { Mean vector of auxiliary normal dist. }
V0 : TMatrix; { Variance-covariance matrix of auxiliary normal dist. }
L : TMatrix; { Cholesky factor of V0 }
Z : TVector; { Random vector from the auxiliary normal dist. }
X : TVector; { Random vector from the original lognormal dist. }
F : Text; { Output file }
I, J : Integer; { Loop variables }
procedure ReadParam(FileName : String; var Name : String; var N : Integer;
var M : TVector; var V : TMatrix);
var
F : Text; { Data file }
I, J : Integer; { Loop variables }
S : TVector; { Standard deviations }
R : Float; { Correlation coefficient }
begin
Assign(F, FileName);
Reset(F);
Readln(F, Name);
Readln(F, N);
DimVector(M, N);
DimVector(S, N);
DimMatrix(V, N, N);
{ Read means and standard deviations. Compute variances }
for I := 1 to N do
begin
Read(F, M[I], S[I]);
V[I,I] := Sqr(S[I]);
end;
{ Read correlation coefficients and compute covariances }
for I := 2 to N do
for J := 1 to Pred(I) do
begin
Read(F, R);
V[I,J] := R * S[I] * S[J];
V[J,I] := V[I,J];
end;
Close(F);
end;
begin
{ Read parameters of log-normal distribution LN(M, V) }
ReadParam('ranmull.dat', Name, N, M, V);
DimVector(X, N);
DimVector(Z, N);
DimVector(M0, N);
DimMatrix(V0, N, N);
DimMatrix(L, N, N);
{ Define auxiliary normal distribution N(M0, V0) }
for I := 1 to N do
begin
for J := 1 to N do
V0[I,J] := Ln(V[I,J] / (M[I] * M[J]) + 1.0);
M0[I] := Ln(M[I]) - 0.5 * V0[I,I];
end;
Assign(F, 'ranmull.out');
Rewrite(F);
{ Perform Cholesky decomposition of variance-covariance matrix }
if Cholesky(V0, 1, N, L) = MAT_NOT_PD then
begin
WriteLn('Variance-covariance matrix is not positive definite.');
Exit;
end;
for I := 1 to NSIM do
begin
{ Pick random vector from auxiliary normal distribution }
RanMult(M0, L, 1, N, Z);
{ Convert to lognormal }
for J := 1 to N do
X[J] := Exp(Z[J]);
{ Output result to file }
for J := 1 to N do
Write(F, X[J]:12:6);
Writeln(F);
end;
Close(F);
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -