Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Как воспользоваться вероятностями R в C

Anna | 24.06.2014 | нет комментариев

R — язык программирования для статистической обработки данных и работы с графикой, а также свободная программная среда вычислений с открытым начальным кодом в рамках плана GNU © Wikipedia. 

В R собрано большое число статистических алгорифмов на все случаи жизни и их дозволено применять не только из родной програмной среды: его поддерживают такие знаменитые математические пакеты, как SPSS, Statistica, SAS, Wolfram Mathematica и некоторые другие. Как же дозволено интегрировать R в свои приложения?
На програпрогре теснее была статья про применение R в С , впрочем она осветила каждого один из методов, тот, что допустимо применять только если ваш код распространяется под GPL-совместимой лицензией. Но и в отвратном случае есть выход — применение пакета Rserve.

Rserve

Rserve — это TCP/IP / unix socket сервер, тот, что разрешает применять вероятности R без необходимости линковаться с его библиотеками. Заказчики реализованы под разные знаменитые языки, такие как C/C , Java, PHP. Код заказчиков распространяется под LGPL.

Установим R и Rserve:

# sudo apt-get instal r-base
# sudo R
> install.packages("Rserve");

Сейчас осталось запустить Rserve:

# R CMD Rserve

Существует также отладочный режим

# R CMD Rserve.dbg

При запуске без параметров Rserve работает в режиме TCP/IP сервера на дефолтном порту (6311). Дабы применять unix sockets следует запускать Rserve с флагом –RS-socket

# R CMD Rserve --RS-socket "/home/zoberg/mysocket"

Список доступных флагов дозволено посмотреть, набрав

# R CMD Rserve --help

C заказчик

C заказчик состоит из 4 заголовочных файлов: Rconnection.h (здесь лежат все объявление, которые могут потребоваться в работе), Rsrv.hconfig.h (необходим только в Windows), sisocks.h (кроссплатформенные сокеты) и одного Rconnection.cc. Взять их все дозволено из официального репозитория на guthub.

Выходит, разберём сейчас демо, охватывающее множество основных операций

/// main.cpp
#include <iostream>
using std::cout;

#define MAIN                      // коcтыль из sisocks.h
#define SOCK_ERRORS  // verbose socket errors

#include "sisocks.h"
#include "Rconnection.h"

// незатейливый пример работы с C   API
int main(int argc, char **argv) {
    initsocks(); // необходимо только под Win32 - ничего не делает в unix

    // создаем объект подключения к Rserve. 
    // Параметры конструктора по умолчанию - "127.0.0.1", 6311.
    // если хотим применять unix sockets, то следует передавать такие параметры: 
    // Rconnection *rc = new Rconnection("/home/zoberg/mysocket", -1);
    Rconnection *rc = new Rconnection();

    int i=rc->connect();
    if (i) {
        char msg[128];
        sockerrorchecks(msg, 128, -1);
        printf("unable to connect (result=%d, socket:%s).n", i, msg); return i;
    }

    double d[6] = { 1.5, 2.4, 5.6, -1.2, 0.6, 1.7 };

    // присвоим определенный выше массив переменной "a" в R
    Rdouble *rd = new Rdouble(d, 6);
    rc->assign("a", rd);
    delete rd;

    // создаем матрицу "b" размером 2 x 3 и считаем произведение матриц b * t(b)
    Rdouble *x = (Rdouble*) rc->eval("b<-matrix(a,2); b%*%t(b)");

    if (x) { // если всё прошло отлично, то получаем итог
        cout << x << "n";

        // получим размерность получившейся в итоге матрицы
        Rinteger *dim = (Rinteger*) x->attribute("dim");
        if (dim)
            cout << dim->intAt(0) << " by " << dim->intAt(1) << " matrixn";

        // выведем матрицу итога (без форматирования)
        double *d = x->doubleArray();
        int i=0, ct = x->length();
        while (i < ct) {
            cout << d[i  ] << " "; 
        }
        cout << "n";

        // освободим память
        delete x;
    }

    // присваивание массива целых чисел переменной i в R
    int ia[6] = { 1, 4, 6, 3, 5 , 2 };
    Rinteger *ri = new Rinteger(ia, 6);
    rc->assign("i", ri);
    delete ri;

    // Ирисы Фишера — это комплект данных для задачи систематизации, 
    // на примере которого Рональд Фишер в 1936 году продемонстрировал
    // работу разработанного им способа дискриминантного обзора.
    // Данный комплект данных есть в R, получим его
    Rvector *iris = (Rvector*) rc->eval("data(iris); iris");
    if (!iris) {
        cout << "oops! couldn't get iris datan"; delete rc; return 0;
    }

    // сейчас из этого комплекта данных предпочтем ширину чашелистиков (sepal width) -
    // дешевая операция без обращения к Rserve, так как мы теснее имеем все нужные данные
    Rdouble *sw = (Rdouble*) iris->byName("Sepal.Width");
    double *swd = sw->doubleArray();

    // and print it ...
    { 
        int i=0, ct=sw->length(); 
        while (i<ct) {
            cout << swd[i  ] << " ";
        }
        cout << "n";
     }

    // Следует освобождать только память, выделенную под iris,
    // деструктор sw вызывается механически.
    delete iris;

    // освободим объект соединения. Соединение будет разорвано.
    delete rc;
}

