からっぽのしょこ

読んだら書く!書いたら読む!同じ事は二度調べ(たく)ない

【R】arccot関数の定義の可視化

はじめに

 円関数(三角関数)の定義や性質、公式などを可視化して理解しようシリーズです。

 この記事では、arccot関数のグラフを作成します。

【前の内容】

www.anarchive-beta.com

【他の内容】

www.anarchive-beta.com

【この記事の内容】

arccot関数の定義の可視化

 arccot関数(逆cot関数・逆余接関数・逆コタンジェント関数・inverse cotangent function)の定義をグラフで確認します。arccot関数は、逆円関数(inverse circular functions)・逆三角関数(inverse trigonometric functions)の1つです。
 cot関数の定義や作図については「【R】cot関数の可視化 - からっぽのしょこ」を参照してください。

 利用するパッケージを読み込みます。

# 利用パッケージ
library(tidyverse)

 この記事では、基本的に パッケージ名::関数名() の記法を使うので、パッケージの読み込みは不要です。ただし、作図コードについてはパッケージ名を省略するので、ggplot2 を読み込む必要があります。
 また、ネイティブパイプ演算子 |> を使います。magrittr パッケージのパイプ演算子 %>% に置き換えられますが、その場合は magrittr を読み込む必要があります。

定義式の確認

 まずは、arccot関数の定義式を確認します。
 tan関数については「【R】tan関数の可視化 - からっぽのしょこ」、arctan関数については「【R】arctan関数の定義の可視化 - からっぽのしょこ」を参照してください。

arccot関数とcot関数の関係

 cot関数は、tan関数の逆数で定義されます。

 \displaystyle
\cot x
    = \frac{1}{\tan x}
    = \frac{\cos x}{\sin x}

 arccot関数は、cot関数の逆関数で定義されます。

 \displaystyle
\mathrm{arccot}\ x
    = \cot^{-1} x

 定義域は  -\infty \leq x \leq \infty、終域は  0 \lt \mathrm{arccot}\ x \lt \pi です。関数の出力はラジアン(弧度法の角度)、 \pi は円周率です。

arccot関数とarctan関数の関係

 arccot関数とarctan関数の関係を導出します。

・途中式(クリックで展開)

 tan関数とcot関数は、逆数の関係でした。

 \displaystyle
\begin{aligned}
\cot y
    = \frac{1}{\tan y}
\Leftrightarrow
\frac{1}{\cot y}
    = \tan y
\end{aligned}

 tan関数とarctan関数、cot関数とarccot関数は、それぞれ逆関数の関係でした。

 \displaystyle
\begin{aligned}
x  &= \tan(\arctan x)
   && (-\infty \leq x \leq \infty)
\\
x  &= \cot(\mathrm{arccot}\ x)
   && (-\infty \leq x \leq \infty)
\end{aligned}

 また、それぞれの関数の定義域と終域より、次の式も成り立ちます。

 \displaystyle
\begin{aligned}
y  &= \arctan(\tan y)
   && (-\frac{\pi}{2} \lt y \lt \frac{\pi}{2})
\\
y  &= \mathrm{arccot}(\cot y)
   &&
      (0 \lt y \lt \pi)
\end{aligned}

 これらの式を用いて、arccot関数とarctan関数の関係を考えます。

逆数によるarctan関数

・途中式(クリックで展開)

 arccot関数を  y とおきます。 y 0, \pi を含めず  0 から  \pi の値をとります。

 \displaystyle
y   = \mathrm{arccot}\ x
\tag{1}

 両辺をcot関数で計算します。

 \displaystyle
\begin{aligned}
\cot y
   &= \cot(\mathrm{arccot}\ x)
\\
   &= x
\end{aligned}

 逆数の関係より、両辺の逆数をとって、左辺を置き換えます。

 \displaystyle
\begin{alignat}{2}
&&
\cot y
   &= x
\\
\Leftrightarrow &&
\frac{1}{\cot y}
   &= \frac{1}{x}
\\
\Leftrightarrow &&
\tan y
   &= \frac{1}{x}
\end{alignat}

 両辺をarctan関数で計算します。

 \displaystyle
\arctan(\tan y)
    = \arctan \frac{1}{x}

 左辺に関して、変数の範囲  0 \lt y \lt \pi に対して終域が  -\frac{\pi}{2} \lt \arctan x \lt \frac{\pi}{2} なので、場合分けして

 \displaystyle
\arctan(\tan y)
    = \begin{cases}
        y
          & (0 \lt y \lt \frac{\pi}{2}) \\
        y - \pi
          & (\frac{\pi}{2} \lt y \lt \pi)
      \end{cases}

となります。 y = \frac{\pi}{2} のとき、 \cos \frac{\pi}{2} = 0 になり(0除算になるため)  \tan \frac{\pi}{2} を定義できないので、範囲に含まれません。
 下の式に関して、 y - \pi の範囲は

 \displaystyle
