# dsearch

二分探索法

## 呼び出し手順

    [ind, occ, info] = dsearch(X, val [, ch ])

## パラメータ

X

  実数ベクトルまたは行列

val

  厳密に昇順(val(1) < val(2) < ... < val(n))のn個の要素を有する 実数 (行または列) ベクトル

ch

  (オプションの) 文字 "c" または "d" (デフォルト値 "c")

ind

  Xと同じ次元の実数ベクトルまたは行列

occ

  val と同じ形式の実数のベクトル (しかし, ch="c"の場合には n-1 個の要素となります)

info

  整数

## 説明

この関数は, ソートされたテーブルを探索したり, いくつかのクラス(間隔または値のクラス)に散らばっている ベクトルの要素の数を数える際に有用です.

デフォルトで,または `ch="c"`の時, これは区間の場合で, n-1 個の間隔で 各 X(i) の探索が行われます. 区間は次のように定義されます:

    I1 = [val(1), val(2)]
    Ik = (val(k), val(k+1)] for 1 < k <= n-1 ;

そして:

ind(i)

  はX(i)の区間番号です. (X(i)が　[val(1),val(n)] の範囲にない場合は 0)

occ(k)

  はIkの中にあるXの要素の数です.

info

  [val(1),val(n)]の範囲にないXの要素の数

`ch="d"` の場合, これは離散値の時で, 各 X(i) に関して val(k) と等しいかどうかの検索となります :

ind(i)

  は,値がX(i) (X(i)=val(k)の場合, ind(i) = k) に一致する要素の添字と等しくなります. X(i) が val に含まれない場合は 0 となります.

occ(k)

  val(k)に等しい X の要素の数

info

  集合{val(1),...,val(n)}の中にない X の要素の数

## 例

    // 例 #1 (elementary stat for U(0,1))
    m = 50000 ; n = 10;
    X = grand(m,1,"def");
    val = linspace(0,1,n+1)';
    [ind, occ] = dsearch(X, val);
    clf() ; plot2d2(val, [occ/m;0])  // no normalisation : y must be near 1/n

    // 例 #2 (elementary stat for B(N,p))
    N = 8 ; p = 0.5; m = 50000;
    X = grand(m,1,"bin",N,p); val = (0:N)';
    [ind, occ] = dsearch(X, val, "d");
    Pexp = occ/m; Pexa = binomial(p,N);
    clf() ; hm = 1.1*max(max(Pexa),max(Pexp));
    plot2d3([val val+0.1], [Pexa' Pexp],[1 2],"111",  ...
            "Pexact@Pexp", [-1 0 N+1 hm],[0 N+2 0 6])
    xtitle(  "binomial distribution B("+string(N)+","+string(p)+") :" ...
            +" exact probability versus experimental ones")

    // 例 #3 (piecewise Hermite polynomial)
    x = [0 ; 0.2 ; 0.35 ; 0.5 ; 0.65 ; 0.8 ;  1];
    y = [0 ; 0.1 ;-0.1  ; 0   ; 0.4  ;-0.1 ;  0];
    d = [1 ; 0   ; 0    ; 1   ; 0    ; 0   ; -1];
    X = linspace(0, 1, 200)';
    ind = dsearch(X, x);

    // Hermite base 関数を定義
    deff("y=Ll(t,k,x)","y=(t-x(k+1))./(x(k)-x(k+1))")   // Lagrange left on Ik
    deff("y=Lr(t,k,x)","y=(t-x(k))./(x(k+1)-x(k))")     // Lagrange right on Ik
    deff("y=Hl(t,k,x)","y=(1-2*(t-x(k))./(x(k)-x(k+1))).*Ll(t,k,x).^2")
    deff("y=Hr(t,k,x)","y=(1-2*(t-x(k+1))./(x(k+1)-x(k))).*Lr(t,k,x).^2")
    deff("y=Kl(t,k,x)","y=(t-x(k)).*Ll(t,k,x).^2")
    deff("y=Kr(t,k,x)","y=(t-x(k+1)).*Lr(t,k,x).^2")

    // 曲線をプロット
    Y = y(ind).*Hl(X,ind) + y(ind+1).*Hr(X,ind) + d(ind).*Kl(X,ind) + d(ind+1).*Kr(X,ind);
    clf(); plot2d(X,Y,2) ; plot2d(x,y,-9,"000")
    xtitle("an Hermite piecewise polynomial")
    // NOTE : you can verify by adding these ones :
    // YY = interp(X,x,y,d); plot2d(X,YY,3,"000")

## 参照

- find
- tabul