воскресенье, 27 октября 2013 г.

Обновление dlib.image

В dlib.image появилась возможность отслеживать прогресс во время работы фильтров. Для этого используется многопоточность - необходимо создать класс-враппер, наследующий от FilteringThread. Прогресс (от 0 до 1) считывается из свойства progress для SuperImage. В данном примере показано, как использовать эту функциональность для вывода прогресса свертки в консоль:

import std.stdio;
import dlib.image.image;
import dlib.image.io.png;
import dlib.image.filters.convolution;
import dlib.image.fthread;

class ConvolutionThread: FilteringThread
{
    float[] kernel;
    
    this(SuperImage img, float[] k)
    {
        super(img);
        kernel = k;
    }
    
    override void run()
    {
        output = image.convolve(kernel);
    }
    
    override void onRunning()
    {
        writef("Convolving %s%%", cast(uint)(image.progress * 100));
        write("\r");
        stdout.flush();
    }
    
    override void onFinished()
    {
        writeln();
    }
}

void main()
{
    auto img = loadPNG("test.png");
    img = (new ConvolutionThread(img, Kernel.Emboss)).filtered;
    img.savePNG("output.png");
}

суббота, 19 октября 2013 г.

Пример работы с Yahoo! Finance на D

Пример работы с сетевым API Yahoo! Finance: запрос котировок ценных бумаг. Демонстрирует некоторые распространенные идиомы Phobos - например, форматированный ввод, объекты времени и даты. Использует минималистичный HTTP-клиент DHTTPClient. На ввод программа принимает тикер (биржевое обозначение акции) - например, MGNT.ME для акций "Магнит". Выводит стоимость, дату и время последней сделки.

module main;

import std.stdio;
import std.string;
import std.uri;
import std.format;
import std.datetime;

import dhttpclient;

struct Quote
{
    string symbol;     // s
    string name;       // n
    double lastTrade;  // l1
    string currency;   // c4
    DateTime datetime; // d1 t1
}

Quote getQuote(string sym)
{   
    const request = "snl1c4d1t1";

    const url = 
        "http://finance.yahoo.com/d/quotes.csv?e=.csv"
      ~ "&f=" ~ request
      ~ "&s=" ~ sym.encode;
    
    auto http = new HTTPClient();
    auto data = http.get(url).chomp;

    Quote q;

    with (q)
    {
        uint year, month, day;
        string time;

        formattedRead(data, 
            "\"%s\",\"%s\",%s,\"%s\",\"%s/%s/%s\",\"%s\"", 
            &symbol, &name,
            &lastTrade, &currency,
            &month, &day, &year, &time);

        uint hour, minute;
        formattedRead(time, "%s:%s", &hour, &minute);
        if (time[$-2..$] == "pm")
            hour += 12;

        datetime = DateTime(year, month, day, hour, minute);
    }

    return q;
}

void main(string[] args)
{
    string s = "AAPL"; // Apple Inc.
    
    if (args.length > 1)
        s = args[1];

    auto q = getQuote(s);

    writefln("Symbol: %s", q.symbol);
    writefln("Name: %s", q.name);
    writefln("Last trade: %s %s (%s)", 
        q.lastTrade, 
        q.currency, 
        q.datetime);
}

пятница, 11 октября 2013 г.

Рефакторинг матриц в dlib

На днях состоялось грандиозное обновление пакета линейной алгебры dlib.math. Изменения коснулись, главным образом, реализации матриц. Если раньше матрицы 2x2, 3x3 и 4x4 имели каждая отдельную независимую реализацию, то теперь все они являются частными случаями обобщенной квадратной матрицы Matrix!(T,N) (где T - тип элементов, N - размерность). Она содержит все необходимые общие методы для матриц любого размера (нахождение определителя, нахождение обратной матрицы, нахождение матрицы миноров и алгебраических дополнений и т.д.), оптимизированные, где это возможно, для размерностей 2, 3 и 4. Таким образом, нынешние специализации Matrix2x2f, Matrix3x3f и Matrix4x4f практически идентичны их прежним аналогам.