\begin{alignat}{2}
&&
\frac{\pi}{2} &\lt y \lt \pi
\\
\Leftrightarrow &&
    \frac{\pi}{2} - \pi &\lt y - \pi \lt \pi - \pi
\\
\Leftrightarrow &&
    -\frac{\pi}{2} &\lt y - \pi \lt 0
\end{alignat}

であり、またarccot関数の定義域と終域の関係から

 \displaystyle
\begin{aligned}
0 \lt y \lt \frac{\pi}{2}
   &\Rightarrow
      x \gt 0
\\
\frac{\pi}{2} \lt y \lt \pi
   &\Rightarrow
      x \lt 0
\end{aligned}

が対応します。
 よって、式(1)などでそれぞれ置き換えると、次の関係が成り立ちます。

 \displaystyle
\arctan \frac{1}{x}
    = \begin{cases}
        \mathrm{arccot}\ x
          & (x \gt 0) \\
        \mathrm{arccot}\ x - \pi
          & (x \lt 0)
      \end{cases}

  \mathrm{arccot}\ x について式を整理します。

 \displaystyle
\mathrm{arccot}\ x
    = \begin{cases}
        \arctan \frac{1}{x}
          & (x \gt 0) \\
        \arctan \frac{1}{x} + \pi
          & (x \lt 0)
      \end{cases}
\tag{2}

 arccot関数とarctan関数の関係式が得られました。

 また、式(2)より、次の関係も成り立ちます。

 \displaystyle
\begin{aligned}
\mathrm{arccot}(\cot z)
   &= \begin{cases}
        \arctan(\frac{1}{\cot z})
          & (\cot z \gt 0) \\
        \arctan(\frac{1}{\cot z}) + \pi
          & (\cot z \lt 0)
      \end{cases}
\\
   &= \begin{cases}
        \arctan(\tan z)
          & (\cot z \gt 0) \\
        \arctan(\tan z) + \pi
          & (\cot z \lt 0)
      \end{cases}
\end{aligned}


 以上で、arctan関数を用いてarccot関数の計算を行えるのが分かりました。

逆数によるarccot関数

・途中式(クリックで展開)

 同様に、arctan関数を  y とおきます。 y \pm \frac{\pi}{2} を含めず  -\frac{\pi}{2} から  \frac{\pi}{2} の値をとります。

 \displaystyle
y   = \arctan x
\tag{3}

 両辺をtan関数で計算します。

 \displaystyle
\begin{aligned}
\tan y
   &= \tan(\arctan x)
\\
   &= x
\end{aligned}

 逆数の関係より、両辺の逆数をとって、左辺を置き換えます。

 \displaystyle
\begin{alignat}{2}
&&
\tan y
   &= x
\\
\Leftrightarrow &&
\frac{1}{\tan y}
   &= \frac{1}{x}
\\
\Leftrightarrow &&
\cot y
   &= \frac{1}{x}
\end{alignat}

 両辺をarccot関数で計算します。

 \displaystyle
\mathrm{arccot}(\cot y)
    = \mathrm{arccot}\ \frac{1}{x}

 左辺に関して、変数の範囲  -\frac{\pi}{2} \lt y \lt \frac{\pi}{2} に対して終域が  0 \lt \arctan x \lt \pi なので、場合分けして

 \displaystyle
\mathrm{arccot}(\cot y)
    = \begin{cases}
        y + \pi
          & (-\frac{\pi}{2} \lt y \lt 0) \\
        y
          & (0 \lt y \lt \frac{\pi}{2})
      \end{cases}

となります。 y = 0 のとき、 \sin 0 = 0 になり(0除算になるため)  \cot 0 を定義できないので、範囲に含まれません。
 上の式に関して、 y + \pi の範囲は

 \displaystyle
\begin{alignat}{2}
&&
-\frac{\pi}{2} &\lt y \lt 0
\\
\Leftrightarrow &&
    -\frac{\pi}{2} + \pi &\lt y + \pi \lt 0 + \pi
\\
\Leftrightarrow &&
    \frac{\pi}{2} &\lt y + \pi \lt \pi
\end{alignat}

であり、またarctan関数の定義域と終域の関係から

 \displaystyle
\begin{aligned}
-\frac{\pi}{2} \lt y \lt 0
   &\Rightarrow
      x \lt 0
\\
0 \lt y \lt \frac{\pi}{2}
   &\Rightarrow
      x \gt 0
\end{aligned}

が対応します。
 よって、式(3)などでそれぞれ置き換えると、次の関係が成り立ちます。

 \displaystyle
