Dodatkowe narzędzia

Biblioteki tu opisane są opcjonalne. Można je zainstalować w miarę potrzeb. Tutorial przybliżający ogólne zasady instalacji: http://cpp0x.pl/artykuly/?id=48.

Statystyka (prob)

Funkcje gęstości rozkładów zmiennych losowych, generatory zmiennych losowych i testy statystyczne (cdf, pdf, cdf_inv, sample, mean, variance) oraz funkcje specjalne (kombinatoryczne, bessel, beta, digamma, zeta itp.) znajdują się w bibliotece „prob”. Jest to biblioteka zewnętrzna przygotowana przez Johna Burkardta. Dołącza się ją za pomocą:

#include <ext/prob.h>

Dostępne rozkłady:

angle half_normal
anglit hypergeometric
arcsin i4
benford i4row
bernoulli i4vec
beta_binomial inverse
beta laplace
binomial Levy
birthday log_normal
bradford log_series
buffon_laplace log_uniform
buffon logistic
burr lorentz
cardioid maxwell
cauchy multinomial
chi multivariate_normal
chi_square nakagami
chi_square_noncentral negative_binomial
circular_normal_01 normal_01
circular_normal normal
cosine pareto
coupon pearson
deranged planck
dipole point_distance
dirichlet poisson
dirichlet_mix power
dirichlet_multinomial quasigeometric
discrete r4
empirical_discrete r8
english_sentence_length r8row
english_word_length r8vec
erlang rayleigh
exponential_01 reciprocal
exponential runs
extreme_values sech
f semicircular
f_noncentral student
fischer student_noncentral
fisk triangle
folded_normal triangular
frechet uniform_01
gamma uniform
gamma_inc uniform_discrete
genlogistic von_mises
geometric weibull
gompertz weibull_discrete
gumbel Zipf

Pliki z parametrami (INIReader)

Parametry programu można definiować w pliku i wczytywać w wygodny sposób za pomocą biblioteki „INIReader”. Można zdefiniować stałe liczbowe lub tekstowe oraz organizować je w sekcje. Bibliotekę dołącza się za pomocą:

#include <ext/INIReader.h>

Przykład

Plik test.ini:

; Test config file for ini_example.c and INIReaderTest.cpp
[protocol] ; Protocol configuration
version=6 ; IPv6
[user]
name = Bob Smith ; Spaces around '=’ are stripped
email = bob@smith.com ; And comments (like this) ignored
active = true ; Test a boolean
pi = 3.14159 ; Test a floating point number

