11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*- 2a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Copyright (c) 2011 David Schultz 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice unmodified, this list of conditions, and the following 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * disclaimer. 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * documentation and/or other materials provided with the distribution. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 27a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 28a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details. 29a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 30a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h> 328cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes__FBSDID("$FreeBSD: head/lib/msun/src/s_ctanhf.c 284428 2015-06-15 20:47:26Z tijl $"); 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 34a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <complex.h> 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <math.h> 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 37a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include "math_private.h" 38a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 39a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesfloat complex 40a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesctanhf(float complex z) 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 42a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes float x, y; 43a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes float t, beta, s, rho, denom; 44a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes uint32_t hx, ix; 45a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 46a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes x = crealf(z); 47a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes y = cimagf(z); 48a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 49a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes GET_FLOAT_WORD(hx, x); 50a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ix = hx & 0x7fffffff; 51a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 52a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if (ix >= 0x7f800000) { 53a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if (ix & 0x7fffff) 548cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes return (CMPLXF((x + 0) * (y + 0), 558cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes y == 0 ? y : (x + 0) * (y + 0))); 56a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes SET_FLOAT_WORD(x, hx - 0x40000000); 578cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes return (CMPLXF(x, 58a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))); 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 60a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 61a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if (!isfinite(y)) 628cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes return (CMPLXF(y - y, y - y)); 63a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 648cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes if (ix >= 0x41300000) { /* |x| >= 11 */ 65a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes float exp_mx = expf(-fabsf(x)); 668cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes return (CMPLXF(copysignf(1, x), 67a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 4 * sinf(y) * cosf(y) * exp_mx * exp_mx)); 68a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes } 69a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 70a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes t = tanf(y); 71a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes beta = 1.0 + t * t; 72a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes s = sinhf(x); 73a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes rho = sqrtf(1 + s * s); 74a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes denom = 1 + beta * s * s; 758cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes return (CMPLXF((beta * rho * s) / denom, t / denom)); 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 77a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 78a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesfloat complex 79a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesctanf(float complex z) 80a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 81a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 828cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes z = ctanhf(CMPLXF(cimagf(z), crealf(z))); 838cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes return (CMPLXF(cimagf(z), crealf(z))); 84a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 85a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 86