Примечание насчет управления памятью: каждая нужная память аллоцируется объектом Rmessage, тот, что неявно создается при вызове «eval». Собственником этого объекта является Rexp, возвращаемый eval’ом (назовём его основным). Невозможно освобождать никакие другие Rexp, помимо основного! Всякий иной Rexp, ассоциированный с основным, становится недействительным позже освобождения основного Rexp. Также позже освобождения основного Rexp недействительными становятся все указатели (скажем, возвращаемые способом doubleArray()).

Скомпилируем

# g   -c Rconnection.cc
# g   Rconnection.o main.cpp -o RExample -lcrypt

и запустим

# ./RExample
Rdouble[4]
2 by 2 matrix
33.97 -2.1 -2.1 10.09 
3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 3.7 3.4 3 3 4 4.4 3.9 3.5 3.8 3.8 3.4 3.7 3.6 3.3 3.4 3 3.4 3.5 3.4 3.2 3.1 3.4 4.1 4.2 3.1 3.2 3.5 3.6 3 3.4 3.5 2.3 3.2 3.5 3.8 3 3.8 3.2 3.7 3.3 3.2 3.2 3.1 2.3 2.8 2.8 3.3 2.4 2.9 2.7 2 3 2.2 2.9 2.9 3.1 3 2.7 2.2 2.5 3.2 2.8 2.5 2.8 2.9 3 2.8 3 2.9 2.6 2.4 2.4 2.7 2.7 3 3.4 3.1 2.3 3 2.5 2.6 3 2.6 2.3 2.7 3 2.9 2.9 2.5 2.8 3.3 2.7 3 2.9 3 3 2.5 2.9 2.5 3.6 3.2 2.7 3 2.5 2.8 3.2 3 3.8 2.6 2.2 3.2 2.8 2.8 2.7 3.3 3.2 2.8 3 2.8 3 2.8 3.8 2.8 2.8 2.6 3 3.4 3.1 3 3.1 3.1 3.1 2.7 3.2 3.3 3 2.5 3 3.4 3 

Готово! Больше подробные данные об интерфейсе взаимодействия с R дозволено получить, исследовав Rconnection.h.

Rserve.conf

Скажу пару слов о файле конфигураций Rserve.conf. Он предоставляет увлекательную вероятность исполнять определенный код на R сразу при старте Rserve. Файл настроек по умолчанию ищется в /etc/Rserve.conf, но дозволено задавать и иной путь, воспользовавшись флагом –RS-conf при запуске Rserve. Rserve.conf может содержать следующие опции:

workdir <path> [/tmp/Rserv] 
pwdfile <file> [none=disabled] 
remote enable|disable [disable]
auth required|disable [disable]
plaintext enable|disable [disable]
fileio enable|disable [enable]
interactive yes|no [yes] (since 0.6-2)

(с версии 0.1-9):
socket <socket> [none=disabled]
port <port> [6311]
maxinbuf <size in kb> [262144]

(с версии 0.3):
maxsendbuf <size in kb> [0=unlimited]
uid <uid> [none]
gid <gid> [none]
su now|server|client [none] (since 0.6-1)

(с версии 0.3-16):
source <file>
eval <expressions>

(с версии 0.5 и только в unix):
chroot <directory> [none]
sockmod <mode> [0=default]
umask <mask> [0]

(с версии 0.5-3):
encoding native|utf8|latin1 [native]

Пакету Rserve и C заказчику для него теснее много лет, впрочем никаких русскоязычных мануалов по ним я не нашёл. Верю, что данная статья сэкономит кому-то немножко времени.

P.S. Существует load-balancer для Rserve: RSproxy.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB