\begin{equation*} \newcommand\mean[2]{\mathrm{E}_{#1} \left[ #2 \right]} \end{equation*}

予稿を書きつつある。同時にWavenetを読み込んでいる。 今日思ったのが、プリエンファシスもAuxiliary FunctionでL1スパース解が求まるのでは無いかという想像。式導出だけでもできるはずなのでやってみたい。

試しにやってみたが、圧縮率が微妙に悪化。 値の範囲チェックが悪かったりするかもしれない。コメントアウトで残すには汚いので、ここに供養する。

/* 残差絶対値平均を最小にするプリエンファシスフィルタ係数計算 */
static void LINNEPreemphasisFilter_CalculateLADCoefficient(
        struct LINNEPreemphasisFilter *preem, const int32_t *buffer, uint32_t num_samples)
{
    uint32_t smpl, itr;
    double coef = 0.0f, obj_value, prev_obj_value;
    double curr;

    LINNE_ASSERT(preem != NULL);
    LINNE_ASSERT(buffer != NULL);

#if 0
    /* 係数の初期値を最小二乗法で定める */
    {
        double corr[2];
        curr = buffer[0] * pow(2.0f, -15);
        for (smpl = 0; smpl < num_samples - 1; smpl++) {
            const double succ = buffer[smpl + 1] * pow(2.0f, -15);
            corr[0] += curr * curr;
            corr[1] += curr * succ;
            curr = succ;
        }
        coef = (corr[0] <= 1e-6) ? 0.0f : (corr[1] / corr[0]);
    }
#endif

    prev_obj_value = FLT_MAX;
    for (itr = 0; itr < 10; itr++) {
        double r01 = 0.0f, r11 = 0.0f;

        /* 方程式の係数計算 */
        obj_value = 0.0f;
        curr = buffer[0] * pow(2.0f, -15);
        for (smpl = 0; smpl < num_samples - 1; smpl++) {
            double res, inv_res;
            const double succ = buffer[smpl + 1] * pow(2.0f, -15);
            /* 絶対値残差計算 */
            res = fabs(succ - coef * curr);
            obj_value += res;
            /* 正則化 */
            res = (res < 1e-8) ? 1e-8 : res;
            inv_res = 1.0f / res;
            r01 += succ * curr * inv_res;
            r11 += curr * curr * inv_res;
            curr = succ;
        }

        obj_value /= (num_samples - 1);

        /* 係数更新 */
        coef = r01 / r11;

        /* 収束判定 */
        if (fabs(prev_obj_value - obj_value) < 1e-8) {
            break;
        }
    }

    /* 係数設定 */
    preem->coef = (int32_t)LINNEUtility_Round(coef * pow(2.0f, LINNE_PREEMPHASIS_COEF_SHIFT));
    /* 丸め込み */
    if (preem->coef >= (1 << (LINNE_PREEMPHASIS_COEF_SHIFT - 1))) {
        preem->coef = (1 << (LINNE_PREEMPHASIS_COEF_SHIFT - 1)) - 1;
    }
}

1次線形近似で平均絶対値が最小になるのは中央値 \(m\) のときだから、 \(\mean{}{|x_{n} - a x_{n-1}|}\) を最小化すると考えると、 \(a x_{n-1} = m\) となるようにすれば良くて、

\begin{equation*} \mean{}{|x_{n} - a x_{n-1}|} \end{equation*}

(うまく行かなそうなのでやめた。備忘としては残す。)