\mathrm{arccot}\ \frac{1}{x}
    = \begin{cases}
        \arctan x + \pi
          & (x \lt 0) \\
        \arctan x
          & (x \gt 0)
      \end{cases}

  \arctan x について式を整理します。

 \displaystyle
\arctan x
    = \begin{cases}
        \mathrm{arccot}\ \frac{1}{x} - \pi
          & (x \lt 0) \\
        \mathrm{arccot}\ \frac{1}{x}
          & (x \gt 0)
      \end{cases}
\tag{4}

 arctan関数とarccot関数の関係式が得られました。

 また、式(4)より、次の関係も成り立ちます。

 \displaystyle
\begin{aligned}
\arctan(\tan z)
   &= \begin{cases}
        \mathrm{arccot}(\frac{1}{\tan z}) - \pi
          & (\tan z \lt 0) \\
        \mathrm{arccot}(\frac{1}{\tan z})
          & (\tan z \gt 0)
      \end{cases}
\\
   &= \begin{cases}
        \mathrm{arccot}(\cot z) - \pi
          & (\tan z \lt 0) \\
        \mathrm{arccot}(\cot z)
          & (\tan z \gt 0)
      \end{cases}
\end{aligned}


 (この記事ではこちらの関係は使いませんが、)arccot関数を用いてarctan関数の計算を行えるのが分かりました。

曲線の形状

 続いて、arccot関数のグラフを作成します。

曲線の作成

・作図コード(クリックで展開)

 逆円関数の曲線の描画用のデータフレームを作成します。

# 閾値を指定
threshold <- 4

# 逆関数の曲線の座標を作成
curve_inv_df <- tibble::tibble(
  x        = seq(from = -threshold, to = threshold, length.out = 1001), 
  arccot_x = dplyr::case_when(
    x  > 0 ~ atan(1/x), 
    x == 0 ~ NA_real_, 
    x  < 0 ~ atan(1/x) + pi 
  ), 
  arctan_x = atan(x)
)
curve_inv_df
# A tibble: 1,001 × 3
       x arccot_x arctan_x
   <dbl>    <dbl>    <dbl>
 1 -4        2.90    -1.33
 2 -3.99     2.90    -1.33
 3 -3.98     2.90    -1.32
 4 -3.98     2.90    -1.32
 5 -3.97     2.89    -1.32
 6 -3.96     2.89    -1.32
 7 -3.95     2.89    -1.32
 8 -3.94     2.89    -1.32
 9 -3.94     2.89    -1.32
10 -3.93     2.89    -1.32
# ℹ 991 more rows

 cot曲線用の閾値 threshold を指定しておき、閾値の範囲の変数  x と関数  \mathrm{arccot}\ x の値をデータフレームに格納します。比較用に、 \arctan x の値も格納しておきます。arctan関数は atan() で、arccot関数は atan() を使って計算できます。

 円関数の曲線の描画用のデータフレームを作成します。

# 元の関数の曲線の座標を作成
curve_df <- tibble::tibble(
  t     = seq(from = -pi, to = pi, length.out = 1001), # ラジアン
  cot_t = 1/tan(t), 
  inv_flag = (t > 0 & t < pi) # 逆関数の終域
) |> 
  dplyr::mutate(
    cot_t = dplyr::if_else(
      (cot_t >= -threshold & cot_t <= threshold), true = cot_t, false = NA_real_
    )
  ) # 閾値外を欠損値に置換
curve_df
# A tibble: 1,001 × 3
       t cot_t inv_flag
   <dbl> <dbl> <lgl>   
 1 -3.14    NA FALSE   
 2 -3.14    NA FALSE   
 3 -3.13    NA FALSE   
 4 -3.12    NA FALSE   
 5 -3.12    NA FALSE   
 6 -3.11    NA FALSE   
 7 -3.10    NA FALSE   
 8 -3.10    NA FALSE   
 9 -3.09    NA FALSE   
10 -3.09    NA FALSE   
# ℹ 991 more rows

 変数  -\pi \leq \theta \leq \pi と関数  \cot \theta の値をデータフレームに格納します。tan関数は tan() で計算できます。
 ただし、 \theta = n \pi (  n は整数)のとき発散するので、閾値 threshold を指定しておき、閾値外の値を(数値型の)欠損値 NA に置き換えます。
 また、 \theta の値が  \mathrm{arccot}\ x のとり得る範囲内かのフラグを inv_flag 列とします。

 arccot関数とcot関数のグラフを作成します。

・作図コード(クリックで展開)

# ラベル用の文字列を作成
def_label <- paste0(
  "list(", 
  "arccot~x == cot^{-1}*x, ", 
  "0 < arccot~x < pi", 
  ")"
)

