Вычисление среднего значения массива логарифмических значений в JavaScript - PullRequest
1 голос
/ 02 мая 2019

Я вычисляю среднее значение массива значений журнала (децибел, если это имеет значение) в JavaScript. Мне пришло в голову, что если числа являются логарифмическими значениями (где 55 - это 10, умноженное на 54), средний уровень в децибелах не будет средним от логарифмов. Какой лучший способ подойти к этому?

Ниже приведен код, с помощью которого я обычно вычисляю среднее значение в JS. Какой бы изящный способ вычислить среднее значение массива лог-значений в JavaScript?

// These values are in decibels
const samples = [40, 50, 55, 80, 45];
document.getElementById('samples').innerText = JSON.stringify(samples);

let total = 0;

samples.forEach(value => {
  total = total + value;
});

const average = total / samples.length;

document.getElementById('avg').innerText = JSON.stringify(average);
<div>
  Decibel samples:
  <span id="samples"></span>
</div>

<div>
  Average:
  <span id="avg"></span>
</div>

Ответы [ 3 ]

2 голосов
/ 02 мая 2019

На основе определения децибела (@schnauss) Децибела в Википедии . Есть 2 определения: мощность и амплитуда децибел. Я смотрю на мощность децибела .

Избавьтесь от логарифмов, найдите среднее значение и повторно примените логарифм.

mathematics behind the calculations

var samples = [40, 50, 55, 80, 45],
    x = 0.0;

samples.forEach(value => {
    x += Math.pow(10, value/10.0);
});

var average = x / samples.length,
    logAverage = 10 * Math.log10(average);
    
console.log(logAverage);

Результат ~ 73 дБ

1 голос
/ 02 мая 2019

I думаю это соответствующая формула.(Децибелы могут быть довольно запутанными.)

const mean = (ns) => ns.reduce((a, b) => a + b, 0) / (ns.length || 1)

const decibelAverage = (decibels) =>
    10 * Math.log10(mean(decibels.map(n => 10 ** (n / 10))))

console.log(decibelAverage([40, 50, 55, 80, 45])) //~> 73.03013877157564

Дело в том, что децибел представляет 10-кратный логарифм базового-10 уровня мощности.(Существует также другой тип децибела. Если вам нужно, то где-то где-то есть квадратный корень.)

1 голос
/ 02 мая 2019

Простой подход может заключаться в том, чтобы инвертировать журнал в значения, выполнить среднее значение, как обычно, и затем применить журнал к результату. Это может быть более эффективный способ выполнения этой операции, но если производительность не критична, вы можете попробовать ее.

Я не могу попробовать этот код, поэтому, если что-то пойдет не так, не стесняйтесь говорить что-нибудь! Любое предложение приветствуется.

РЕДАКТИРОВАТЬ: забыл заново сделать журнал в конце, просто добавил его

// These values are in decibels
const samples = [40, 50, 55, 80, 45];

//Undo the log. Be careful if base 10 is not the one you are using!
samples.forEach(function(element, index, array){
    array[index] = Math.pow(10, element);
});

document.getElementById('samples').innerText = JSON.stringify(samples);

let total = 0;
 
 samples.forEach(value => {
   total = total + value;
 });

const average = Math.log10(total / samples.length);

document.getElementById('avg').innerText = JSON.stringify(average);
<div>
  Decibel samples:
  <span id="samples"></span>
</div>

<div>
  Average:
  <span id="avg"></span>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...