Выполнение расчетов с накоплением. Произведение

Выполнение расчетов с накоплением. Произведение

Вероятно, суммой с накоплением уже удивить кого-то сложно. Однако, из этой формулы можно вывести произведение с накоплением. Если вспомнить курс школьной метематики.

Постановка задачи

Посчитать произведение с накоплением. Что-то вроде: даны числа 1, 2, 3, требуется посчитать 1, 1*2, 1*2*3 и т.п.

Произведение с накоплением

Формула для тех, кто все уже знает

Хм… не в этот раз ;)

При чем тут математика

Решение базируется на предыдущей статье “Выполнение расчетов с накоплением. Сумма”. Из нее вы можете узнать, как построить формулу, и как она работает.

Самым важным в этом вопросе, является свойство логарифмов:

Сумма логарифмов с одинаковыми основаниями равна логарифму произведения выражений, стоящих под знаками логарифмов слагаемых: ln(x) + ln(y) = ln(xy), (x>0, y>0).

Свойство суммы логарифмов

Обновление формулы

Предыдущая формула расчитывала суммы с накопительным итогом. Как ее вывести написано в статье

Расчет с накоплением суммы

=ARRAYFORMULA(IF(
  B2:B;
  MMULT(
    TRANSPOSE((ROW(B2:B)<=TRANSPOSE(ROW(B2:B)))*B2:B);
    SIGN(B2:B)
  );
  IFERROR(1/0)
))

Из упомянутого математического свойства логарифмов мы можем вытянуть, что e^(ln(x)+ln(y)) = e^ln(xy) = xy, (x>0, y>0). Отлично, то что надо! Видимо, нам нужно получить натуральный логарифм всех наших значений, сложить их, получить значение, а потом возвести экспоненту в степень, равную полученному значению. Да проще паренной репы:

![Расчет с накоплением произведения MMULT]

=ARRAYFORMULA(IF(
  A2:A;
  EXP(MMULT(
    TRANSPOSE(
      LN(IF(ISNUMBER(A2:A)*(ROW(A2:A)<=TRANSPOSE(ROW(A2:A)));A2:A;1))
    );
    (A2:A)^0
  ));
  IFERROR(1/0)
))

Особенности формулы с MMULT

Произведение и степень требуют к себе тщательного подхода, а значит, нам требуется проверять значение на число ISNUMBER(A2:A).

Другой, уже “неприятной”, особенностью является требование использовать только положительные значения. Иной формулы пока нет.

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

Альтернатива

Альтернативной формулой в данном варианте выступает QUERY. Еще бы! Я буду ссылаться уже на другую предыдущую статью “QUERY. Большое число колонок”. В данном случае, нам потребуется расчитать не агрегатную функцию, а обычное произведение всех колонок. Вот так

Соединение запроса QUERY с SEQUENCE

А следовательно

Расчет с накоплением произведения QUERY

=ARRAYFORMULA(QUERY(
  TRANSPOSE(
    (ROW(A2:A10)<=TRANSPOSE(ROW(A2:A10)))*A2:A10 +
      (ROW(A2:A10)>TRANSPOSE(ROW(A2:A10)))
  );
  "select Col" & JOIN("*Col";SEQUENCE(1;ROWS(A2:A10)));
))

Особенности формулы с QUERY

Эта формула тоже не без изъяна. Она очень тяжелая и “падает” при большом числе строк. Например, при 1000 строк уже не каждый ПК “потянет” её.

Преимущество в том, что она считает отрицательные числа. Считает правильно.

А еще она требует правки заголовков, т.к. QUERY без заголовков не бывает ;-) Пример обрезки

Расчет с накоплением произведения QUERY без заголовков

=ARRAYFORMULA(QUERY(
  TRANSPOSE(
    (ROW(A2:A10)<=TRANSPOSE(ROW(A2:A10)))*A2:A10+
      (ROW(A2:A10)>TRANSPOSE(ROW(A2:A10)))
  );
  "select Col" & JOIN("*Col";SEQUENCE(1;ROWS(A2:A10)))&
    " label Col" & JOIN("*Col";SEQUENCE(1;ROWS(A2:A10)))&"''";
))

Уверен, что найдется решение для любого числа и типа данных. Будем пробовать.

Ссылки