summaryrefslogtreecommitdiff
path: root/fuzzylite/src/imex/RScriptExporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fuzzylite/src/imex/RScriptExporter.cpp')
-rw-r--r--fuzzylite/src/imex/RScriptExporter.cpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/fuzzylite/src/imex/RScriptExporter.cpp b/fuzzylite/src/imex/RScriptExporter.cpp
new file mode 100644
index 0000000..5fe53c7
--- /dev/null
+++ b/fuzzylite/src/imex/RScriptExporter.cpp
@@ -0,0 +1,234 @@
+/*
+ fuzzylite (R), a fuzzy logic control library in C++.
+ Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved.
+ Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com>
+
+ This file is part of fuzzylite.
+
+ fuzzylite is free software: you can redistribute it and/or modify it under
+ the terms of the FuzzyLite License included with the software.
+
+ You should have received a copy of the FuzzyLite License along with
+ fuzzylite. If not, see <http://www.fuzzylite.com/license/>.
+
+ fuzzylite is a registered trademark of FuzzyLite Limited.
+ */
+
+#include "fl/imex/RScriptExporter.h"
+
+#include "fl/Engine.h"
+#include "fl/imex/FllExporter.h"
+#include "fl/variable/InputVariable.h"
+#include "fl/variable/OutputVariable.h"
+
+#include <fstream>
+namespace fl {
+
+ RScriptExporter::RScriptExporter() : Exporter(),
+ _minimumColor("yellow"), _maximumColor("red"), _contourColor("black") { }
+
+ RScriptExporter::~RScriptExporter() { }
+
+ std::string RScriptExporter::name() const {
+ return "RScriptExporter";
+ }
+
+ void RScriptExporter::setMinimumColor(const std::string& minimumColor) {
+ this->_minimumColor = minimumColor;
+ }
+
+ std::string RScriptExporter::getMinimumColor() const {
+ return this->_minimumColor;
+ }
+
+ void RScriptExporter::setMaximumColor(const std::string& maximumColor) {
+ this->_maximumColor = maximumColor;
+ }
+
+ std::string RScriptExporter::getMaximumColor() const {
+ return _maximumColor;
+ }
+
+ void RScriptExporter::setContourColor(const std::string& contourColor) {
+ this->_contourColor = contourColor;
+ }
+
+ std::string RScriptExporter::getContourColor() const {
+ return this->_contourColor;
+ }
+
+ RScriptExporter* RScriptExporter::clone() const {
+ return new RScriptExporter(*this);
+ }
+
+ std::string RScriptExporter::toString(const Engine* engine) const {
+ if (engine->inputVariables().empty()) {
+ throw Exception("[exporter error] engine has no input variables to export the surface", FL_AT);
+ }
+ if (engine->outputVariables().empty()) {
+ throw Exception("[exporter error] engine has no output variables to export the surface", FL_AT);
+ }
+ InputVariable* a = engine->inputVariables().at(0);
+ InputVariable* b = engine->inputVariables().at(1 % engine->numberOfInputVariables());
+ return toString(const_cast<Engine*> (engine), a, b,
+ 1024, FldExporter::AllVariables, engine->outputVariables());
+ }
+
+ std::string RScriptExporter::toString(Engine* engine, InputVariable* a, InputVariable* b,
+ int values, FldExporter::ScopeOfValues scope,
+ const std::vector<OutputVariable*>& outputVariables) const {
+ std::ostringstream writer;
+ writeScriptExportingDataFrame(engine, writer, a, b, values, scope, outputVariables);
+ return writer.str();
+ }
+
+ std::string RScriptExporter::toString(Engine* engine, InputVariable* a, InputVariable* b,
+ std::istream& reader, const std::vector<OutputVariable*>& outputVariables) const {
+ std::ostringstream writer;
+ writeScriptExportingDataFrame(engine, writer, a, b, reader, outputVariables);
+ return writer.str();
+ }
+
+ void RScriptExporter::toFile(const std::string& filePath, const Engine* engine) const {
+ if (engine->inputVariables().empty()) {
+ throw Exception("[exporter error] engine has no input variables to export the surface", FL_AT);
+ }
+ if (engine->outputVariables().empty()) {
+ throw Exception("[exporter error] engine has no output variables to export the surface", FL_AT);
+ }
+ InputVariable* a = engine->inputVariables().at(0);
+ InputVariable* b = engine->inputVariables().at(1 % engine->numberOfInputVariables());
+
+ toFile(filePath, const_cast<Engine*> (engine), a, b,
+ 1024, FldExporter::AllVariables, engine->outputVariables());
+ }
+
+ void RScriptExporter::toFile(const std::string& filePath, Engine* engine,
+ InputVariable* a, InputVariable* b, int values, FldExporter::ScopeOfValues scope,
+ const std::vector<OutputVariable*>& outputVariables) const {
+ std::ofstream writer(filePath.c_str());
+ if (not writer.is_open()) {
+ throw Exception("[file error] file <" + filePath + "> could not be created", FL_AT);
+ }
+ writeScriptExportingDataFrame(engine, writer, a, b, values, scope, outputVariables);
+ writer.close();
+ }
+
+ void RScriptExporter::toFile(const std::string& filePath, Engine* engine,
+ InputVariable* a, InputVariable* b, std::istream& reader,
+ const std::vector<OutputVariable*>& outputVariables) const {
+ std::ofstream writer(filePath.c_str());
+ if (not writer.is_open()) {
+ throw Exception("[file error] file <" + filePath + "> could not be created", FL_AT);
+ }
+ writeScriptExportingDataFrame(engine, writer, a, b, reader, outputVariables);
+ writer.close();
+ }
+
+ void RScriptExporter::writeScriptImportingDataFrame(const Engine* engine, std::ostream& writer,
+ InputVariable* a, InputVariable* b, const std::string& dfPath,
+ const std::vector<OutputVariable*>& outputVariables) const {
+ writeScriptHeader(writer, engine);
+
+ writer << "engine.fldFile = \"" << dfPath << "\"\n";
+ writer << "if (require(data.table)) {\n"
+ << " engine.df = data.table::fread(engine.fldFile, sep=\"auto\", header=\"auto\")\n"
+ << "} else {\n"
+ << " engine.df = read.table(engine.fldFile, header=TRUE)\n"
+ << "}\n";
+ writer << "\n";
+
+ writeScriptPlots(writer, a, b, outputVariables);
+ }
+
+ void RScriptExporter::writeScriptExportingDataFrame(Engine* engine, std::ostream& writer,
+ InputVariable* a, InputVariable* b, int values, FldExporter::ScopeOfValues scope,
+ const std::vector<OutputVariable*>& outputVariables) const {
+ writeScriptHeader(writer, engine);
+
+ std::vector<InputVariable*> activeVariables = engine->inputVariables();
+ for (std::size_t i = 0; i < activeVariables.size(); ++i) {
+ if (activeVariables.at(i) != a and activeVariables.at(i) != b) {
+ activeVariables.at(i) = fl::null;
+ }
+ }
+ writer << "engine.fld = \"";
+ FldExporter().write(engine, writer, values, scope, activeVariables);
+ writer << "\"\n\n";
+ writer << "engine.df = read.delim(textConnection(engine.fld), header=TRUE, "
+ "sep=\" \", strip.white=TRUE)\n\n";
+
+ writeScriptPlots(writer, a, b, outputVariables);
+ }
+
+ void RScriptExporter::writeScriptExportingDataFrame(Engine* engine, std::ostream& writer,
+ InputVariable* a, InputVariable* b, std::istream& reader,
+ const std::vector<OutputVariable*>& outputVariables) const {
+ writeScriptHeader(writer, engine);
+
+ writer << "engine.fld = \"";
+ FldExporter().write(engine, writer, reader);
+ writer << "\"\n\n";
+
+ writer << "engine.df = read.delim(textConnection(engine.fld), header=TRUE, "
+ "sep=\" \", strip.white=TRUE)\n\n";
+
+ writeScriptPlots(writer, a, b, outputVariables);
+ }
+
+ void RScriptExporter::writeScriptHeader(std::ostream& writer, const Engine* engine) const {
+ writer << "#Code automatically generated with " << fuzzylite::library() << ".\n\n"
+ << "library(ggplot2);\n"
+ << "\n";
+ writer << "engine.name = \"" << engine->getName() << "\"\n";
+ if (not engine->getDescription().empty())
+ writer << "engine.description = \"" << engine->getDescription() << "\"\n";
+ writer << "engine.fll = \"" << FllExporter().toString(engine) << "\"\n\n";
+ }
+
+ void RScriptExporter::writeScriptPlots(std::ostream& writer,
+ InputVariable* a, InputVariable* b,
+ const std::vector<OutputVariable*>& outputVariables) const {
+ std::ostringstream arrangeGrob;
+ arrangeGrob << "arrangeGrob(";
+ for (std::size_t i = 0; i < outputVariables.size(); ++i) {
+ OutputVariable* z = outputVariables.at(i);
+ if (a != b) {
+ writer << "engine.plot.i1i2_o" << (i + 1) << " = ggplot(engine.df, aes(" << a->getName() << ", " << b->getName() << ")) + \n"
+ << " geom_tile(aes(fill=" << z->getName() << ")) + \n"
+ << " scale_fill_gradient(low=\"" << _minimumColor << "\", high=\"" << _maximumColor << "\") + \n"
+ << " stat_contour(aes(x=" << a->getName() << ", y=" << b->getName() << ", z=" << z->getName() << "), color=\"" << _contourColor << "\") + \n"
+ << " ggtitle(\"(" << a->getName() << ", " << b->getName() << ") = " << z->getName() << "\")\n\n";
+
+ writer << "engine.plot.i2i1_o" << (i + 1) << " = ggplot(engine.df, aes(" << b->getName() << ", " << a->getName() << ")) + \n"
+ << " geom_tile(aes(fill=" << z->getName() << ")) + \n"
+ << " scale_fill_gradient(low=\"" << _minimumColor << "\", high=\"" << _maximumColor << "\") + \n"
+ << " stat_contour(aes(x=" << b->getName() << ", y=" << a->getName() << ", z=" << z->getName() << "), color=\"" << _contourColor << "\") + \n"
+ << " ggtitle(\"(" << b->getName() << ", " << a->getName() << ") = " << z->getName() << "\")\n\n";
+ arrangeGrob << "engine.plot.i1i2_o" << (i + 1) << ", " << "engine.plot.i2i1_o" << (i + 1) << ", ";
+ } else {
+ writer << "engine.plot.i1_o" << (i + 1) << " = ggplot(engine.df, aes(" << a->getName() << ", " << z->getName() << ")) + \n"
+ << " geom_line(aes(color=" << z->getName() << "), size=3, lineend=\"round\", linejoin=\"mitre\") + \n"
+ << " scale_color_gradient(low=\"" << _minimumColor << "\", high=\"" << _maximumColor << "\") + \n"
+ << " ggtitle(\"" << a->getName() << " vs " << z->getName() << "\")\n\n";
+
+ writer << "engine.plot.o" << (i + 1) << "_i1 = ggplot(engine.df, aes(" << a->getName() << ", " << z->getName() << ")) + \n"
+ << " geom_line(aes(color=" << z->getName() << "), size=3, lineend=\"round\", linejoin=\"mitre\") + \n"
+ << " scale_color_gradient(low=\"" << _minimumColor << "\", high=\"" << _maximumColor << "\") + \n"
+ << " coord_flip() + \n"
+ << " ggtitle(\"" << z->getName() << " vs " << a->getName() << "\")\n\n";
+ arrangeGrob << "engine.plot.i1_o" << (i + 1) << ", " << "engine.plot.o" << (i + 1) << "_i1, ";
+ }
+
+ }
+ arrangeGrob << "ncol=2, top=engine.name)";
+ writer << "if (require(gridExtra)) {\n"
+ << " engine.plots = " << arrangeGrob.str() << "\n"
+ << " ggsave(paste0(engine.name, \".pdf\"), engine.plots)\n"
+ << " if (require(grid)) {\n"
+ << " grid.newpage()\n"
+ << " grid.draw(engine.plots)\n"
+ << " }\n"
+ << "}\n";
+ }
+}