#/*********************************************************** # hyperb.rb -- 双曲線関数 # -- 逆双曲線関数 #***********************************************************/ EPS5 = 0.0001 def my_sinh(x) # 自家製 $\sinh x$ if (x.abs > EPS5) t = Math::exp(x) return (t - 1 / t.to_f) / 2.0 end return x * (1 + x * x / 6.0) end def my_cosh(x) # 自家製 $\cosh x$ t = Math::exp(x) return (t + 1 / t.to_f) / 2.0 end def my_tanh(x) # 自家製 $\tanh x$ if (x > EPS5); return 2 / (1 + Math::exp(-2 * x)) - 1; end if (x < -EPS5); return 1 - 2 / (Math::exp(2 * x) + 1); end return x * (1 - x * x / 3.0) end def arcsinh(x) # $\sinh^-1end x$ if (x > EPS5); return Math::log(Math::sqrt(x * x + 1) + x); end if (x < -EPS5); return -Math::log(Math::sqrt(x * x + 1) - x); end return x * (1 - x * x / 6.0) end def arccosh(x) # $\cosh^-1end x$, $x \ge 1$ return Math::log(x + Math::sqrt(x * x - 1)) end def arctanh(x) # $\tanh^-1end x$ if (x.abs > EPS5) return 0.5 * Math::log((1 + x) / (1 - x.to_f)) end return x * (1 + x * x / 3.0) end #************ 以下はテスト用 ************* printf("双曲線関数とその逆の整合性\n") for i in -10..10 printf("%4d % .3e % .3e % .3e\n", i, arcsinh(my_sinh(i)) - i,\ arccosh(my_cosh(i)) - i.abs,\ arctanh(my_tanh(i)) - i) end for i in -10..10 x = 0.0002 * i printf("%7.4f % .3e % .3e % .3e\n",\ x, arcsinh(my_sinh(x)) - x,\ arccosh(my_cosh(x)) - x.abs,\ arctanh(my_tanh(x)) - x) end printf("tanh の桁あふれテスト (ライブラリ関数と比較)\n") -5000.step(5000, 500) do |i| printf("%5d % g % g\n", i, my_tanh(i), Math::tanh(i)) end exit 0