C # Complex Tanh не работает для больших значений - PullRequest
0 голосов
/ 20 ноября 2018

Это реализация от Microsoft для Sinh Complex

public static Complex Sinh(Complex value) /* Hyperbolic sin */
{
    double a = value.m_real;
    double b = value.m_imaginary;
    return new Complex(Math.Sinh(a) * Math.Cos(b), Math.Cosh(a) * Math.Sin(b));
}

и реализация для Cosh

public static Complex Cos(Complex value) {
    double a = value.m_real;
    double b = value.m_imaginary;
    return new Complex(Math.Cos(a) * Math.Cosh(b), - (Math.Sin(a) * Math.Sinh(b)));
}

и, наконец, реализация для Tanh

public static Complex Tanh(Complex value) /* Hyperbolic tan */
{
    return (Sinh(value) / Cosh(value));
}

Источник: https://referencesource.microsoft.com/System.Numerics/a.html#e62f37ac1d0c67da

Я не понимаю, почему Microsoft внедрила метод Tanh таким образом?

Он потерпит неудачу при очень большомценности.Например:

  • tanh(709 + 0i) --> 1, нормально
  • tanh(711 + 0i) --> NaN, сбой должен быть 1

Любые идеи, как улучшить метод tanh, который?

Для double методы Math.Tanh работают для больших значений.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Используя комментарий Ганса Пассанта, можно реализовать еще один способ реализации метода tanh:

public static Complex Tanh(Complex value)
{
    if (Math.Abs(value.Real) > 20)
        return new Complex(Math.Sign(value.Real), 0);
    else
        return Complex.Tanh(value);
}

См. https://dotnetfiddle.net/QvUECX.

И метод tan:

public static Complex Tan(Complex value)
{
    if (Math.Abs(value.Imaginary) > 20)
        return new Complex(0, Math.Sign(value.Imaginary));
    else
        return Complex.Tan(value);
}

См. https://dotnetfiddle.net/Xzclcu.

0 голосов
/ 20 ноября 2018

Сложный метод tanh может быть реализован так:

public static Complex Tanh(Complex value)
{
    double a = value.Real;
    double b = value.Imaginary;
    double tanh_a = Math.Tanh(a);
    double tan_b = Math.Tan(b);
    Complex num = new Complex(tanh_a, tan_b);
    Complex den = new Complex(1, tanh_a * tan_b);
    return num / den;
}

Это также будет работать для больших значений, см. https://dotnetfiddle.net/xGWdQt.

Обновление

Также необходимо повторно реализовать сложный метод tan, чтобы он работал с большими значениями (мнимая часть):

public static Complex Tan(Complex value)
{
    double a = value.Real;
    double b = value.Imaginary;
    double tan_a = Math.Tan(a);
    double tanh_b = Math.Tanh(b);
    Complex num = new Complex(tan_a, tanh_b);
    Complex den = new Complex(1, -tan_a * tanh_b);
    return num / den;
}

См. https://dotnetfiddle.net/dh6CSG.

...