1

任意の区間で1を、それ以外で-1を示す関数を作ってみた【Desmos】

259
0

はじめに

 初めまして、きり梅です。
 この記事は自作した関数の解説と、備忘録と、日記と、噂のMathlogへの興味を足して4で割ったような記事です。
 関数はDesmosに合わせて作っています。Desmos以外のソフトでは使えない可能性があります。
 また、著者は数学にわかであり、用語の誤用や拙いTeXや説明等はご了承ください。

経緯

 最近、Twitterとかで数学の面白い話を聞いたりするとDesmosで実験することがちょくちょくある。
 先日、複数の曲線の一部をつなぎ合わせて一つの関数として扱おうとしたのだが、一部を取り出すのに任意の区間で1、それ以外で0を示す関数を作り、曲線の関数と乗算して、それを複数用意し加算するという方法を取った。
 これが、どう実装するかだとか、区間端を含むか含まないかの調整だとかでまあまあ面倒だったので、今後また使う可能性を考え、一般化した関数を作ったので、ついでに備忘録と噂のMathlogを試してみようという事でここに書き記しておくことにします。

完成した関数

 とりあえずページをスクロールするのが面倒なときや人もいると思うのでまず完成した関数を置いておきます。

  https://www.desmos.com/calculator/ujvztcqibu

f(p1,p2,o1,o2,x)=sign(sign(sign(p1p2)(|xp1+p22||p1p22|))+sign(o2o1p2p1(xp1)+o1)10)

 p1が選択区間の左端で、p2が右端です。p1p2間が1、それ以外は1になります。
 o1o2は代入した数が負か0か正かでx=p1,p2の時に-1,0,1のどれになるかをそれぞれ指定できます。
 p2<p1にすることで選択範囲1になります。

解説

 原理を説明するために関数に色を付けてわかりやすくします。

sign(sign(sign(p1p2)(|xp1+p22||p1p22|))+sign(o2o1p2p1(xp1)+o1)10)

 の順で解説します。

赤部の解説

|xp1+p22||p1p22|

 赤部は(p1,0)(p2,0)を通る直角の折れ線になっています。

まず直角の折れ線を作るためxの絶対値を取り、
|x|
折り返し部分をp1p2の中間に合わせる。
|xp1+p22|
(p1,0)(p2,0)を通るように高さを合わせる。
|xp1+p22||p1p22|

 分かりやすくGIFにするとこんな感じです。
赤部GIF 赤部GIF

青部の解説

sign(p1p2)

 青部の役割はp1<p2の時は、1を示し、赤部に乗算することで折れ線を上下反転し、p2<p1になったときには元に戻すことで、区間内選択と区間外選択を切り替えられるようにします。
青部GIF 青部GIF

 ここから赤部と青部を乗算して、sign関数で囲うことで、任意の区間内で1を、区間外で1を示す関数になります(以降これをAとします)。

A
sign(sign(p1p2)(|xp1+p22||p1p22|))

 が、sign(0)=0なので、これだとx=p1,p2の時に数値が0になってしまいます。
青部GIF2 青部GIF2

 それで問題無いならいいのですが、今回はここを1,0,1のいずれかに任意で指定できるようにします。

緑部の解説

 xp1p2の時にそれぞれどのの数値を示すか指定するために、o1,o2を用意します(取りうる数値は1,0,1のいずれかを想定して話を進めますが実際は実数であればいいです)。

 ここで欲しいのは、x=p1の時にo1を示し、x=p2の時にo2を示す関数です。これをAに加算すればA0を示してしまうp1,p2の地点を正か負か0の好きなものに調整できます。

 そのために、(p1,o1)(p2,o2)を通る直線を用意します。これが緑部になります。

o2o1p2p1(xp1)+o1

緑部GIF 緑部GIF

紫部の解説

 先ほどの緑部にもう少し手を加えていきます。このままAに加算すると関係ないところにも影響を与えてしまうので、まずsign関数で囲い、取りうる値の範囲を1x1に収めます。

sign(o2o1p2p1(xp1)+o1)

この状態でも、A1の部分にこちらの関数の1の部分が重なると関数が崩れてしまうので、A0の部分には影響を与えるが、それ以外には影響を与えないように、値の範囲を狭めます。

sign(o2o1p2p1(xp1)+o1)10

今回は適当に10で除算していますが、符号に影響を与えずに1<x<1になるのならどのような方法でもいいです。

紫部GIF 紫部GIF

最後の仕上げの解説

 必要なものは揃ったのでまとめていきます。

sign(sign(p1p2)(|xp1+p22||p1p22|))
Aに紫部を加算して、
sign(sign(p1p2)(|xp1+p22||p1p22|))+sign(o2o1p2p1(xp1)+o1)10
それをsignで囲うだけ。
sign(sign(sign(p1p2)(|xp1+p22||p1p22|))+sign(o2o1p2p1(xp1)+o1)10)

完成GIF 完成GIF

これで完成です。
p2のドットの上にあった黒点が消えていると思います。

もしこれよりスマートにできる方法があったら教えていただけると助かります。

投稿日:202191
OptHub AI Competition

この記事を高評価した人

高評価したユーザはいません

この記事に送られたバッジ

バッジはありません。
バッチを贈って投稿者を応援しよう

バッチを贈ると投稿者に現金やAmazonのギフトカードが還元されます。

投稿者

コメント

他の人のコメント

コメントはありません。
読み込み中...
読み込み中
  1. はじめに
  2. 経緯
  3. 完成した関数
  4. 解説
  5. 赤部の解説
  6. 青部の解説
  7. 緑部の解説
  8. 紫部の解説
  9. 最後の仕上げの解説