Инверсия логарифмической функции c для уровня входного сигнала микрофона - PullRequest
0 голосов
/ 01 марта 2020

Я пытаюсь написать слайдер с логарифмическим масштабированием c для контроля порогового значения микрофона.

Я написал нижеприведенную функцию, которая может быть ужасной (математика - не моя сильная сторона), но похоже, что делает логарифмическое c масштабирование, которое я хочу. Однако теперь мне нужно отобразить уровень RMS на шкале, которая использует шкалу, поэтому мне нужно инвертировать эту функцию.

const rmsLogarithmicScale = (value, max) => {
    const log = ((100 - (Math.log((1 - value) * 100) / 4.605170185988092) * 100) / 100) * max;
    return log === Infinity ? max : log;
};

console.log(rmsLogarithmicScale(0.5, 0.05)); // Result: 0.007525749891599539
console.log(rmsLogarithmicScale(0.5, 300)); // Result: 45.15449934959723
const rmsLogarithmicScaleInverse = (rms, max) => {
    // I have literally no idea where to start...
}

rmsLogarithmicScaleInverse(0.007525749891599539, 0.05); // Result: 0.5

Есть ли добрый математик, который может помочь мне разобраться с этим?

Ответы [ 2 ]

1 голос
/ 01 марта 2020

После того, как @Bergi предложил мне попробовать упростить свою исходную функцию, я переписал функцию в стиле @Andy и сумел ее тоже инвертировать.

Вы должны начать с упрощения до const log = -Math.log (1 - значение) / Math.log (100) * max; - Берги

const logScale = (value, max) => {
    const x1 = 1 - value;
    const x2 = -Math.log(x1);
    const x3 = x2 / Math.log(100);
    const x4 = x3 * max;
    return x4;
};

const altInverseRmsLogScale = (lg, max) => {
    const x4 = lg / max;
    const x3 = x4 * Math.log(100);
    const x2 = Math.exp(-x3);
    const x1 = 1 - x2;
    return x1;
};

console.log(logScale(0.7, 300)); // 4.727557716909737
console.log(inverseLogScale(logScale(0.7, 300), 300)); // 0.07000000000000006

Краткая версия

const logScale = (value, max) => (-Math.log(1 - value) / Math.log(100)) * max;

const inverseLogScale = (lg, max) => 1 - Math.exp(-(lg / max * Math.log(100)));

Версия Terser

const logScale = (value, max) => (-Math.log(1 - value) / Math.log(100)) * max;
const inverseLogScale = (lg, max) => 1 - Math.pow(100, -lg / max);

console.log(logScale(0.6, 300));
console.log(inverseLogScale(logScaleTwo(0.6, 300), 300));

https://repl.it/@sarcoma / логарифмическая шкала

Окончательная функция

Мне также нужно было обработать Infinity, возвращаемое при value === max.

const logScale = (value, max) => {
    const log = (-Math.log(1 - value) / Math.log(100)) * max;
    return log === Infinity ? max : log;
};
const inverseLogScale = (lg, max) => 1 - Math.pow(100, -lg / max);
0 голосов
/ 01 марта 2020

Ответ был предоставлен в Java, JavaScript пример ниже исходного

Это обратное вычисление, выраженное в промежуточных формах.

( Но я предпочитаю ваше обсуждение в комментариях - просто добавлю это, потому что это было весело.)

public static void main(String[] args) {
    double v = rmsLogScale(0.5,0.05);
    System.out.println("v = " + v);                // prints 0.007525749891599539
    double iv = invRmsLogScale(v, 0.05);
    System.out.println("iv = "+iv);                // 0.499999999999999994

}

static double rmsLogScale(double v, double m) {
    double x1 = (1 - v) * 100.;
    double x2 = Math.log(x1);
    double x3 = x2 / 4.605170185988092;
    double x4 = x3 * 100.;
    double x5 = 100. - x4;
    double x6 = x5 / 100. * m;

    return x6;
}

static double invRmsLogScale(double lg, double m) {
    double x5 = (lg * 100) / m;
    double x4 = (100. - x5);
    double x3 = x4 / 100.;
    double x2 = x3 * 4.605170185988092;
    double x1 = Math.exp(x2);
    double x0 = 1 - ((x1) / 100.);
    return x0;
}

JavaScript

const rmsLogScale = (v, m) => {
    const x1 = (1 - v) * 100.0;
    const x2 = Math.log(x1);
    const x3 = x2 / 4.605170185988092;
    const x4 = x3 * 100.0;
    const x5 = 100.0 - x4;
    return x5 / 100.0 * m;
};

const inverseRmsLogScale = (lg, m) => {
    const x5 = (lg * 100) / m;
    const x4 = (100.0 - x5);
    const x3 = x4 / 100.0;
    const x2 = x3 * 4.605170185988092;
    const x1 = Math.exp(x2);
    return 1 - ((x1) / 100.0);
};

console.log(rmsLogScale(0.5, 0.5));
console.log(rmsLogScale(0.5, 300));

console.log(inverseRmsLogScale(rmsLogScale(0.5, 0.5), 0.5));
console.log(inverseRmsLogScale(rmsLogScale(0.3, 300), 300));
...