Новая реализация создана с учетом обратной совместимости, но все-таки есть несколько критичных изменений:

1. Больше нет шаблонов Matrix2x2!(T), Matrix3x3!(T), Matrix4x4!(T). Используйте вместо них Matrix!(T,2), Matrix!(T,3) и Matrix!(T,4). При этом псевдонимы на специализации типа Matrix2x2f и Matrix4x4d сохранены;

2. Нет доступа к элементам матриц 4x4 через поля m*, t* и h*. Возможен только доступ через поля a*. Это справедливо для матриц любого размера:

a11 a12 a13 a14 .. a1N
a21 a22 a23 a24 .. a2N
a31 a32 a33 a34 .. a3N
a41 a42 a43 a44 .. a4N
 :   :   :   :  .
aN1 aN2 aN3 aN4  ' aNN

2. Все аффинные преобразования (функции rotationMatrix, translationMatrix и др.) и утилитарные функции для матриц вынесены в отдельный модуль dlib.math.affine. Там же находятся функции right, up, forward, translation, scaling, которые раньше были опрелены как методы в Matrix4x4!(T). Благодаря UFCS, их и теперь можно использовать как методы - однако все они теперь представляют собой свойства только для чтения. Пока они определены только для Matrix!(T,4), но в будущем функции базиса (right, up, forwartd) будут доступны и для Matrix!(T,3).

3. В целях обратной совместимости сохраняются модули dlib.math.matrix2x2, dlib.math.matrix3x3, dlib.math.matrix4x4, но они помечены как deprecated. Вместо них импортируйте dlib.math.matrix (и dlib.math.affine, если вам нужны аффинные преобразования)

2. Не рекомендуется использовать identityMatrix3x3!(T) и identityMatrix4x4!(T). Единичные матрицы создаются при помощи статического метода identity: например, Matrix3x3f.identity.

3. Не рекомендуется трансформировать векторы методом transform. Вместо этого лучше использовать умножение вектора на матрицу: Vector3f(1, 2, 3) * myMatrix.

4. Любые матрицы можно создавать при помощи функции-фабрики matrixf, которая автоматически определяет размерность на основе входных данных:

auto m1 = matrixf(
    8, 3, 2, 0,
    4, 0, 2, 0,
    1, 3, 3, 0,
    0, 0, 3, 1
);

Это выражение создаст матрицу типа Matrix!(float,4) и присвоит ее переменной m1.

Убедительная просьба всем пользователям dlib сообщить мне (в Issues в репозитории на GitHub, либо на почту - gecko0307@gmail.com), если будут обнаружены какие-то несостыковки и баги, связанные с данным рефакторингом матриц.

среда, 9 октября 2013 г.

WolframAlpha

Совершенно случайно набрел на интереснейший сервис - http://www.wolframalpha.com. Это гибрид поисковика, базы знаний и вычислительной системы, понимающий запросы на литературном английском.

В первую очередь меня, конечно, заинтересовали его математические возможности. WolframAlpha может служить как простой калькулятор арифметических выражений

32*56-756

...и конвертер величин:

100 kilograms in pounds

Если вам нужна система линейной алгебры, а Matlab/Octave под рукой нет, то сервис поможет и здесь. Например, можно решать уравнения:

solve x^2+2x-1=0

Или рисовать графики функций:

plot f(x)=x^2

Поддерживаются операции с матрицами:

matrix inverse {{8, 3, 2, 0},{4, 0, 2, 0},{1, 3, 3, 0},{0, 0, 3, 1}} decimal

Также у WolframAlpha можно спрашивать какие-нибудь научные факты, например, возраст Вселенной:

universe age in years

Или статистические данные, например, крупнейшие города США:

biggest cities of usa

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

weather in moscow

Я еще не успел ознакомиться со всеми возможностями этой замечательной системы - уверен, там есть еще много интересного.