1226458Sdas/*- 2226458Sdas * Copyright (c) 2011 David Schultz 3226458Sdas * All rights reserved. 4226458Sdas * 5226458Sdas * Redistribution and use in source and binary forms, with or without 6226458Sdas * modification, are permitted provided that the following conditions 7226458Sdas * are met: 8226458Sdas * 1. Redistributions of source code must retain the above copyright 9226458Sdas * notice unmodified, this list of conditions, and the following 10226458Sdas * disclaimer. 11226458Sdas * 2. Redistributions in binary form must reproduce the above copyright 12226458Sdas * notice, this list of conditions and the following disclaimer in the 13226458Sdas * documentation and/or other materials provided with the distribution. 14226458Sdas * 15226458Sdas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16226458Sdas * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17226458Sdas * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18226458Sdas * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19226458Sdas * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20226458Sdas * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21226458Sdas * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22226458Sdas * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23226458Sdas * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24226458Sdas * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25226458Sdas */ 26226458Sdas 27226458Sdas/* 28226458Sdas * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details. 29226458Sdas */ 30226458Sdas 31226458Sdas#include <sys/cdefs.h> 32226458Sdas__FBSDID("$FreeBSD$"); 33226458Sdas 34226458Sdas#include <complex.h> 35226458Sdas#include <math.h> 36226458Sdas 37226458Sdas#include "math_private.h" 38226458Sdas 39226458Sdasfloat complex 40226458Sdasctanhf(float complex z) 41226458Sdas{ 42226458Sdas float x, y; 43226458Sdas float t, beta, s, rho, denom; 44226458Sdas uint32_t hx, ix; 45226458Sdas 46226458Sdas x = crealf(z); 47226458Sdas y = cimagf(z); 48226458Sdas 49226458Sdas GET_FLOAT_WORD(hx, x); 50226458Sdas ix = hx & 0x7fffffff; 51226458Sdas 52226458Sdas if (ix >= 0x7f800000) { 53226458Sdas if (ix & 0x7fffff) 54284810Stijl return (CMPLXF((x + 0) * (y + 0), 55284810Stijl y == 0 ? y : (x + 0) * (y + 0))); 56226458Sdas SET_FLOAT_WORD(x, hx - 0x40000000); 57284810Stijl return (CMPLXF(x, 58226458Sdas copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))); 59226458Sdas } 60226458Sdas 61226600Sdas if (!isfinite(y)) 62284810Stijl return (CMPLXF(y - y, y - y)); 63226600Sdas 64284810Stijl if (ix >= 0x41300000) { /* |x| >= 11 */ 65226458Sdas float exp_mx = expf(-fabsf(x)); 66284810Stijl return (CMPLXF(copysignf(1, x), 67226458Sdas 4 * sinf(y) * cosf(y) * exp_mx * exp_mx)); 68226458Sdas } 69226458Sdas 70226458Sdas t = tanf(y); 71226458Sdas beta = 1.0 + t * t; 72226458Sdas s = sinhf(x); 73226458Sdas rho = sqrtf(1 + s * s); 74226458Sdas denom = 1 + beta * s * s; 75284810Stijl return (CMPLXF((beta * rho * s) / denom, t / denom)); 76226458Sdas} 77226458Sdas 78226458Sdasfloat complex 79226458Sdasctanf(float complex z) 80226458Sdas{ 81226458Sdas 82284810Stijl z = ctanhf(CMPLXF(cimagf(z), crealf(z))); 83284810Stijl return (CMPLXF(cimagf(z), crealf(z))); 84226458Sdas} 85226458Sdas 86