1) Fortran-style exponential factoring (stable; no direct cosh/sinh)
This is a straight translation of your Fortran into MATLAB, it computes the same intermediate arrays.
Cn = stable_coeffs_from_exp(gammaV, f, h, d)
Cn =
-2.0187 -1.9803 -1.9805
-2.0158 -1.9831 -1.9833
-2.0000 -2.0000 -2.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
function [Cn, phiU_term, BBm] = stable_coeffs_from_exp(gamma, f, h, d)
exp1kmD = exp(-gamma.*d);
exp2kmD = exp(-2*gamma.*d);
exp2kmH = exp(-2*gamma.*h);
exp2kmHmD = exp(-2*gamma.*(h - d));
BBm = (nuR - gamma).*exp2kmHmD ./ exp2kmD;
BBm = BBm + (nuR + gamma).*(1 + 2*exp2kmHmD);
BBm = BBm ./ (nuR - gamma + (nuR + gamma).*exp2kmD);
BBm = BBm ./ (1 + exp2kmHmD);
Cn = 2*(BBm.*exp2kmD - 1);
phiU_term = 1 + exp2kmHmD./exp2kmD + 2*exp2kmHmD;
phiU_term = phiU_term ./ (1 + exp2kmHmD);
phiU_term = BBm.*(1 + exp2kmD) - phiU_term;
phiU_term = phiU_term .* exp1kmD;
2) Direct hyperbolic form, rewritten with exponentials (also stable)
If you want to stick to the analytical formula
Cnℓ=γcosh(γh)−f2sinh(γh)f2cosh(γd)−γsinh(γd)⋅1cosh(γ(h−d)),Cnℓ=f2cosh(γd)−γsinh(γd)γcosh(γh)−f2sinh(γh)⋅cosh(γ(h−d))1,
do not compute exp(gamma*...) directly (it can overflow).
Compute t=e−γxt=e−γx and form cosh/sinh from tt and 1/t1/t:
Cn = Cn_from_hyperbolic(gammaV, f, h, d)
Cn =
-2.0187 -1.9803 -1.9805
-2.0158 -1.9831 -1.9833
-2.0000 -2.0000 -2.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
function Cn = Cn_from_hyperbolic(gamma, f, h, d)
t_hd = exp(-gamma.*(h - d));
cosh_h = 0.5*(t_h.^-1 + t_h);
sinh_h = 0.5*(t_h.^-1 - t_h);
cosh_d = 0.5*(t_d.^-1 + t_d);
sinh_d = 0.5*(t_d.^-1 - t_d);
cosh_hd = 0.5*(t_hd.^-1 + t_hd);
Cn = (gamma.*cosh_h - f.^2.*sinh_h ) ./ ( f.^2.*cosh_d - gamma.*sinh_d ) ./ cosh_hd;
Why this is stable: all exponentials are of the form exp(-γ*positive) so they’re in (0,1](0,1]. You never form exp(+γx) directly, which is what overflows for large γ*h or γ*d.