# 関数曲線を作図
ggplot() + 
  geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), 
                             xend = c(Inf, 0), yend = c(0, Inf)), 
               arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線
  geom_line(data = curve_inv_df, 
            mapping = aes(x = x, y = arccot_x, color = "arccot"), 
            linewidth = 1) + # 逆関数
  geom_line(data = curve_df,
            mapping = aes(x = t, y = cot_t, linetype = inv_flag, color = "cot"), 
            linewidth = 1, na.rm = TRUE) + # 元の関数
  geom_abline(slope = 1, intercept = 0, 
              linetype = "dotdash") + # 恒等関数
  scale_color_manual(breaks = c("arccot", "cot"), 
                     values = c("black", "#F8766D"), 
                     labels = c(expression(arccot~x), expression(cot~x)), 
                     name = "function") + # 凡例表示用
  scale_linetype_manual(breaks = c(TRUE, FALSE), 
                        values = c("solid", "dotted"), guide ="none") + # 終域用
  coord_fixed(ratio = 1) + # アスペクト比
  labs(title = "inverse cotangent function", 
       subtitle = parse(text = def_label), 
       x = expression(x), 
       y = expression(f(x)))

cot関数とarccot関数の関係

 arccot関数を実線、cot関数を朱色の実線と点線で、また恒等関数  f(x) = x を鎖線で示します。 \tau = \mathrm{arccot}\ x がとり得る範囲(  0 \lt \tau \lt \pi )の  \cot \tau を実線で示しています。
 恒等関数(傾きが1で切片が0の直線)に対して、arccot曲線とcot曲線は線対称な曲線です。

 arccot関数の軸を入れ替えたグラフを作成します。

・作図コード(クリックで展開)

# 範囲πにおける目盛数を指定
tick_num <- 2

# ラジアン軸目盛用の値を作成
rad_break_vec <- seq(from = -pi, to = pi, by = pi/tick_num)
rad_label_vec <- paste(round(rad_break_vec/pi, digits = 2), "* pi")

# 逆関数と元の関数の関係を作図
ggplot() + 
  geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), 
                             xend = c(Inf, 0), yend = c(0, Inf)), 
               arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線
  geom_vline(xintercept = c(0, pi), 
             linetype = "twodash") + # 漸近線
  geom_line(data = curve_inv_df, 
            mapping = aes(x = arccot_x, y = x, color = "arccot"), 
            linewidth = 1) + # 逆関数
  geom_line(data = curve_df,
            mapping = aes(x = t, y = cot_t, color = "cot"), 
            linewidth = 1, linetype = "dashed", na.rm = TRUE) + # 元の関数
  scale_color_manual(breaks = c("arccot", "cot"), 
                     values = c("black", "#F8766D"), 
                     labels = c(expression(arccot~x), expression(cot~theta)), 
                     name = "function") + # 凡例表示用
  scale_x_continuous(breaks = rad_break_vec, 
                     labels = parse(text = rad_label_vec)) + # ラジアン軸目盛
  coord_fixed(ratio = 1) + # アスペクト比
  labs(title = "inverse cotangent function", 
       subtitle = parse(text = def_label), 
       x = expression(list(theta, tau == arccot~x)), 
       y = expression(x == cot~theta == cot~tau))

cot関数とarccot関数の関係

 (1つは縦軸線と重なって見えませんが)漸近線を鎖線で示します。
 arccot曲線の横軸と縦軸を入れ替える(恒等関数の直線に対して反転する)と、cot曲線に一致します。

 arccot関数とarctan関数のグラフを作成します。

・作図コード(クリックで展開)

# ラベル用の文字列を作成
def_label <- "arccot~x == frac(pi, 2) - arctan~x"

# 関数曲線を作図
ggplot() + 
  geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), 
                             xend = c(Inf, 0), yend = c(0, Inf)), 
               arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線
  geom_hline(yintercept = 0.5*pi, 
             linetype = "dashed") + # 余角用の水平線
  geom_line(data = curve_inv_df, 
            mapping = aes(x = x, y = arccot_x, linetype = "arccot"), 
            linewidth = 1) + # arccot関数
  geom_line(data = curve_inv_df,
            mapping = aes(x = x, y = arctan_x, linetype = "arctan"), 
            linewidth = 1) + # arctan関数
  scale_linetype_manual(breaks = c("arccot", "arctan"), 
                        values = c("solid", "dotted"), 
                        labels = c(expression(arccot~x), expression(arctan~x)), 
                        name = "function") + # 凡例表示用
  scale_y_continuous(breaks = rad_break_vec, 
                     labels = parse(text = rad_label_vec)) + # ラジアン軸目盛
  guides(linetype = guide_legend(override.aes = list(linewidth = 0.5))) + # 凡例の体裁
  coord_fixed(ratio = 1, 
              ylim = c(-pi, pi)) + # アスペクト比
  labs(title = "inverse cotangent function", 
       subtitle = parse(text = def_label), 
       x = expression(x), 
       y = expression(theta == f(x)))

