function y = sinh(xin)
%SINH	Hyperbolic sine.
%	SINH(X) is the hyperbolic sine of the elements of X.

%	J.M. Hammond, 6-17-92
%	Copyright (c) 1984-93 by the MathWorks, Inc.

%       21 Oct 92 (jmh) -- fixed for matrix inputs

% Complex argument
if any(any(imag(xin) ~= 0))		% 21 Oct 92 (jmh)
    x = real(xin);
    y = imag(xin);
    y = sinh(x).*cos(y) + i*cosh(x).*sin(y);

% Real argument
else
    % Reference: W. J. Cody and W. Waite, "Software Manual
    % for the Elementary Functions", 1980, chapter 12.
   
    lnv  = 0.6931610107421875;     % v is close to 2, log(v) is exact
    xsmall = 1.49e-8;              % approximately sqrt(eps)
    xbar = 7.083964185322641e+02;  % log(1/realmin)
    vf   = 0.138302778796019e-04;  % v/2-1, where v is as above
    
    x = abs(xin);
    y = zeros(size(x));
    
    % sinh(x) = x to working precision
    k = (xsmall >= x) | (isnan(x));
    if any(any(k))			% 21 Oct 92 (jmh)
        y(k) = x(k);
    end
    
    % Use rational approximation
    k = (xsmall < x) & (x <= 1);
    if any(any(k))			% 21 Oct 92 (jmh)
        p = [-0.35181283430177118e6 -0.11563521196851768e5 ...
             -0.16375798202630751e3 -0.78966127417357099e0];
        q = [-0.21108770058106271e7  0.36162723109421836e5 ...
             -0.27773523119650702e3  1.0];
        xx = x(k).^2;
        y(k) = x(k) + x(k).*xx.*((((p(4)*xx + p(3)).*xx + p(2)).*xx + p(1))./...
                                (((xx + q(3)).*xx + q(2)).*xx + q(1)));
    end
    
    % Use exp
    k = (1 < x) & (x < xbar);
    if any(any(k))			% 21 Oct 92 (jmh)
        y(k) = (exp(x(k)) - exp(-x(k)))/2;
    end
    
    % Dodge overflow problem for answers close to realmax
    k = (xbar < x);
    if any(any(k))			% 21 Oct 92 (jmh)
        x(k) = x(k) - lnv;
        y(k) = exp(x(k)) + vf .* exp(x(k));
    end
 
    y = y.*sign(xin);
 
end
