МИВК Многофункциональный
информационно-вычислительный
комплекс ОИЯИ

ROOT предоставляет алгоритмы для интегрирования одномерных функций несколькими адаптивными и неадаптивными методами. Для интегрирования многомерных функций в ROOT используется адаптивный метод или метод Монте-Карло (GSLMCIntegrator).

Для интегрирования одномерных функций следует использовать класс ROOT::Math:: IntegratorOneDim. Он имеет несколько конструкторов. При создании объекта этого класса можно задать в конструкторе только тип желаемого метода интегрирования, а интегрируемую функцию и ошибку определить в соответствующих методах класса. Также можно сразу задать все эти опции в конструкторе. Например:

 ROOT::Math::IntegratorOneDim::IntegratorOneDim(const IGenFunction & f, type, absTol = -1, relTol = -1, size = 0, rule = 0) 
          

Параметры

f – интегрируемая функция (одномерный интерфейс);

type -  метод интегрирования (адаптивный, неадаптивный и т. д.)

absTol - желаемая абсолютная ошибка. Алгоритм остановится, когда будет достигнуто либо абсолютное, либо относительное отклонение.

relTol - желаемая относительная ошибка.

size - размер максимальное количество подинтервалов

rule - правило интегрирования Гаусса-Кронрода (только для метода kADAPTIVE)

 Возможные значения type:

kGAUSS: простой метод интегрирования Гаусса

kLEGENDRE: интеграция Гаусса-Лежандра

kNONADAPTIVE: используется для плавных функций

kADAPTIVE: используется для общих функций без особенностей.

kADAPTIVESINGULAR: тип адаптивной интеграции по умолчанию, который может использоваться в случае наличия особенностей.

kDEFAULT: указание типа по умолчанию в статических параметрах

При передаче значений по умолчанию используемые значения берутся из значений по умолчанию, определенных в ROOT :: Math :: IntegratorOneDimOptions.

Численное интегрирование многомерных интегралов производится с помощью класса ROOT :: Math :: IntegratorMultiDim. Для интегрирования можно использовать метод Монте-Карло или алгоритм Genz – Mallik. Конструктор:

 ROOT::Math::IntegratorMultiDim::IntegratorMultiDim      (const IMultiGenFunction & f,  type = IntegrationMultiDim::kDEFAULT, absTol = -1, elTol = -1, ncall = 0)
 

Возможные значения type:

kADAPTIVE - адаптивное многомерное интегрирование

kPLAIN - простое интегрирование по методу Монте-Карло

kMISER - интегрирование по методу Монте-Карло с помощью алгоритма MISER

kVEGAS - интегрирование по методу Монте-Карло с помощью алгоритма VEGAS

Подробное описание этих алгоритмов можно найти в руководстве GSL.

kDEFAULT - тип по умолчанию, указанный в статической опции.

После того, как объект класса одномерного или многомерного интегрирования создан, к нему следует применить метод Integral():

 

double ROOT::Math::IntegratorOneDim::Integral   (double a, double b )             

double ROOT::Math::IntegratorMultiDim::Integral (const double * a, const double * b )

 

Параметры:

a – нижнее значение интервала интегрирования

b - верхнее значение интервала интегрирования.

В одномерном случае a и b – числа, а в многомерном случае a и b – массивы соответствующей размерности.

Различные опции методов интегрирования можно настроить с помощью классов ROOT :: Math :: IntegratorOneDimOptions и ROOT :: Math :: IntegratorMultiDimOptions.

Ниже приведен пример макроса, вычисляющего 4-х мерный интеграл разными методами.

 

#include "Math/IntegratorMultiDim.h"

#include "Math/Functor.h"

#include "TStopwatch.h"

 

double f4 (const double * x) {

  return x[0]+x[1]+x[2]*x[3];

}

 

  void testIntegrationMultiDim() {

   TStopwatch timer;

   timer.Start();

 

   ROOT::Math::Functor wf(&f4,4);

   double a[4] = {1,2,3,4};

   double b[4] = {4,8,10,12};

 

 

   ROOT::Math::IntegratorMultiDim ig(ROOT::Math::IntegrationMultiDim::kADAPTIVE);

   ig.SetFunction(wf);

   double val = ig.Integral(a,b);

   std::cout << "integral result ADAPTIV is " << val << std::endl;

 

   ROOT::Math::IntegratorMultiDim ig2(ROOT::Math::IntegrationMultiDim::kVEGAS);

   ig2.SetFunction(wf);

   val = ig2.Integral(a,b);

   std::cout << "integral result VEGAS   is " << val << std::endl;

 

   ROOT::Math::IntegratorMultiDim ig3(wf,ROOT::Math::IntegrationMultiDim::kPLAIN);

   val = ig3.Integral(a,b);

   std::cout << "integral result PLAIN   is " << val << std::endl;

 

   ROOT::Math::IntegratorMultiDim ig4(wf,ROOT::Math::IntegrationMultiDim::kMISER);

   val = ig4.Integral(a,b);

   std::cout << "integral result MISER   is " << val << std::endl;

 

   std::cout <<"time:";

   timer.Print("m");

}