arccot関数とarctan関数の関係

 余角の関係より、 \mathrm{arccot}\ x = \frac{\pi}{2} - \arctan x が成り立ちます。

単位円と関数の関係

 次は、単位円における偏角(単位円上の点)と円関数(cot・tan・sin・cos・exsec・excsc)と逆円関数(arccot)の関係を確認します。
 各関数についてはそれぞれの記事を参照してください。

グラフの作成

 変数を固定して、単位円におけるcot関数の線分とarccot関数の円弧のグラフを作成します。

・作図コード(クリックで展開)

 円関数の変数を指定して、逆円関数を計算します。

# 点用のラジアンを指定
theta <- 11/6 * pi

# 終域内のラジアンに変換
cot_theta <- 1/tan(theta)
if(cot_theta > 0) {
  tau <- atan(1/cot_theta)
} else if(cot_theta == 0) {
  tau <- NA
} else if(cot_theta < 0) {
  tau <- atan(1/cot_theta) + pi
}
tau / pi
[1] 0.8333333

 cot関数の変数  \theta を指定して、cot関数  z = \cot \theta を変数としてarctan関数  \tau = \mathrm{arccot}\ z を計算します。
  \theta = 0 の場合、 \tan 0 = 0 なので 1/tan(theta)Inf になります。 \theta = 0 以外(  \theta = 2 \pi など)の場合はプログラム上の誤差のため tan(theta)0 になりません。ggplot2による作図では、Inf は描画領域の端を表すため意図しないグラフになることがあります。

 円周上の点の描画用のデータフレームを作成します。

# 円周上の点の座標を作成
point_df <- tibble::tibble(
  angle = c("theta", "tau"), # 角度カテゴリ
  t = c(theta, tau), 
  x = cos(t), 
  y = sin(t), 
  point_type = c("main", "sub") # 入出力用
)
point_df
# A tibble: 2 × 5
  angle     t      x      y point_type
  <chr> <dbl>  <dbl>  <dbl> <chr>     
1 theta  5.76  0.866 -0.500 main      
2 tau    2.62 -0.866  0.500 sub    

 円関数の入力  \theta と逆円関数の出力  \tau それぞれについて、単位円上の点の座標  (x, y) = (\cos t, \sin t) を計算します。

 単位円の描画用のデータフレームを作成します。

# 単位円の座標を作成
circle_df <- tibble::tibble(
  t = seq(from = 0, to = 2*pi, length.out = 361), # 1周期分のラジアン
  r = 1, # 半径
  x = r * cos(t), 
  y = r * sin(t)
)

# 範囲πにおける目盛数を指定
tick_num <- 6

# 角度目盛の座標を作成
rad_tick_df <- tibble::tibble(
  i = seq(from = 0, to = 2*tick_num-0.5, by = 0.5), # 目盛番号
  t = i/tick_num * pi, # ラジアン
  r = 1, # 半径
  x = r * cos(t), 
  y = r * sin(t), 
  major_flag = i%%1 == 0, # 主・補助フラグ
  grid       = dplyr::if_else(major_flag, true = "major", false = "minor") # 目盛カテゴリ
)

 円周と角度軸目盛の座標を作成します。

 偏角の描画用のデータフレームを作成します。

# 半径線の終点の座標を作成
radius_df <- dplyr::bind_rows(
  # 始線
  tibble::tibble(
    x = 1, 
    y = 0, 
    w         = "normal", # 補助線用
    line_type = "main" # 入出力用
  ), 
  # 動径
  point_df |> 
    dplyr::select(x, y, line_type = point_type) |> 
    dplyr::mutate(
      w = dplyr::case_match(
        line_type, 
        "main" ~ "normal", 
        "sub"  ~ "thin"
      ), # 補助線用
    ), 
  # 補助線
  tibble::tibble(
    x = 0, 
    y = 1, 
    w         = "thin", # 補助線用
    line_type = "main" # 入出力用
  )
)

# 角マークの座標を作成
d_in  <- 0.2
d_spi <- 0.005
d_out <- 0.3
angle_mark_df <- dplyr::bind_rows(
  # 元の関数の入力
  tibble::tibble(
    angle = "theta", # 角度カテゴリ
    u = seq(from = 0, to = theta, length.out = 600), 
    x = (d_in + d_spi*u) * cos(u), 
    y = (d_in + d_spi*u) * sin(u)
  ), 
  # 逆関数の出力
  tibble::tibble(
    angle = "tau", # 角度カテゴリ
    u = seq(from = 0, to = tau, length.out = 600), 
    x = d_out * cos(u), 
    y = d_out * sin(u)
  )
)

