C#复数Tanh对于大值失败
这是Microsoft为C#复数Tanh对于大值失败,c#,complex-numbers,C#,Complex Numbers,这是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 pub
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));
}
资料来源:
我不明白微软为什么用那种方式实现Tanh
方法
对于非常大的值,它将失败。例如:
,正常tanh(709+0i)-->1
,失败应为1tanh(711+0i)-->NaN
tanh
方法吗
对于
double
而言,Math.Tanh
方法适用于大值。复杂的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;
}
这也适用于较大的值,请参见
更新
此外,需要重新实现复数tan
方法,使其能够处理较大的值(虚部):
请参阅。使用Hans Passant的评论实现
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);
}
看
以及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);
}
请参阅。这种实现有缺点吗?>“我不明白微软为什么要用这种方式实现Tanh方法?”关于微软只雇用完美人才的传闻没有事实根据!在数学模型中忽略垃圾中的垃圾并不是那么明智。楠是你的朋友,告诉你之前的计算结果是胡说八道。如果你想忽略它,那么一个基本的解决方法是如果(Math.Abs(value.Real)>20)value=newcomplex(Math.Sign(value.Real),0)@汉帕桑。我无法控制房间里的垃圾。我是《不确定性传播库》(METAS UncLib)的作者,我们的一位客户正在非线性优化的目标函数中使用
tanh
方法。当然可以。抛出一个异常。@HansPassant我仍然认为对于像tanh
这样的数学函数来说,异常不是一个好主意。对于较大的值(实部),它应该只返回1或-1。我个人不喜欢数学函数中的if语句。
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);
}