long live QtJubatus!
authorTasuku Suzuki <stasuku@gmail.com>
Sat, 8 Jun 2013 14:48:35 +0000 (23:48 +0900)
committerTasuku Suzuki <stasuku@gmail.com>
Sat, 8 Jun 2013 15:06:57 +0000 (00:06 +0900)
Change-Id: I5ff66b0ce8c5730ec51a65d1a410c7ce31dceed2
Reviewed-on: http://cr.qtquick.me/676
Tested-by: Tasuku Suzuki <stasuku@gmail.com>
Reviewed-by: Tasuku Suzuki <stasuku@gmail.com>
35 files changed:
.gitignore [new file with mode: 0644]
.qmake.conf [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
examples/cpp/classifier/classifier.pro [new file with mode: 0644]
examples/cpp/classifier/gender/gender.json [new file with mode: 0644]
examples/cpp/classifier/gender/gender.pro [new file with mode: 0644]
examples/cpp/classifier/gender/main.cpp [new file with mode: 0644]
examples/cpp/classifier/gender/widget.cpp [new file with mode: 0644]
examples/cpp/classifier/gender/widget.h [new file with mode: 0644]
examples/cpp/classifier/gender/widget.ui [new file with mode: 0644]
examples/cpp/cpp.pro [new file with mode: 0644]
examples/examples.pro [new file with mode: 0644]
examples/qml/classifier/classifier.pro [new file with mode: 0644]
examples/qml/classifier/gender/Button.qml [new file with mode: 0644]
examples/qml/classifier/gender/Selector.qml [new file with mode: 0644]
examples/qml/classifier/gender/gender.json [new file with mode: 0644]
examples/qml/classifier/gender/gender.pro [new file with mode: 0644]
examples/qml/classifier/gender/gender.qml [new file with mode: 0644]
examples/qml/classifier/gender/gender.qrc [new file with mode: 0644]
examples/qml/classifier/gender/main.cpp [new file with mode: 0644]
examples/qml/qml.pro [new file with mode: 0644]
jubatus.pro [new file with mode: 0644]
src/imports/imports.pro [new file with mode: 0644]
src/imports/jubatus/jubatus.pro [new file with mode: 0644]
src/imports/jubatus/main.cpp [new file with mode: 0644]
src/imports/jubatus/plugins.qmltypes [new file with mode: 0644]
src/imports/jubatus/qmldir [new file with mode: 0644]
src/jubatus/classifier/classifier.pri [new file with mode: 0644]
src/jubatus/classifier/qjubatusclassifier.cpp [new file with mode: 0644]
src/jubatus/classifier/qjubatusclassifier.h [new file with mode: 0644]
src/jubatus/jubatus.pro [new file with mode: 0644]
src/jubatus/jubatus_global.h [new file with mode: 0644]
src/src.pro [new file with mode: 0644]
sync.profile [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..ddc9832
--- /dev/null
@@ -0,0 +1,2 @@
+*.pro.*
+*.qmlproject.*
diff --git a/.qmake.conf b/.qmake.conf
new file mode 100644 (file)
index 0000000..2bd1ccd
--- /dev/null
@@ -0,0 +1,3 @@
+load(qt_build_config)
+
+MODULE_VERSION = 0.1.0
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..214687b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2012 Silk Project.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Silk nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..accfd16
--- /dev/null
+++ b/README
@@ -0,0 +1,9 @@
+$ git clone git://git.qtquick.me/qmlplugins/jubatus.git
+$ cd jubatus
+$ qmake
+$ make
+$ (sudo) make install
+$ qmlscene ./examples/examples.qml
+
+contributions are always welcome!
+see http://qtquick.me/ for details
diff --git a/examples/cpp/classifier/classifier.pro b/examples/cpp/classifier/classifier.pro
new file mode 100644 (file)
index 0000000..6c95c81
--- /dev/null
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += gender
diff --git a/examples/cpp/classifier/gender/gender.json b/examples/cpp/classifier/gender/gender.json
new file mode 100644 (file)
index 0000000..7beb1f7
--- /dev/null
@@ -0,0 +1,21 @@
+{
+  "method": "AROW",
+  "converter": {
+    "num_filter_types": {},
+    "num_filter_rules": [],
+    "string_filter_types": {},
+    "string_filter_rules": [],
+    "num_types": {},
+    "num_rules": [
+      { "key": "*", "type": "num"}
+    ],
+    "string_types": {
+    },
+    "string_rules": [
+      { "key": "*", "type": "str", "sample_weight": "bin", "global_weight": "bin" }
+    ]
+  },
+  "parameter": {
+    "regularization_weight" : 1.0
+  }
+}
diff --git a/examples/cpp/classifier/gender/gender.pro b/examples/cpp/classifier/gender/gender.pro
new file mode 100644 (file)
index 0000000..a03b161
--- /dev/null
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = jubatus-gender-widget
+QT += widgets jubatus
+CONFIG += c++11
+SOURCES = main.cpp
+
+HEADERS += \
+    widget.h
+
+SOURCES += \
+    widget.cpp
+
+FORMS += \
+    widget.ui
+
+OTHER_FILES += gender.json
diff --git a/examples/cpp/classifier/gender/main.cpp b/examples/cpp/classifier/gender/main.cpp
new file mode 100644 (file)
index 0000000..397e6f7
--- /dev/null
@@ -0,0 +1,38 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "widget.h"
+
+int main(int argc, char **argv)
+{
+    QApplication app(argc, argv);
+
+    Widget widget;
+    widget.show();
+
+    return app.exec();
+}
+
diff --git a/examples/cpp/classifier/gender/widget.cpp b/examples/cpp/classifier/gender/widget.cpp
new file mode 100644 (file)
index 0000000..4236107
--- /dev/null
@@ -0,0 +1,83 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "widget.h"
+#include "ui_widget.h"
+
+static QVariantMap makeDatum(const Ui::Widget *ui)
+{
+    QVariantMap ret;
+    ret.insert(QStringLiteral("hair"), ui->hair->currentText());
+    ret.insert(QStringLiteral("top"), ui->top->currentText());
+    ret.insert(QStringLiteral("bottom"), ui->bottom->currentText());
+    ret.insert(QStringLiteral("height"), ui->height->value());
+    return ret;
+}
+
+static QList<QJubatusClassifier::TrainData> makeTrainData(const QString &label, const Ui::Widget *ui)
+{
+    QList<QJubatusClassifier::TrainData> ret;
+    QJubatusClassifier::TrainData data;
+    data.first = label;
+    data.second = makeDatum(ui);
+    ret.append(data);
+    return ret;
+}
+
+Widget::Widget(QWidget *parent)
+    : QDialog(parent)
+    , ui(new Ui::Widget)
+{
+    ui->setupUi(this);
+
+    connect(ui->male, &QPushButton::clicked, [&] {
+        classifier.train(QStringLiteral("test"), makeTrainData(QStringLiteral("male"), ui));
+    });
+
+    connect(ui->female, &QPushButton::clicked, [&] {
+        classifier.train(QStringLiteral("test"), makeTrainData(QStringLiteral("female"), ui));
+    });
+
+    connect(ui->other, &QPushButton::clicked, [&] {
+        classifier.train(QStringLiteral("test"), makeTrainData(QStringLiteral("other"), ui));
+    });
+
+    connect(ui->classify, &QPushButton::clicked, [&] {
+        QStringList text;
+        QList<QList<QJubatusClassifier::EstimateResult>> results = classifier.classify(QStringLiteral("test"), QList<QVariantMap>() << makeDatum(ui));
+        foreach (const QList<QJubatusClassifier::EstimateResult> &result, results) {
+            foreach (const QJubatusClassifier::EstimateResult &r, result) {
+                text.append(QString("%1\t%2").arg(r.label).arg(r.score));
+            }
+        }
+        ui->result->setPlainText(text.join(QStringLiteral("\n")));
+    });
+}
+
+Widget::~Widget()
+{
+    delete ui;
+}
diff --git a/examples/cpp/classifier/gender/widget.h b/examples/cpp/classifier/gender/widget.h
new file mode 100644 (file)
index 0000000..1a3f4eb
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WIDGET_H
+#define WIDGET_H
+
+#include <QtWidgets>
+#include <QtJubatus/QJubatusClassifier>
+
+namespace Ui {
+    class Widget;
+}
+
+class Widget : public QDialog
+{
+    Q_OBJECT
+    
+public:
+    explicit Widget(QWidget *parent = 0);
+    ~Widget();
+    
+private:
+    Ui::Widget *ui;
+    QJubatusClassifier classifier;
+};
+
+#endif // WIDGET_H
diff --git a/examples/cpp/classifier/gender/widget.ui b/examples/cpp/classifier/gender/widget.ui
new file mode 100644 (file)
index 0000000..c8e6d34
--- /dev/null
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget</class>
+ <widget class="QWidget" name="Widget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>331</width>
+    <height>386</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QGroupBox" name="groupBox">
+       <property name="title">
+        <string>Elements</string>
+       </property>
+       <layout class="QFormLayout" name="formLayout">
+        <item row="0" column="0">
+         <widget class="QLabel" name="label">
+          <property name="text">
+           <string>&amp;Hair:</string>
+          </property>
+          <property name="buddy">
+           <cstring>hair</cstring>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="QComboBox" name="hair">
+          <item>
+           <property name="text">
+            <string>short</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>long</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="label_2">
+          <property name="text">
+           <string>&amp;Top:</string>
+          </property>
+          <property name="buddy">
+           <cstring>top</cstring>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QComboBox" name="top">
+          <item>
+           <property name="text">
+            <string>sweeter</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>shirt</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>jacket</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>T shirt</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item row="2" column="0">
+         <widget class="QLabel" name="label_3">
+          <property name="text">
+           <string>&amp;Bottom:</string>
+          </property>
+          <property name="buddy">
+           <cstring>bottom</cstring>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="QComboBox" name="bottom">
+          <item>
+           <property name="text">
+            <string>jeans</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>skirt</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>chino</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item row="3" column="0">
+         <widget class="QLabel" name="label_4">
+          <property name="text">
+           <string>&amp;Height:</string>
+          </property>
+          <property name="buddy">
+           <cstring>height</cstring>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="1">
+         <widget class="QDoubleSpinBox" name="height">
+          <property name="minimum">
+           <double>1.000000000000000</double>
+          </property>
+          <property name="maximum">
+           <double>2.000000000000000</double>
+          </property>
+          <property name="singleStep">
+           <double>0.050000000000000</double>
+          </property>
+          <property name="value">
+           <double>1.600000000000000</double>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <widget class="QPushButton" name="male">
+         <property name="text">
+          <string>Learn as &quot;male&quot;</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="female">
+         <property name="text">
+          <string>Learn as &quot;female&quot;</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="other">
+         <property name="text">
+          <string>Learn as &quot;other&quot;</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="classify">
+         <property name="text">
+          <string>classify</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QPlainTextEdit" name="result"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/cpp/cpp.pro b/examples/cpp/cpp.pro
new file mode 100644 (file)
index 0000000..b102086
--- /dev/null
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS += classifier
diff --git a/examples/examples.pro b/examples/examples.pro
new file mode 100644 (file)
index 0000000..d1ff340
--- /dev/null
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+!isEmpty(QT.jubatus.name) {
+       SUBDIRS += cpp
+       !isEmpty(QT.qml.name): SUBDIRS += qml
+}
+
diff --git a/examples/qml/classifier/classifier.pro b/examples/qml/classifier/classifier.pro
new file mode 100644 (file)
index 0000000..0ccf948
--- /dev/null
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS += gender
+
diff --git a/examples/qml/classifier/gender/Button.qml b/examples/qml/classifier/gender/Button.qml
new file mode 100644 (file)
index 0000000..7e3c0ef
--- /dev/null
@@ -0,0 +1,87 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import QtQuick 2.0
+
+MouseArea {
+    id: root
+    width: 100
+    height: 100
+
+    property bool checkable: false
+    property bool checked: false
+    property alias backgroundColor: background.color
+    property alias color: text.color
+    property alias font: text.font
+    property alias text: text.text
+
+    Rectangle {
+        id: background
+        anchors.fill: parent
+        anchors.margins: 2
+        color: 'tomato'
+        z: -1
+    }
+
+    Text {
+        id: text
+        anchors.fill: parent
+        verticalAlignment: Text.AlignVCenter
+        horizontalAlignment: Text.AlignHCenter
+        elide: Text.ElideRight
+        font.pixelSize: 26
+        color: 'white'
+    }
+
+    StateGroup {
+        states: [
+            State {
+                name: "checked"
+                when: root.checkable && root.checked
+                PropertyChanges {
+                    target: root
+                    opacity: 1
+                }
+            },
+            State {
+                name: "unchecked"
+                when: root.checkable && !root.checked
+                PropertyChanges {
+                    target: root
+                    opacity: 0.5
+                }
+            },
+            State {
+                name: "pressed"
+                when: !root.checkable && root.pressed
+                PropertyChanges {
+                    target: root
+                    scale: 0.8
+                }
+            }
+        ]
+    }
+}
diff --git a/examples/qml/classifier/gender/Selector.qml b/examples/qml/classifier/gender/Selector.qml
new file mode 100644 (file)
index 0000000..f11942e
--- /dev/null
@@ -0,0 +1,55 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import QtQuick 2.0
+
+Item {
+    id: root
+    height: 40
+    width: 100
+    property color color: 'red'
+    property alias model: repeater.model
+
+    property int currentIndex: 0
+    property string curerntText: root.model[currentIndex]
+
+    Row {
+        anchors.centerIn: parent
+        Repeater {
+            id: repeater
+            Button {
+                id: button
+                width: 100
+                height: 40
+                text: model.modelData
+                backgroundColor: root.color
+                checkable: true
+                checked: model.index === root.currentIndex
+                onClicked: root.currentIndex = model.index
+            }
+        }
+    }
+}
diff --git a/examples/qml/classifier/gender/gender.json b/examples/qml/classifier/gender/gender.json
new file mode 100644 (file)
index 0000000..7beb1f7
--- /dev/null
@@ -0,0 +1,21 @@
+{
+  "method": "AROW",
+  "converter": {
+    "num_filter_types": {},
+    "num_filter_rules": [],
+    "string_filter_types": {},
+    "string_filter_rules": [],
+    "num_types": {},
+    "num_rules": [
+      { "key": "*", "type": "num"}
+    ],
+    "string_types": {
+    },
+    "string_rules": [
+      { "key": "*", "type": "str", "sample_weight": "bin", "global_weight": "bin" }
+    ]
+  },
+  "parameter": {
+    "regularization_weight" : 1.0
+  }
+}
diff --git a/examples/qml/classifier/gender/gender.pro b/examples/qml/classifier/gender/gender.pro
new file mode 100644 (file)
index 0000000..b5c8c1f
--- /dev/null
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = jubatus-gender-quick
+QT += widgets quick jubatus
+
+SOURCES = main.cpp
+
+RESOURCES += \
+    gender.qrc
+
+OTHER_FILES += gender.qml gender.json \
+    Selector.qml \
+    Button.qml
diff --git a/examples/qml/classifier/gender/gender.qml b/examples/qml/classifier/gender/gender.qml
new file mode 100644 (file)
index 0000000..5da9633
--- /dev/null
@@ -0,0 +1,145 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import QtQuick 2.0
+import QtJubatus 0.1 as Jubatus
+
+Rectangle {
+    id: root
+    width: 600
+    height: 400
+
+    Column {
+        width: parent.width
+        Selector {
+            id: hair
+            width: parent.width
+            model: ['short', 'long']
+            color: 'black'
+        }
+
+        Selector {
+            id: top
+            width: parent.width
+            model: ['sweeter', 'shirt', 'jacket', 'T shirt']
+            color: 'red'
+        }
+
+        Selector {
+            id: bottom
+            width: parent.width
+            model: ['jeans', 'skirt', 'chino']
+            color: 'blue'
+        }
+
+        TextInput {
+            id: height
+            width: 100
+            height: 40
+            anchors.horizontalCenter: parent.horizontalCenter
+            font.pixelSize: 26
+            horizontalAlignment: TextInput.AlignHCenter
+            verticalAlignment: TextInput.AlignVCenter
+            text: '1.60'
+            validator: DoubleValidator {
+                top: 2.00
+                bottom: 1.00
+                decimals: 2
+            }
+
+            Rectangle {
+                anchors.fill: parent
+                anchors.margins: 2
+                z: -1
+                color: 'yellow'
+            }
+        }
+
+        Row {
+            anchors.horizontalCenter: parent.horizontalCenter
+            Button {
+                text: 'male'
+                backgroundColor: 'blue'
+                onClicked: root.train('male')
+            }
+            Button {
+                text: 'female'
+                backgroundColor: 'red'
+                onClicked: root.train('female')
+            }
+            Button {
+                text: 'other'
+                backgroundColor: 'purple'
+                onClicked: root.train('other')
+            }
+        }
+
+        Row {
+            anchors.horizontalCenter: parent.horizontalCenter
+            Item {
+                width: 300
+                height: 100
+                Rectangle {
+                    anchors.fill: parent
+                    anchors.margins: 2
+                    color: 'black'
+                }
+                Text {
+                    id: result
+                    anchors.fill: parent
+                    verticalAlignment: Text.AlignVCenter
+                    horizontalAlignment: Text.AlignHCenter
+                    elide: Text.ElideRight
+                    font.pixelSize: 26
+                    color: 'white'
+                }
+            }
+            Button {
+                text: 'classify'
+                backgroundColor: 'green'
+                onClicked: {
+                    var data = {'hair': hair.curerntText, 'top': top.curerntText, 'bottom': bottom.curerntText, 'height': parseInt(height.text)}
+                    var results = classifier.classify(data)
+                    var text = []
+                    for (var i in results) {
+                        text.push('%1(%2)'.arg(results[i].label).arg(results[i].score))
+                    }
+                    result.text = text.join('\n')
+                }
+            }
+        }
+    }
+
+    function train(label) {
+        var data = {'hair': hair.curerntText, 'top': top.curerntText, 'bottom': bottom.curerntText, 'height': parseInt(height.text)}
+        classifier.train(label, data)
+    }
+
+    Jubatus.Classifier {
+        id: classifier
+        name: 'test'
+    }
+}
diff --git a/examples/qml/classifier/gender/gender.qrc b/examples/qml/classifier/gender/gender.qrc
new file mode 100644 (file)
index 0000000..7ad1f93
--- /dev/null
@@ -0,0 +1,7 @@
+<RCC>
+    <qresource prefix="/">
+        <file>gender.qml</file>
+        <file>Selector.qml</file>
+        <file>Button.qml</file>
+    </qresource>
+</RCC>
diff --git a/examples/qml/classifier/gender/main.cpp b/examples/qml/classifier/gender/main.cpp
new file mode 100644 (file)
index 0000000..8963c49
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <QtWidgets/QApplication>
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlComponent>
+#include <QtQuick/QQuickItem>
+#include <QtQuick/QQuickView>
+
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+
+    QUrl url = QUrl(QStringLiteral("qrc:/gender.qml"));
+
+    QQmlEngine engine;
+    QObject::connect(&engine, SIGNAL(quit()), &app, SLOT(quit()));
+    QQmlComponent *component = new QQmlComponent(&engine);
+    component->loadUrl(url);
+    QObject *object = component->create();
+    QQuickWindow *window = qobject_cast<QQuickWindow *>(object);
+    QQuickView *view = 0;
+    if (!window) {
+        QQuickItem *item = qobject_cast<QQuickItem *>(object);
+        if (item) {
+            view = new QQuickView(&engine, NULL);
+            window = view;
+            view->setResizeMode(QQuickView::SizeRootObjectToView);
+            view->setContent(url, component, item);
+        }
+    }
+
+    if (window) {
+        window->show();
+    }
+
+    return app.exec();
+}
diff --git a/examples/qml/qml.pro b/examples/qml/qml.pro
new file mode 100644 (file)
index 0000000..d2a4c21
--- /dev/null
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS += classifier
+
diff --git a/jubatus.pro b/jubatus.pro
new file mode 100644 (file)
index 0000000..e16f633
--- /dev/null
@@ -0,0 +1,2 @@
+load(qt_parts)
+OTHER_FILES += LICENSE README .qmake.conf sync.profile
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
new file mode 100644 (file)
index 0000000..c00d2fc
--- /dev/null
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = jubatus
diff --git a/src/imports/jubatus/jubatus.pro b/src/imports/jubatus/jubatus.pro
new file mode 100644 (file)
index 0000000..63a6899
--- /dev/null
@@ -0,0 +1,12 @@
+IMPORT_VERSION = 0.1
+
+QT = qml jubatus
+LIBS += -L$$QT.jubatus.libs
+
+CONFIG += exceptions
+
+SOURCES += main.cpp
+
+load(qml_plugin)
+
+OTHER_FILES = plugins.qmltypes qmldir
diff --git a/src/imports/jubatus/main.cpp b/src/imports/jubatus/main.cpp
new file mode 100644 (file)
index 0000000..db2fe7c
--- /dev/null
@@ -0,0 +1,148 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <QtQml/QQmlExtensionPlugin>
+#include <QtQml/qqml.h>
+
+#include <QtJubatus/QJubatusClassifier>
+
+#include <string>
+#include <vector>
+
+#include <jubatus/client.hpp>
+
+using std::make_pair;
+using std::pair;
+using std::string;
+using std::vector;
+using jubatus::classifier::datum;
+using jubatus::classifier::estimate_result;
+
+class QmlJubatusClassifier : public QJubatusClassifier
+{
+    Q_OBJECT
+    Q_PROPERTY(QString name MEMBER m_name)
+public:
+    QmlJubatusClassifier(QObject *parent = 0) : QJubatusClassifier(parent) {}
+
+    using QJubatusClassifier::train;
+    Q_INVOKABLE void train(const QVariantList &data);
+    Q_INVOKABLE void train(const QString &label, const QVariantMap &data);
+    using QJubatusClassifier::classify;
+    Q_INVOKABLE QVariantList classify(const QVariantList &data);
+    Q_INVOKABLE QVariantList classify(const QVariantMap &data);
+
+    QString m_name;
+};
+
+void QmlJubatusClassifier::train(const QVariantList &data)
+{
+    vector<pair<string, datum>> train_data;
+    foreach (const QVariant &v, data) {
+        switch (v.type()) {
+        case QVariant::List: {
+            QVariantList list = v.toList();
+            if (!list.isEmpty()) {
+                QString name = list.takeFirst().toString();
+                foreach (const QVariant &v2, list) {
+                    train_data.push_back(make_pair(name.toStdString(), convert(v2.toMap())));
+                }
+            }
+            break; }
+        default:
+            qDebug() << Q_FUNC_INFO << __LINE__ << v.type();
+            break;
+        }
+    }
+    train(m_name.toStdString(), train_data);
+}
+
+void QmlJubatusClassifier::train(const QString &label, const QVariantMap &data)
+{
+    vector<pair<string, datum>> train_data;
+    train_data.push_back(make_pair(label.toStdString(), convert(data)));
+    train(m_name.toStdString(), train_data);
+}
+
+QVariantList QmlJubatusClassifier::classify(const QVariantList &data)
+{
+    QVariantList ret;
+
+    vector<datum> test_data;
+    foreach (const QVariant &v, data) {
+        test_data.push_back(convert(v.toMap()));
+    }
+
+    vector<vector<estimate_result> > results = classify(m_name.toStdString(), test_data);
+
+    for (size_t i = 0; i < results.size(); ++i) {
+        QVariantList list;
+        for (size_t j = 0; j < results[i].size(); ++j) {
+            const estimate_result& jr = results[i][j];
+            QVariantMap qr;
+            qr.insert(QStringLiteral("label"), QString::fromStdString(jr.label));
+            qr.insert(QStringLiteral("score"), jr.score);
+            list.append(qr);
+        }
+        ret.append(QVariant(list));
+    }
+    return ret;
+}
+
+QVariantList QmlJubatusClassifier::classify(const QVariantMap &data)
+{
+    QVariantList ret;
+
+    vector<datum> test_data;
+    test_data.push_back(convert(data));
+
+    vector<vector<estimate_result> > results = classify(m_name.toStdString(), test_data);
+
+    for (size_t i = 0; i < results[0].size(); ++i) {
+        const estimate_result& jr = results[0][i];
+        QVariantMap qr;
+        qr.insert(QStringLiteral("label"), QString::fromStdString(jr.label));
+        qr.insert(QStringLiteral("score"), jr.score);
+        ret.append(qr);
+    }
+    return ret;
+}
+
+class QmlJubatusPlugin : public QQmlExtensionPlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+    virtual void registerTypes(const char *uri)
+    {
+        Q_ASSERT(QLatin1String(uri) == QLatin1String("QtJubatus"));
+        // @uri QtFluentd
+        qmlRegisterType<QmlJubatusClassifier>(uri, 0, 1, "Classifier");
+    }
+};
+
+#include "main.moc"
diff --git a/src/imports/jubatus/plugins.qmltypes b/src/imports/jubatus/plugins.qmltypes
new file mode 100644 (file)
index 0000000..d1cae24
--- /dev/null
@@ -0,0 +1,66 @@
+import QtQuick.tooling 1.1
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated with the command '/home/tasuku/org/qt-project/qt5/5.1.0-beta1/5.1.0-beta1/gcc_64/bin/qmlplugindump QtJubatus 0.1'.
+
+Module {
+    Component {
+        name: "QJubatusClassifier"
+        prototype: "QObject"
+        Property { name: "host"; type: "string" }
+        Property { name: "port"; type: "int" }
+        Property { name: "timeout"; type: "double" }
+        Signal {
+            name: "hostChanged"
+            Parameter { name: "host"; type: "string" }
+        }
+        Signal {
+            name: "portChanged"
+            Parameter { name: "port"; type: "int" }
+        }
+        Signal {
+            name: "timeoutChanged"
+            Parameter { name: "timeout"; type: "double" }
+        }
+        Method {
+            name: "setHost"
+            Parameter { name: "host"; type: "string" }
+        }
+        Method {
+            name: "setPort"
+            Parameter { name: "port"; type: "int" }
+        }
+        Method {
+            name: "setTimeout"
+            Parameter { name: "timeout"; type: "double" }
+        }
+    }
+    Component {
+        name: "QmlJubatusClassifier"
+        prototype: "QJubatusClassifier"
+        exports: ["Classifier 0.1"]
+        exportMetaObjectRevisions: [0]
+        Property { name: "name"; type: "string" }
+        Method {
+            name: "train"
+            Parameter { name: "data"; type: "QVariantList" }
+        }
+        Method {
+            name: "train"
+            Parameter { name: "label"; type: "string" }
+            Parameter { name: "data"; type: "QVariantMap" }
+        }
+        Method {
+            name: "classify"
+            type: "QVariantList"
+            Parameter { name: "data"; type: "QVariantList" }
+        }
+        Method {
+            name: "classify"
+            type: "QVariantList"
+            Parameter { name: "data"; type: "QVariantMap" }
+        }
+    }
+}
diff --git a/src/imports/jubatus/qmldir b/src/imports/jubatus/qmldir
new file mode 100644 (file)
index 0000000..7e2e4ff
--- /dev/null
@@ -0,0 +1,3 @@
+module QtJubatus
+plugin declarative_jubatus
+typeinfo plugins.qmltypes
diff --git a/src/jubatus/classifier/classifier.pri b/src/jubatus/classifier/classifier.pri
new file mode 100644 (file)
index 0000000..8732c5f
--- /dev/null
@@ -0,0 +1,8 @@
+CONFIG += exceptions
+
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+
+PUBLIC_HEADERS += $$PWD/qjubatusclassifier.h
+HEADERS += $$PUBLIC_HEADERS
+SOURCES += $$PWD/qjubatusclassifier.cpp
diff --git a/src/jubatus/classifier/qjubatusclassifier.cpp b/src/jubatus/classifier/qjubatusclassifier.cpp
new file mode 100644 (file)
index 0000000..76d331b
--- /dev/null
@@ -0,0 +1,181 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "qjubatusclassifier.h"
+
+#include <QtCore/QDebug>
+
+#include <string>
+#include <vector>
+
+#include <jubatus/client.hpp>
+
+class QJubatusClassifier::Private
+{
+public:
+    Private(QJubatusClassifier *parent);
+    ~Private();
+
+private:
+    QJubatusClassifier *q;
+
+public:
+    jubatus::classifier::client::classifier *client;
+
+    QString host;
+    int port;
+    double timeout;
+};
+
+QJubatusClassifier::Private::Private(QJubatusClassifier *parent)
+    : q(parent)
+    , client(0)
+    , host(QStringLiteral("localhost"))
+    , port(9199)
+    , timeout(1.0)
+{
+}
+
+QJubatusClassifier::Private::~Private()
+{
+    delete client;
+}
+
+QJubatusClassifier::QJubatusClassifier(QObject *parent)
+    : QObject(parent)
+    , d(new Private(this))
+{
+    connect(this, &QJubatusClassifier::destroyed, [this](){ delete d; });
+}
+
+const QString &QJubatusClassifier::host() const
+{
+    return d->host;
+}
+
+void QJubatusClassifier::setHost(const QString &host)
+{
+    if (d->host == host) return;
+    d->host = host;
+    emit hostChanged(host);
+}
+
+int QJubatusClassifier::port() const
+{
+    return d->port;
+}
+
+void QJubatusClassifier::setPort(int port)
+{
+    if (d->port == port) return;
+    d->port = port;
+    emit portChanged(port);
+}
+
+double QJubatusClassifier::timeout() const
+{
+    return d->timeout;
+}
+
+void QJubatusClassifier::setTimeout(double timeout)
+{
+    if (d->timeout == timeout) return;
+    d->timeout = timeout;
+    emit timeoutChanged(timeout);
+}
+
+jubatus::classifier::datum QJubatusClassifier::convert(const QVariantMap &data)
+{
+    jubatus::classifier::datum ret;
+
+    foreach (const QString &key, data.keys()) {
+        QVariant value = data.value(key);
+        switch (value.type()) {
+        case QVariant::String:
+            ret.string_values.push_back(make_pair(key.toStdString(), value.toString().toStdString()));
+            break;
+        case QVariant::Int:
+            ret.num_values.push_back(make_pair(key.toStdString(), value.toInt()));
+            break;
+        case QVariant::Double:
+            ret.num_values.push_back(make_pair(key.toStdString(), value.toDouble()));
+            break;
+        default:
+            qDebug() << Q_FUNC_INFO << __LINE__ << value << "not supported.";
+            break;
+        }
+    }
+
+    return ret;
+}
+
+void QJubatusClassifier::train(const QString &name, const QList<QJubatusClassifier::TrainData> &data)
+{
+    std::vector<std::pair<std::string, jubatus::classifier::datum>> train_data;
+    foreach (const TrainData &v, data) {
+        train_data.push_back(make_pair(v.first.toStdString(), convert(v.second)));
+    }
+    train(name.toStdString(), train_data);
+}
+
+void QJubatusClassifier::train(const std::string &name, const std::vector<std::pair<std::string, jubatus::classifier::datum>> &data)
+{
+    jubatus::classifier::client::classifier client(d->host.toStdString(), d->port, d->timeout);
+    client.train(name, data);
+}
+
+QList<QList<QJubatusClassifier::EstimateResult>> QJubatusClassifier::classify(const QString &name, const QList<QVariantMap> &data)
+{
+    QList<QList<EstimateResult>> ret;
+
+    std::vector<jubatus::classifier::datum> test_data;
+    foreach (const QVariant &v, data) {
+        test_data.push_back(convert(v.toMap()));
+    }
+
+    std::vector<std::vector<jubatus::classifier::estimate_result> > results = classify(name.toStdString(), test_data);
+
+    for (size_t i = 0; i < results.size(); ++i) {
+        QList<EstimateResult> list;
+        for (size_t j = 0; j < results[i].size(); ++j) {
+            const jubatus::classifier::estimate_result& jr = results[i][j];
+            EstimateResult qr;
+            qr.label = QString::fromStdString(jr.label);
+            qr.score = jr.score;
+            list.append(qr);
+        }
+        ret.append(list);
+    }
+    return ret;
+}
+
+std::vector<std::vector<jubatus::classifier::estimate_result>> QJubatusClassifier::classify(const std::string &name, const std::vector<jubatus::classifier::datum> &data)
+{
+    jubatus::classifier::client::classifier client(d->host.toStdString(), d->port, d->timeout);
+    return client.classify(name, data);
+}
+
+
diff --git a/src/jubatus/classifier/qjubatusclassifier.h b/src/jubatus/classifier/qjubatusclassifier.h
new file mode 100644 (file)
index 0000000..6e971ed
--- /dev/null
@@ -0,0 +1,85 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef QJUBATUSCLASSIFIER_H
+#define QJUBATUSCLASSIFIER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+
+#include "jubatus_global.h"
+
+namespace jubatus {
+    namespace classifier {
+        struct datum;
+        struct estimate_result;
+    }
+}
+
+class JUBATUS_EXPORT QJubatusClassifier : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
+    Q_PROPERTY(int port READ port WRITE setPort NOTIFY portChanged)
+    Q_PROPERTY(double timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged)
+public:
+    explicit QJubatusClassifier(QObject *parent = 0);
+
+    const QString &host() const;
+    int port() const;
+    double timeout() const;
+
+    struct EstimateResult {
+        QString label;
+        double score;
+    };
+
+    typedef QPair<QString, QVariantMap> TrainData;
+
+    void train(const QString &name, const QList<QJubatusClassifier::TrainData> &data);
+    QList<QList<QJubatusClassifier::EstimateResult>> classify(const QString &name, const QList<QVariantMap> &data);
+
+public slots:
+    void setHost(const QString &host);
+    void setPort(int port);
+    void setTimeout(double timeout);
+
+signals:
+    void hostChanged(const QString &host);
+    void portChanged(int port);
+    void timeoutChanged(double timeout);
+
+protected:
+    void train(const std::string &name, const std::vector<std::pair<std::string, jubatus::classifier::datum>> &data);
+    std::vector<std::vector<jubatus::classifier::estimate_result>> classify(const std::string &name, const std::vector<jubatus::classifier::datum> &data);
+    static jubatus::classifier::datum convert(const QVariantMap &data);
+
+private:
+    class Private;
+    Private *d;
+};
+
+#endif // QJUBATUSCLASSIFIER_H
diff --git a/src/jubatus/jubatus.pro b/src/jubatus/jubatus.pro
new file mode 100644 (file)
index 0000000..76323e0
--- /dev/null
@@ -0,0 +1,15 @@
+TARGET = QtJubatus
+MODULE = jubatus
+QT = core
+
+load(qt_module)
+
+CONFIG += link_pkgconfig
+PKGCONFIG += jubatus-client
+
+include(./classifier/classifier.pri)
+
+DEFINES += JUBATUS_LIBRARY
+
+HEADERS += \
+    jubatus_global.h
diff --git a/src/jubatus/jubatus_global.h b/src/jubatus/jubatus_global.h
new file mode 100644 (file)
index 0000000..249ec88
--- /dev/null
@@ -0,0 +1,36 @@
+/* Copyright (c) 2012 Silk Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Silk nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL SILK BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JUBATUS_GLOBAL_H
+#define JUBATUS_GLOBAL_H
+
+#ifdef JUBATUS_LIBRARY
+# define JUBATUS_EXPORT Q_DECL_EXPORT
+#else
+# define JUBATUS_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // JUBATUS_GLOBAL_H
diff --git a/src/src.pro b/src/src.pro
new file mode 100644 (file)
index 0000000..621b6e2
--- /dev/null
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+SUBDIRS = jubatus
+
+!isEmpty(QT.qml.name) {
+    src_imports.subdir = imports
+    src_imports.depends = jubatus
+    SUBDIRS += src_imports
+}
diff --git a/sync.profile b/sync.profile
new file mode 100644 (file)
index 0000000..6868f52
--- /dev/null
@@ -0,0 +1,13 @@
+%modules = ( # path to module name map
+    "QtJubatus" => "$basedir/src/jubatus",
+);
+
+%moduleheaders = ( # restrict the module headers to those found in relative path
+);
+
+%classnames = (
+    "qjubatusclassifier.h" => "QJubatusClassifier"
+);
+%dependencies = (
+    "qtbase" => "refs/heads/dev",
+);