# 角ラベルの座標を作成
d_in  <- 0.1
d_out <- 0.4
angle_label_df <- tibble::tibble(
  u = 0.5 * c(theta, tau), 
  x = c(d_in, d_out) * cos(u), 
  y = c(d_in, d_out) * sin(u), 
  angle_label = c("theta", "tau")
)

  \theta, \tau それぞれについて、始線と動径、角マークと角ラベルの座標を作成します。また、cot関数を示す線分用に、半径と同じ長さの補助線の座標も格納します。

 逆円関数を示す円弧の描画用のデータフレームを作成します。

# 関数円弧の座標を作成
radian_df <- tibble::tibble(
  u = seq(from = 0, to = tau, length.out = 600), 
  r = 1, # 半径
  x = r * cos(u), 
  y = r * sin(u)
)
radian_df
# A tibble: 600 × 4
         u     r     x       y
     <dbl> <dbl> <dbl>   <dbl>
 1 0           1 1     0      
 2 0.00437     1 1.00  0.00437
 3 0.00874     1 1.00  0.00874
 4 0.0131      1 1.00  0.0131 
 5 0.0175      1 1.00  0.0175 
 6 0.0219      1 1.00  0.0219 
 7 0.0262      1 1.00  0.0262 
 8 0.0306      1 1.00  0.0306 
 9 0.0350      1 0.999 0.0350 
10 0.0393      1 0.999 0.0393 
# ℹ 590 more rows

 ラジアン  0 \leq u \leq \tau を作成して、単位円の円周上の(半径が  r = 1 の)円弧の座標  (x, y) = (\cos u, \sin u) を計算します。

 円関数を示す線分の描画用のデータフレームを作成します。

# 関数の描画順を指定
fnc_level_vec <- c("arccot", "cot", "tan", "sin", "cos", "exsec", "excsc")

# 関数線分の座標を作成
fnc_seg_df <- tibble::tibble(
  fnc = c(
    "cot", "tan", 
    "sin", "sin", 
    "cos", "cos", 
    "exsec", "excsc"
  ) |> 
    factor(levels = fnc_level_vec), # 関数カテゴリ
  x_from = c(
    0, 1, 
    0, cos(theta), 
    0, 0, 
    cos(theta), cos(theta)
  ), 
  y_from = c(
    1, 0, 
    0, 0, 
    0, sin(theta), 
    sin(theta), sin(theta)
  ), 
  x_to = c(
    1/tan(theta), 1, 
    0, cos(theta), 
    cos(theta), cos(theta), 
    1, 1/tan(theta)
  ), 
  y_to = c(
    1, tan(theta), 
    sin(theta), sin(theta), 
    0, sin(theta), 
    tan(theta), 1
  ), 
  w = c(
    "normal", "normal", 
    "normal", "normal", 
    "normal", "normal", 
    "bold", "thin"
  ) # 重なり対策用
)
fnc_seg_df
# A tibble: 8 × 6
  fnc   x_from y_from   x_to   y_to w     
  <fct>  <dbl>  <dbl>  <dbl>  <dbl> <chr> 
1 cot    0      1     -1.73   1     normal
2 tan    1      0      1     -0.577 normal
3 sin    0      0      0     -0.500 normal
4 sin    0.866  0      0.866 -0.500 normal
5 cos    0      0      0.866  0     normal
6 cos    0     -0.500  0.866 -0.500 normal
7 exsec  0.866 -0.500  1     -0.577 bold  
8 excsc  0.866 -0.500 -1.73   1     thin  

 各線分に対応する関数カテゴリを fnc 列として線の描き分けなどに使います。線分の描画順(重なり順や色付け順)を因子レベルで設定します。
 各線分の始点の座標を x_from, y_from 列、終点の座標を x_to, y_to 列として、完成図を見ながら頑張って格納します。

 関数ラベルの描画用のデータフレームを作成します。

# 関数ラベルの座標を作成
fnc_label_df <- tibble::tibble(
  fnc = c("arccot", "cot", "tan", "sin", "cos", "exsec", "excsc") |> 
    factor(levels = fnc_level_vec), # 関数カテゴリ
  x = c(
    cos(0.5 * tau), 
    0.5 / tan(theta), 
    1, 
    0, 
    0.5 * cos(theta), 
    0.5 * (cos(theta) + 1), 
    0.5 * (cos(theta) + 1/tan(theta))
  ), 
  y = c(
    sin(0.5 * tau), 
    1, 
    0.5 * tan(theta), 
    0.5 * sin(theta), 
    0, 
    0.5 * (sin(theta) + tan(theta)), 
    0.5 * (sin(theta) + 1)
  ), 
  fnc_label = c("arccot(cot~theta)", "cot~theta", "tan~theta", "sin~theta", "cos~theta", "exsec~theta", "excsc~theta"), 
  a = c( 0,    0,   90,  90,  0,   0,    0), 
  h = c(-0.1,  0.5, 0.5, 0.5, 0.5, 1.1, -0.1), 
  v = c(-0.5, -0.5, 1,  -0.5, 1,   0.5,  0.5)
)
fnc_label_df
# A tibble: 7 × 7
  fnc         x      y fnc_label             a     h     v
  <fct>   <dbl>  <dbl> <chr>             <dbl> <dbl> <dbl>