Plik zawiera dwie przykładowe sekcje: protocol i user. W pierwszej jest jeden parametr, w drugiej cztery. Komentarze poprzedza średnik (można również używać //).

Program:

INIReader reader("test.ini");

if (reader.ParseError() < 0)
{
  cout << "Can't load 'test.ini'" << endl;
  return 1;
}
cout << "Config loaded from 'test.ini': version=" << reader.GetInteger("protocol", "version", -1)
     << ", name=" << reader.Get("user", "name", "UNKNOWN")
     << ", email=" << reader.Get("user", "email", "UNKNOWN")
     << ", pi=" << reader.GetReal("user", "pi", -1)
     << ", active=" << reader.GetBoolean("user", "active", true) << endl;

Program wczytuje dane z pliku „test.ini” i pobiera parametry ze wskazanych sekcji i o podanych nazwach. Trzeci argument funkcji wczytujących odpowiada za wartość domyślną, przyjmowaną w przypadku, gdy w pliku zabraknie definicji danego parametru. Funkcje wczytujące parametry w zależności od wersji interpretują parametry jako odpowiedni typ danych:

Funkcja wczytująca Rodzaj zmiennej
Get Napis
GetInteger Liczba całkowita
GetReal Liczba rzeczywista
GetBoolean Wartość logiczna

Obliczenia wieloprocesorowe (omp)

W C++ w prosty sposób możliwe jest tworzenie programów wieloprocesorowych. Umożliwia to biblioteka OpenMP (http://openmp.org/wp/). Najbardziej czasochłonne fragmenty kodu (jakimi są zwykle pętle), można przyśpieszyć bardzo prosto. Dołącza się ją za pomocą:

#include <omp.h>

Pętla wykonywana na 1 rdzeniu procesora:

for (int n=1; n<=1000; n++)
{
  // jakiś kod korzystający ze zmiennych z1, z2, z3
}

Ta sama pętla wykonywana na 10 rdzeniach procesora:

# pragma omp parallel for private(z1,z2,z3) num_threads(10) schedule(static)
for (int n=1; n<=1000; n++)
{
  // jakiś kod korzystający ze zmiennych z1, z2, z3
}

Zmienne używane wewnątrz pętli zostały oznaczona jako prywatne, tzn. każdy z rdzeni będzie posługiwał się własnym zestawem tych zmiennych. Wątki nie mogą korzystać z tych zmiennych równocześnie, bo spowodowałoby to konflikt wartości i błędy w obliczeniach. Rezerwowanie zmiennych odbywa się za pomocą instrukcji 'private’. Jeśli zmienna ma wchodząc do pętli mieć konkretną wartość, należy użyć 'firstprivate’. Instrukcja 'schedule’ określa sposób w jaki zostanie podzielone zadanie wykonania pętli między rdzenie procesora. Jeśli każde pojedyncze wykonanie zajmuje mniej więcej tyle samo czasu, to należy stosować „sztywny podział” zadań (static). W przykładzie wykonanie pętli zostanie podzielone na 10 części, po 100 przebiegów zmiennej 'n’. Pierwszy rdzeń wykona pętlę dla 'n’ od 1 do 100, drugi dla 'n’ od 101 do 200 itd.

Natomiast jeśli pojedyncze wykonanie zajmuje raz więcej, a raz mniej czasu, to wtedy efektywniej jest zastosować „dynamiczny podział” zadań (dynamic).

Przydatna jest też komenda ‘reduction’, która pozwala łączyć wyniki obliczeń wykonywanych przez niezależne procesy. Na przykład:

int suma=0;
# pragma omp parallel for reduction(+: suma) num_threads(10) schedule(static)
for (int n=1; n<=1000; n++)
{
  suma+=n;
}

Powyższy kod wykona sumowanie w 10 niezależnych wątkach. Na koniec wyniki „cząstkowe” otrzymane dla zmiennej ‘suma’ zostaną scalone (w tym przypadku zsumowane).

Uwaga! Konieczne jest skonfigurowanie środowiska. W Settings/Compiler and debugger/Compliter settings/Other options wpisuje się –fopenmp. A w Settings/Compiler and debugger/Compliter settings/Linker settings/Link libraries wpisuje się gomp.

Excel

Do odczytu/zapisu danych z Excela służy biblioteka Excel Format (http://www.codeproject.com/Articles/42504/ExcelFormat-Library).

Pliki pakietu należy zainstalować na dysku. Dołączenie biblioteki do programu:

#include <ExcelFormat.h>

using namespace ExcelFormat;

Przykłady użycia:

// stworzenie zakładki 1 i pobranie wskaźnika do niej
xls.New(1);
BasicExcelWorksheet* sheet = xls.GetWorksheet(0);

// dostęp do komórki w wierszu 10 i kolumnie 5
BasicExcelCell* cell = sheet->Cell(10, 5);

// wpisanie wartości do komórki
sheet->Cell(10,5)->Set("text");

// zapis pliku xls
xls.SaveAs("example1.xls"); 

MathGL

Do rysowania wykresów można użyć biblioteki MathGL, która oferuje 55 głównych typów wykresów, w tym specjalne przeznaczone dla zastosowań statystycznych (http://mathgl.sourceforge.net/doc_en/Main.html).

Pliki źrodłowe pakietu należy zainstalować na dysku. Wymagane są również pliki biblioteki Libpng. Dołączenie biblioteki do programu:

#include <mgl2/mgl.h>

Przykład rysowania wykresu trójwymiarowego:

mglData dat(30,40);	// dane do narysowania
for (int i=0;i<30;i++)   for(int j=0;j<40;j++)
  dat.a[i+30*j] = 1/(1+(i-15)*(i-15)/225.+(j-20)*(j-20)/400.);
            
mglGraph gr;		// obiekt do rysowania wykresów
gr.Rotate(50,60);		// obrócenie osi
gr.Light(true);		// włączenie oświetlenie
gr.Surf(dat);		// rysowanie powierzchni
gr.Cont(dat,"y");		// rysowanie żółtej linii konturu
gr.Axis();			// kreślenie osi
gr.WriteFrame("sample.png");	// zapis do pliku

Python

Można uruchamiać programy napisane w Pythonie. Przykład:

#include <Python.h>

int main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);  /* optional but recommended */
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                                        "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
}

Aby uruchomić komendę języku Python, stosuje się instrukcję PyRun_SimpleString(). Aby uruchomić program z pliku, stosuje się PyRun_SimpleFile(), jako argument podając nazwę pliku z kodem w Pythonie.

Powyżej zaprezentowano najprostszy sposób korzystania z kodów w Pythonie. Możliwa jest integracja C++ i Pythona na niższym poziomie (http://docs.python.org/2/extending/embedding.html).