1 arccot  0.259  0.966 arccot(cot~theta)     0  -0.1  -0.5
2 cot    -0.866  1     cot~theta             0   0.5  -0.5
3 tan     1     -0.289 tan~theta            90   0.5   1  
4 sin     0     -0.250 sin~theta            90   0.5  -0.5
5 cos     0.433  0     cos~theta             0   0.5   1  
6 exsec   0.933 -0.539 exsec~theta           0   1.1   0.5
7 excsc  -0.433  0.250 excsc~theta           0  -0.1   0.5

 関数ごとに1つの線分の中点に関数名を表示することにします。
 ラベルの表示角度を a 列、表示角度に応じた左右の表示位置を h 列、上下の表示位置を v 列として指定します。

 単位円におけるarccot関数のグラフを作成します。

# ラベル用の文字列を作成
var_label <- paste0(
  "list(", 
  "r == 1, ", 
  "theta == ", round(theta/pi, digits = 2), " * pi, ", 
  "tau == ", round(tau/pi, digits = 2), " * pi", 
  ")"
)
fnc_label_vec <- paste(
  c("arctan(tan~theta)", "cot~theta", "tan~theta", "sin~theta", "cos~theta", "exsec~theta", "excsc~theta"), 
  c(tau, 1/tan(theta), tan(theta), sin(theta), cos(theta), 1/cos(theta)-1, 1/sin(theta)-1) |> 
    round(digits = 2), 
  sep = " == "
)

# グラフサイズの下限値・上限値を指定
axis_lower <- 1.5
axis_upper <- 3

# グラフサイズを設定
axis_x_min <- min(-axis_lower, 1/tan(theta)) |> max(-axis_upper)
axis_x_max <- max(axis_lower, 1/tan(theta)) |> min(axis_upper)
axis_y_min <- min(-axis_lower, tan(theta)) |> max(-axis_upper)
axis_y_max <- max(axis_lower, tan(theta)) |> min(axis_upper)

# 単位円における関数線分を作図
ggplot() + 
  geom_segment(data = rad_tick_df, 
               mapping = aes(x = 0, y = 0, xend = x, yend = y, linewidth = grid), 
               color = "white", show.legend = FALSE) + # θ軸目盛線
  geom_segment(mapping = aes(x = c(-Inf, 0), y = c(0, -Inf), 
                             xend = c(Inf, 0), yend = c(0, Inf)),
               arrow = arrow(length = unit(10, units = "pt"), ends = "last")) + # x・y軸線
  geom_path(data = circle_df, 
            mapping = aes(x = x, y = y), 
            linewidth = 1) + # 円周
  geom_segment(data = radius_df, 
               mapping = aes(x = 0, y = 0, xend = x, yend = y, 
                             linewidth = w, linetype = line_type), 
               show.legend = FALSE) + # 半径線
  geom_path(data = angle_mark_df, 
            mapping = aes(x = x, y = y, group = angle)) + # 角マーク
  geom_text(data = angle_label_df, 
            mapping = aes(x = x, y = y, label = angle_label), 
            parse = TRUE, size = 5) + # 角ラベル
  geom_text(mapping = aes(x = 0.5*cos(theta+0.1), y = 0.5*sin(theta+0.1)), 
            label = "r", parse = TRUE, 
            size = 5) + # 半径ラベル:(θ + αで表示位置を調整)
  geom_point(data = point_df, 
             mapping = aes(x = x, y = y, shape = point_type), 
             size = 4, show.legend = FALSE) + # 円周上の点
  geom_vline(xintercept = 1, linetype = "dashed") + # 補助線
  geom_hline(yintercept = 1, linetype = "dashed") + # 補助線
  geom_path(data = radian_df, 
            mapping = aes(x = x, y = y), 
            color = "red", linewidth = 1) + # 関数円弧
  geom_segment(data = fnc_seg_df, 
               mapping = aes(x = x_from, y = y_from, xend = x_to, yend = y_to, 
                             color = fnc, linewidth = w)) + # 関数線分
  geom_text(data = fnc_label_df,
            mapping = aes(x = x, y = y, label = fnc_label, color = fnc,
                          angle = a, hjust = h, vjust = v),
            parse = TRUE, show.legend = FALSE) + # 関数ラベル
  scale_color_manual(breaks = fnc_level_vec, 
                     values = c("red", scales::hue_pal()(n = length(fnc_level_vec)-1)), 
                     labels = parse(text = fnc_label_vec), name = "function") + # 凡例表示用, 色の共通化用
  scale_shape_manual(breaks = c("main", "sub"), 
                     values = c("circle", "circle open")) + # 入出力用
  scale_linetype_manual(breaks = c("main", "sub"), 
                        values = c("solid", "dashed")) + # 補助線用
  scale_linewidth_manual(breaks = c("bold", "normal", "thin", "major", "minor"), 
                         values = c(1.5, 1, 0.5, 0.5, 0.25)) + # 重なり対策用, 補助線用, 主・補助目盛線用
  guides(linewidth = "none") + 
  theme(legend.text.align = 0) + 
  coord_fixed(ratio = 1, 
              xlim = c(axis_x_min, axis_x_max), 
              ylim = c(axis_y_min, axis_y_max)) + 
  labs(title = "circular functions", 
       subtitle = parse(text = var_label), 
       x = expression(x == r ~ cos~theta), 
       y = expression(y == r ~ sin~theta))

単位円における偏角とcot関数とarccot関数の関係

 偏角(x軸の正の部分からの角度)をラジアン  \theta とします。中心角が  \theta の弧長は  l = r \theta です。よって(ラジアンを用いると)、単位円における(  r = 1 のとき)偏角  \theta と弧長  l が一致します。半径が  r の円周上の点の座標は  (x, y) = (r \cos \theta, r \sin \theta) です。
 cot関数の値を  z = \cot \theta、arccot関数の値を  \tau = \mathrm{arccot} z と置く(cot関数の入力を  \theta、arccot関数の出力を  \tau とする)と、cot関数が  z になる偏角(弧長)が  \tau であり、 \cot \theta = \cot \tau となります。

アニメーションの作成

 変数を変化させて、単位円におけるarccot関数のアニメーションを作成します。
 作図コードについては「GitHub - anemptyarchive/Mathematics/.../arccot_definition.R」を参照してください。

 単位円における偏角とarccot関数の円弧の関係を可視化します。

 cot関数の終域  -\infty \leq \cot \theta \leq \infty をarccot関数の定義域  -\infty \leq z \leq \infty として、終域が  0 \leq \mathrm{arccot}\ z \leq \pi になるのを確認できます。

単位円と曲線の関係

 最後は、単位円と関数曲線のグラフを作成して、変数(ラジアン)と座標の関係を確認します。
 作図コードについては「arccot_definition.R」を参照してください。

変数と座標の関係

 変数に応じて移動する円周上の点と曲線上の点のアニメーションを作成します。

 円周上の点とarccot関数曲線上の点の関係を可視化します。

  \cot \theta に対応する偏角(弧長)  \tau = \arctan(\tan \theta)\ \mathrm{or}\ \arctan(\tan \theta) + \pi と曲線の縦軸の値、 z = \cot \theta = \cot \tau と曲線の横軸の値が一致するのを確認できます。

 この記事では、逆cot関数を確認しました。次の記事では、逆sec関数を確認します。

おわりに

 数式弄りが嫌になって最近はグラフを描いて気を紛らわせつつ数学をしているんですが、こうやって不意に数式を扱う必要が出てくるんですよね。式変形が嫌いなわけではないので、リハビリと思えばまぁいいですかね。
 最後に書くのもなんですが、場合分けのところがよく分からず若干言葉を濁しました。cot関数の記事のtan曲線とcot曲線を並べたグラフとを見ると分かりやすいと思います。

 この記事に訪れた人も数式の羅列を見たいわけではないと思うので、クリックしないと目に入らないようにしておきました。
 アニメーションの作図コードについてもGitHubに上げているのを見てもらう形にしました。元々の記事では手元で再現したい人(主に将来の自分)に向けて作図処理の解説も書いていたのですが、コード込みで10万文字を超えたこともあったり、他の記事との兼ね合いで修正するなどの際の管理が面倒だったりで、止めました。

 近頃、初学者だった頃の気持ちを脳内再現できなくなってきた気がします。初心者エミュレータが機能しないとブログのコンセプトに関わるのですが、これも成長の結果なんだと思います。よく言うと冗長さが減った気がします。
 いやまぁ初学者ではなくなったとはいえまだまだ分からないことだらけなので、行間を生む側に回ったとは思えませんし大丈夫でしょう。

 2024年2月2日は、モーニング娘。'24の牧野真莉愛さんの23歳のお誕生日です。

 見てこの圧倒的な美少女感を!

 そして、ばってん少女隊の瀬田さくらさんの22歳のお誕生日です。

 スタプラはエビ中だけと心に決めていたんですが、最近TLに流れてきたキツネ衣装があまりに可憐で心を魅かれてしまいました。にわかです、よろしくお願いします。

【次の内容】

www.anarchive-beta.com