<commit_before>#include <v8.h>
#include "macros.h"
#include "gc.h"

#ifdef windows
#	include <my_global.h>
#endif

#include <mysql.h>
#include <stdlib.h>
#include <string>

#define MYSQL_ERROR mysql_error(conn)
#define ASSERT_CONNECTED if (!conn) { return JS_EXCEPTION("No connection established yet."); }
#define MYSQL_PTR MYSQL * conn = LOAD_PTR(0, MYSQL *)

namespace {

v8::Persistent<v8::FunctionTemplate> rest;

void destroy(v8::Handle<v8::Object> obj) {
	v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(obj->Get(JS_STR("close")));
	fun->Call(obj, 0, NULL);
}

v8::Handle<v8::Value> createResult(MYSQL * conn) {
	MYSQL_RES * res = mysql_store_result(conn);

	if (res) {
		v8::Handle<v8::Value> resargs[] = { v8::External::New((void *) res) };
		return rest->GetFunction()->NewInstance(1, resargs);
	} else {
		if (mysql_field_count(conn)) {
			return JS_EXCEPTION(MYSQL_ERROR);
		} else {
			return JS_BOOL(true);
		}
	}
}

/**
 * MySQL constructor does basically nothing. It just adds "this.close()" method to global GC
 */
JS_METHOD(_mysql) {
	ASSERT_CONSTRUCTOR;
	SAVE_PTR(0, NULL);
	GC * gc = GC_PTR;
	gc->add(args.This(), destroy);
	return args.This();
}

/**
 * Close DB connection
 */
JS_METHOD(_close) {
	MYSQL_PTR;
	if (conn) {
		mysql_close(conn);
		SAVE_PTR(0, NULL);
	}
	return args.This();
}

/**
 * Should be called ASAP: new MySQL().connect("host", "user", "pass", "db")
 */
JS_METHOD(_connect) {
	if (args.Length() < 4) {
		return JS_EXCEPTION("Invalid call format. Use 'mysql.connect(host, user, pass, db)'");
	}

	MYSQL * conn;

	v8::String::Utf8Value host(args[0]);
	v8::String::Utf8Value user(args[1]);
	v8::String::Utf8Value pass(args[2]);
	v8::String::Utf8Value db(args[3]);

	conn = mysql_init(NULL);
	if (!mysql_real_connect(conn, *host, *user, *pass, *db, 0, NULL, CLIENT_MULTI_STATEMENTS)) {
		return JS_EXCEPTION(MYSQL_ERROR);
	} else {
		mysql_query(conn, "SET NAMES 'utf8'");
		SAVE_PTR(0, conn);
		return args.This();
	}
}

/**
 * Query takes a string argument and returns an instance of Result object
 */
JS_METHOD(_query) {
	MYSQL_PTR;
	ASSERT_CONNECTED;
	if (args.Length() < 1) {
		return JS_EXCEPTION("No query specified");
	}
	v8::String::Utf8Value q(args[0]);

	int code = mysql_real_query(conn, *q, q.length());
	if (code != 0) { return JS_EXCEPTION(MYSQL_ERROR); }

	int qc = args.This()->Get(JS_STR("queryCount"))->ToInteger()->Int32Value();
	args.This()->Set(JS_STR("queryCount"), JS_INT(qc+1));

	return createResult(conn);
}

/**
 * Fetch next result from a multi-result set
 */
JS_METHOD(_nextresult) {
	MYSQL_PTR;
	ASSERT_CONNECTED;

	int status = mysql_next_result(conn);

	if (status == -1) { return JS_NULL; }
	if (status > 0) { return JS_EXCEPTION(MYSQL_ERROR); }
	return createResult(conn);
}

JS_METHOD(_affectedrows) {
	MYSQL_PTR;
	ASSERT_CONNECTED;
	return JS_INT(mysql_affected_rows(conn));
}

JS_METHOD(_insertid) {
	MYSQL_PTR;
	ASSERT_CONNECTED;
	return JS_INT(mysql_insert_id(conn));
}

JS_METHOD(_escape) {
	MYSQL_PTR;
	ASSERT_CONNECTED;

	if (args.Length() < 1) {
		return JS_EXCEPTION("Nothing to escape");
	}
	v8::String::Utf8Value str(args[0]);

	int len = args[0]->ToString()->Utf8Length();
	char * result = new char[2*len + 1];

	int length = mysql_real_escape_string(conn, result, *str, len);
	v8::Handle<v8::Value> output = JS_STR(result, length);
	delete[] result;
	return output;
}

JS_METHOD(_qualify) {
	if (args.Length() < 1) {
		return JS_EXCEPTION("Nothing to qualify");
	}

	v8::String::Utf8Value str(args[0]);
	std::string result = "`";
	result += *str;
	result += "`";

	v8::Handle<v8::Value> output = JS_STR(result.c_str());
	return output;
}

JS_METHOD(_result) {
	SAVE_VALUE(0, args[0]);
	return args.This();
}

JS_METHOD(_numrows) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);

	return JS_INT(mysql_num_rows(res));
}

JS_METHOD(_numfields) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);

	return JS_INT(mysql_num_fields(res));
}

JS_METHOD(_fetchnames) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);

	int cnt = mysql_num_fields(res);
	MYSQL_FIELD * fields = mysql_fetch_fields(res);
	v8::Handle<v8::Array> result = v8::Array::New(cnt);

	for(int i = 0; i < cnt; i++) {
		result->Set(JS_INT(i), JS_STR(fields[i].name));
	}

	return result;
}

/**
 * Return result data as an array of JS arrays
 */
JS_METHOD(_fetcharrays) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	mysql_data_seek(res, 0);

	int x = mysql_num_fields(res);
	int y = mysql_num_rows(res);
	MYSQL_ROW row;
	v8::Handle<v8::Array> result = v8::Array::New(y);

	for (int i = 0; i < y; i++) {
		row = mysql_fetch_row(res);
		v8::Handle<v8::Array> item = v8::Array::New(x);
		result->Set(JS_INT(i), item);
		for (int j=0; j<x; j++) {
			if (row[j] == NULL) {
				item->Set(JS_INT(j), v8::Null());
			} else {
				item->Set(JS_INT(j), JS_STR(row[j]));
			}
		}
	}

	return result;
}

/**
 * Return result data as an array of JS objects, indexed with column names
 */
JS_METHOD(_fetchobjects) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	mysql_data_seek(res, 0);

	int x = mysql_num_fields(res);
	int y = mysql_num_rows(res);
	MYSQL_FIELD * fields = mysql_fetch_fields(res);
	MYSQL_ROW row;
	v8::Handle<v8::Array> result = v8::Array::New(y);

	for (int i = 0; i < y; i++) {
		row = mysql_fetch_row(res);
		v8::Handle<v8::Object> item = v8::Object::New();
		result->Set(JS_INT(i), item);
		for (int j=0; j<x; j++) {
			if (row[j] == NULL) {
				item->Set(JS_STR(fields[j].name), v8::Null());
			} else {
				item->Set(JS_STR(fields[j].name), JS_STR(row[j]));
			}
		}
	}

	return result;
}

JS_METHOD(_result_close) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	if (res) {
		mysql_free_result(res);
		SAVE_PTR(0, NULL);
		return JS_BOOL(true);
	} else {
		return JS_BOOL(false);
	}
}

} /* end namespace */

SHARED_INIT() {
	v8::HandleScope handle_scope;
	v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(_mysql);
	ft->SetClassName(JS_STR("MySQL"));

	v8::Handle<v8::ObjectTemplate> ot = ft->InstanceTemplate();
	ot->SetInternalFieldCount(1); /* connection */

	/**
	 * Static property, useful for stats gathering
	 */
	ot->Set(JS_STR("queryCount"), JS_INT(0));

	v8::Handle<v8::ObjectTemplate> pt = ft->PrototypeTemplate();

	/**
	 * MySQL prototype methods (new MySQL().*)
	 */
	pt->Set(JS_STR("connect"), v8::FunctionTemplate::New(_connect));
	pt->Set(JS_STR("close"), v8::FunctionTemplate::New(_close));
	pt->Set(JS_STR("query"), v8::FunctionTemplate::New(_query));
	pt->Set(JS_STR("nextResult"), v8::FunctionTemplate::New(_nextresult));
	pt->Set(JS_STR("affectedRows"), v8::FunctionTemplate::New(_affectedrows));
	pt->Set(JS_STR("escape"), v8::FunctionTemplate::New(_escape));
	pt->Set(JS_STR("qualify"), v8::FunctionTemplate::New(_qualify));
	pt->Set(JS_STR("insertId"), v8::FunctionTemplate::New(_insertid));

	rest = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(_result));
	rest->SetClassName(JS_STR("Result"));

	v8::Handle<v8::ObjectTemplate> resinst = rest->InstanceTemplate();
	resinst->SetInternalFieldCount(1);

	v8::Handle<v8::ObjectTemplate> resproto = rest->PrototypeTemplate();

	/**
	 * Result prototype methods (new MySQL().query().*)
	 */
	resproto->Set(JS_STR("numRows"), v8::FunctionTemplate::New(_numrows));
	resproto->Set(JS_STR("numFields"), v8::FunctionTemplate::New(_numfields));
	resproto->Set(JS_STR("fetchNames"), v8::FunctionTemplate::New(_fetchnames));
	resproto->Set(JS_STR("fetchArrays"), v8::FunctionTemplate::New(_fetcharrays));
	resproto->Set(JS_STR("fetchObjects"), v8::FunctionTemplate::New(_fetchobjects));
	resproto->Set(JS_STR("close"), v8::FunctionTemplate::New(_result_close));

	exports->Set(JS_STR("MySQL"), ft->GetFunction());
}
<commit_msg>proper resultset close on gc in mysql<commit_after>#include <v8.h>
#include "macros.h"
#include "gc.h"

#ifdef windows
#	include <my_global.h>
#endif

#include <mysql.h>
#include <stdlib.h>
#include <string>

#define MYSQL_ERROR mysql_error(conn)
#define ASSERT_CONNECTED if (!conn) { return JS_EXCEPTION("No connection established yet."); }
#define ASSERT_RESULT if (!res) { return JS_EXCEPTION("Result set already closed."); }
#define MYSQL_PTR MYSQL * conn = LOAD_PTR(0, MYSQL *)

namespace {

v8::Persistent<v8::FunctionTemplate> rest;

void finalize(v8::Handle<v8::Object> obj) {
	v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(obj->Get(JS_STR("close")));
	fun->Call(obj, 0, NULL);
}

void result_finalize(v8::Handle<v8::Object> obj) {
	v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(obj->Get(JS_STR("close")));
	fun->Call(obj, 0, NULL);
}

v8::Handle<v8::Value> createResult(MYSQL * conn) {
	MYSQL_RES * res = mysql_store_result(conn);

	if (res) {
		v8::Handle<v8::Value> resargs[] = { v8::External::New((void *) res) };
		return rest->GetFunction()->NewInstance(1, resargs);
	} else {
		if (mysql_field_count(conn)) {
			return JS_EXCEPTION(MYSQL_ERROR);
		} else {
			return JS_BOOL(true);
		}
	}
}

/**
 * MySQL constructor does basically nothing. It just adds "this.close()" method to global GC
 */
JS_METHOD(_mysql) {
	ASSERT_CONSTRUCTOR;
	SAVE_PTR(0, NULL);
	GC * gc = GC_PTR;
	gc->add(args.This(), finalize);
	return args.This();
}

/**
 * Close DB connection
 */
JS_METHOD(_close) {
	MYSQL_PTR;
	if (conn) {
		mysql_close(conn);
		SAVE_PTR(0, NULL);
	}
	return args.This();
}

/**
 * Should be called ASAP: new MySQL().connect("host", "user", "pass", "db")
 */
JS_METHOD(_connect) {
	if (args.Length() < 4) {
		return JS_EXCEPTION("Invalid call format. Use 'mysql.connect(host, user, pass, db)'");
	}

	MYSQL * conn;

	v8::String::Utf8Value host(args[0]);
	v8::String::Utf8Value user(args[1]);
	v8::String::Utf8Value pass(args[2]);
	v8::String::Utf8Value db(args[3]);

	conn = mysql_init(NULL);
	if (!mysql_real_connect(conn, *host, *user, *pass, *db, 0, NULL, CLIENT_MULTI_STATEMENTS)) {
		return JS_EXCEPTION(MYSQL_ERROR);
	} else {
		mysql_query(conn, "SET NAMES 'utf8'");
		SAVE_PTR(0, conn);
		return args.This();
	}
}

/**
 * Query takes a string argument and returns an instance of Result object
 */
JS_METHOD(_query) {
	MYSQL_PTR;
	ASSERT_CONNECTED;
	if (args.Length() < 1) {
		return JS_EXCEPTION("No query specified");
	}
	v8::String::Utf8Value q(args[0]);

	int code = mysql_real_query(conn, *q, q.length());
	if (code != 0) { return JS_EXCEPTION(MYSQL_ERROR); }

	int qc = args.This()->Get(JS_STR("queryCount"))->ToInteger()->Int32Value();
	args.This()->Set(JS_STR("queryCount"), JS_INT(qc+1));

	return createResult(conn);
}

/**
 * Fetch next result from a multi-result set
 */
JS_METHOD(_nextresult) {
	MYSQL_PTR;
	ASSERT_CONNECTED;

	int status = mysql_next_result(conn);

	if (status == -1) { return JS_NULL; }
	if (status > 0) { return JS_EXCEPTION(MYSQL_ERROR); }
	return createResult(conn);
}

JS_METHOD(_affectedrows) {
	MYSQL_PTR;
	ASSERT_CONNECTED;
	return JS_INT(mysql_affected_rows(conn));
}

JS_METHOD(_insertid) {
	MYSQL_PTR;
	ASSERT_CONNECTED;
	return JS_INT(mysql_insert_id(conn));
}

JS_METHOD(_escape) {
	MYSQL_PTR;
	ASSERT_CONNECTED;

	if (args.Length() < 1) {
		return JS_EXCEPTION("Nothing to escape");
	}
	v8::String::Utf8Value str(args[0]);

	int len = args[0]->ToString()->Utf8Length();
	char * result = new char[2*len + 1];

	int length = mysql_real_escape_string(conn, result, *str, len);
	v8::Handle<v8::Value> output = JS_STR(result, length);
	delete[] result;
	return output;
}

JS_METHOD(_qualify) {
	if (args.Length() < 1) {
		return JS_EXCEPTION("Nothing to qualify");
	}

	v8::String::Utf8Value str(args[0]);
	std::string result = "`";
	result += *str;
	result += "`";

	v8::Handle<v8::Value> output = JS_STR(result.c_str());
	return output;
}

JS_METHOD(_result) {
	SAVE_VALUE(0, args[0]);

	GC * gc = GC_PTR;
	gc->add(args.This(), result_finalize);

	return args.This();
}

JS_METHOD(_numrows) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	ASSERT_RESULT;

	return JS_INT(mysql_num_rows(res));
}

JS_METHOD(_numfields) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	ASSERT_RESULT;

	return JS_INT(mysql_num_fields(res));
}

JS_METHOD(_fetchnames) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	ASSERT_RESULT;

	int cnt = mysql_num_fields(res);
	MYSQL_FIELD * fields = mysql_fetch_fields(res);
	v8::Handle<v8::Array> result = v8::Array::New(cnt);

	for(int i = 0; i < cnt; i++) {
		result->Set(JS_INT(i), JS_STR(fields[i].name));
	}

	return result;
}

/**
 * Return result data as an array of JS arrays
 */
JS_METHOD(_fetcharrays) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	ASSERT_RESULT;
	mysql_data_seek(res, 0);

	int x = mysql_num_fields(res);
	int y = mysql_num_rows(res);
	MYSQL_ROW row;
	v8::Handle<v8::Array> result = v8::Array::New(y);

	for (int i = 0; i < y; i++) {
		row = mysql_fetch_row(res);
		v8::Handle<v8::Array> item = v8::Array::New(x);
		result->Set(JS_INT(i), item);
		for (int j=0; j<x; j++) {
			if (row[j] == NULL) {
				item->Set(JS_INT(j), v8::Null());
			} else {
				item->Set(JS_INT(j), JS_STR(row[j]));
			}
		}
	}

	return result;
}

/**
 * Return result data as an array of JS objects, indexed with column names
 */
JS_METHOD(_fetchobjects) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	ASSERT_RESULT;
	mysql_data_seek(res, 0);

	int x = mysql_num_fields(res);
	int y = mysql_num_rows(res);
	MYSQL_FIELD * fields = mysql_fetch_fields(res);
	MYSQL_ROW row;
	v8::Handle<v8::Array> result = v8::Array::New(y);

	for (int i = 0; i < y; i++) {
		row = mysql_fetch_row(res);
		v8::Handle<v8::Object> item = v8::Object::New();
		result->Set(JS_INT(i), item);
		for (int j=0; j<x; j++) {
			if (row[j] == NULL) {
				item->Set(JS_STR(fields[j].name), v8::Null());
			} else {
				item->Set(JS_STR(fields[j].name), JS_STR(row[j]));
			}
		}
	}

	return result;
}

JS_METHOD(_result_close) {
	MYSQL_RES * res = LOAD_PTR(0, MYSQL_RES *);
	if (res) {
		mysql_free_result(res);
		SAVE_PTR(0, NULL);
		return JS_BOOL(true);
	} else {
		return JS_BOOL(false);
	}
}

} /* end namespace */

SHARED_INIT() {
	v8::HandleScope handle_scope;
	v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(_mysql);
	ft->SetClassName(JS_STR("MySQL"));

	v8::Handle<v8::ObjectTemplate> ot = ft->InstanceTemplate();
	ot->SetInternalFieldCount(1); /* connection */

	/**
	 * Static property, useful for stats gathering
	 */
	ot->Set(JS_STR("queryCount"), JS_INT(0));

	v8::Handle<v8::ObjectTemplate> pt = ft->PrototypeTemplate();

	/**
	 * MySQL prototype methods (new MySQL().*)
	 */
	pt->Set(JS_STR("connect"), v8::FunctionTemplate::New(_connect));
	pt->Set(JS_STR("close"), v8::FunctionTemplate::New(_close));
	pt->Set(JS_STR("query"), v8::FunctionTemplate::New(_query));
	pt->Set(JS_STR("nextResult"), v8::FunctionTemplate::New(_nextresult));
	pt->Set(JS_STR("affectedRows"), v8::FunctionTemplate::New(_affectedrows));
	pt->Set(JS_STR("escape"), v8::FunctionTemplate::New(_escape));
	pt->Set(JS_STR("qualify"), v8::FunctionTemplate::New(_qualify));
	pt->Set(JS_STR("insertId"), v8::FunctionTemplate::New(_insertid));

	rest = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(_result));
	rest->SetClassName(JS_STR("Result"));

	v8::Handle<v8::ObjectTemplate> resinst = rest->InstanceTemplate();
	resinst->SetInternalFieldCount(1);

	v8::Handle<v8::ObjectTemplate> resproto = rest->PrototypeTemplate();

	/**
	 * Result prototype methods (new MySQL().query().*)
	 */
	resproto->Set(JS_STR("numRows"), v8::FunctionTemplate::New(_numrows));
	resproto->Set(JS_STR("numFields"), v8::FunctionTemplate::New(_numfields));
	resproto->Set(JS_STR("fetchNames"), v8::FunctionTemplate::New(_fetchnames));
	resproto->Set(JS_STR("fetchArrays"), v8::FunctionTemplate::New(_fetcharrays));
	resproto->Set(JS_STR("fetchObjects"), v8::FunctionTemplate::New(_fetchobjects));
	resproto->Set(JS_STR("close"), v8::FunctionTemplate::New(_result_close));

	exports->Set(JS_STR("MySQL"), ft->GetFunction());
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdarg>
#include <cerrno>
#include <vector>
#include <map>
#include <string>

#include "riscv-types.h"
#include "riscv-endian.h"
#include "riscv-regs.h"
#include "riscv-processor.h"
#include "riscv-format.h"
#include "riscv-opcodes.h"
#include "riscv-util.h"
#include "riscv-imm.h"
#include "riscv-decode.h"
#include "riscv-decode-switch.h"
#include "riscv-csr.h"
#include "riscv-compression.h"
#include "riscv-disasm.h"
#include "riscv-elf.h"
#include "riscv-elf-file.h"
#include "riscv-elf-format.h"

void decode_rv64(riscv_ptr start, riscv_ptr end, riscv_ptr pc_offset)
{
	riscv_decode dec;
	riscv_proc_state proc = { 0 };
	proc.p_type = riscv_proc_type_rv64i;
	proc.pc = start;
	while (proc.pc < end) {
		riscv_ptr pc = proc.pc;
		riscv_decode_instruction(dec, &proc);
		riscv_disasm_instruction(dec, &proc, pc, pc_offset);
	}
}

int main(int argc, char *argv[])
{
	if (argc != 2) panic("usage: %s <elf_file>", argv[0]);
	elf_file elf(argv[1]);
	elf_print_info(elf);
	for (size_t i = 0; i < elf.shdrs.size(); i++) {
		Elf64_Shdr &shdr = elf.shdrs[i];
		if (shdr.sh_flags & SHF_EXECINSTR) {
			printf("Section[%2lu] %s\n", i, elf_shdr_name(elf, i));
			decode_rv64(elf.buf.data() + shdr.sh_offset,
				elf.buf.data() + shdr.sh_offset + shdr.sh_size,
				elf.buf.data() + shdr.sh_offset - shdr.sh_addr);
			printf("\n");
		}
	}
	return 0;
}
<commit_msg>Remove redundant local variable<commit_after>#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdarg>
#include <cerrno>
#include <vector>
#include <map>
#include <string>

#include "riscv-types.h"
#include "riscv-endian.h"
#include "riscv-regs.h"
#include "riscv-processor.h"
#include "riscv-format.h"
#include "riscv-opcodes.h"
#include "riscv-util.h"
#include "riscv-imm.h"
#include "riscv-decode.h"
#include "riscv-decode-switch.h"
#include "riscv-csr.h"
#include "riscv-compression.h"
#include "riscv-disasm.h"
#include "riscv-elf.h"
#include "riscv-elf-file.h"
#include "riscv-elf-format.h"

void decode_rv64(riscv_ptr start, riscv_ptr end, riscv_ptr pc_offset)
{
	riscv_decode dec;
	riscv_proc_state proc = { 0 };
	proc.p_type = riscv_proc_type_rv64i;
	proc.pc = start;
	while (proc.pc < end) {
		riscv_decode_instruction(dec, &proc);
		riscv_disasm_instruction(dec, &proc, proc.pc, pc_offset);
	}
}

int main(int argc, char *argv[])
{
	if (argc != 2) panic("usage: %s <elf_file>", argv[0]);
	elf_file elf(argv[1]);
	elf_print_info(elf);
	for (size_t i = 0; i < elf.shdrs.size(); i++) {
		Elf64_Shdr &shdr = elf.shdrs[i];
		if (shdr.sh_flags & SHF_EXECINSTR) {
			printf("Section[%2lu] %s\n", i, elf_shdr_name(elf, i));
			decode_rv64(elf.buf.data() + shdr.sh_offset,
				elf.buf.data() + shdr.sh_offset + shdr.sh_size,
				elf.buf.data() + shdr.sh_offset - shdr.sh_addr);
			printf("\n");
		}
	}
	return 0;
}
<|endoftext|>


<commit_before><commit_msg>Refactoring<commit_after><|endoftext|>


<commit_before>#include "libnanocv/nanocv.h"
#include "libnanocv/tasks/task_synthetic_shapes.h"
#include "libnanocv/util/thread.h"
#include "libnanocv/util/measure.hpp"
#include "libnanocv/util/tabulator.h"
#include "libnanocv/trainers/batch.h"
#include "libnanocv/trainers/minibatch.h"
#include "libnanocv/trainers/stochastic.h"

using namespace ncv;

template
<
        typename ttrainer
>
void test_optimizer(model_t& model, ttrainer trainer, const string_t& name, tabulator_t& table)
{
        const size_t cmd_trials = 16;

        stats_t<scalar_t> tvalues;
        stats_t<scalar_t> vvalues;
        stats_t<scalar_t> terrors;
        stats_t<scalar_t> verrors;

        log_info() << "<<< running " << name << " ...";

        const size_t usec = ncv::measure_robustly_usec([&] ()
        {
                model.random_params();

                const trainer_result_t result = trainer();

                tvalues(result.m_opt_state.m_tvalue);
                vvalues(result.m_opt_state.m_vvalue);

                terrors(result.m_opt_state.m_terror_avg);
                verrors(result.m_opt_state.m_verror_avg);
        }, cmd_trials);

        table.append(name)
                << tvalues.avg() << terrors.avg() << vvalues.avg() << verrors.avg()
                << (usec / 1000);
}

void test_optimizers(
        const task_t& task, model_t& model, const sampler_t& tsampler, const sampler_t& vsampler,
        const loss_t& loss, const string_t& criterion,
        const string_t& config_name)
{
        const size_t cmd_iterations = 32;
        const size_t cmd_epochs = cmd_iterations;
        const scalar_t cmd_epsilon = 1e-4;
        const bool verbose = false;

        // batch optimizers
        const auto batch_optimizers =
        {
                batch_optimizer::GD,
                batch_optimizer::CGD,
                batch_optimizer::CGD_CD,
                batch_optimizer::CGD_DY,
                batch_optimizer::CGD_FR,
                batch_optimizer::CGD_HS,
                batch_optimizer::CGD_LS,
                batch_optimizer::CGD_N,
                batch_optimizer::CGD_PR,
                batch_optimizer::LBFGS
        };

        // minibatch optimizers
        const auto minibatch_optimizers =
        {
                batch_optimizer::GD,
                batch_optimizer::CGD,
                batch_optimizer::CGD_CD,
                batch_optimizer::CGD_DY,
                batch_optimizer::CGD_FR,
                batch_optimizer::CGD_HS,
                batch_optimizer::CGD_LS,
                batch_optimizer::CGD_N,
                batch_optimizer::CGD_PR,
                batch_optimizer::LBFGS
        };

        // stochastic optimizers
        const auto stochastic_optimizers =
        {
                stochastic_optimizer::SG,
                stochastic_optimizer::SGA,
                stochastic_optimizer::SIA,
                stochastic_optimizer::AG,
                stochastic_optimizer::ADAGRAD,
                stochastic_optimizer::ADADELTA
        };

        // run optimizers and collect results
        tabulator_t table("optimizer\\");
        table.header() << "train loss" << "train error" << "valid loss" << "valid error" << "time [msec]";

        for (batch_optimizer optimizer : batch_optimizers)
        {
                test_optimizer(model, [&] ()
                {
                        return ncv::batch_train(
                                model, task, tsampler, vsampler, ncv::n_threads(),
                                loss, criterion, optimizer, cmd_iterations, cmd_epsilon, verbose);
                }, "batch [" + text::to_string(optimizer) + "]", table);
        }

        for (batch_optimizer optimizer : minibatch_optimizers)
        {
                test_optimizer(model, [&] ()
                {
                        return ncv::minibatch_train(
                                model, task, tsampler, vsampler, ncv::n_threads(),
                                loss, criterion, optimizer, cmd_epochs, cmd_epsilon, verbose);
                }, "minibatch [" + text::to_string(optimizer) + "]", table);
        }

        for (stochastic_optimizer optimizer : stochastic_optimizers)
        {
                test_optimizer(model, [&] ()
                {
                        return ncv::stochastic_train(
                                model, task, tsampler, vsampler, ncv::n_threads(),
                                loss, criterion, optimizer, cmd_epochs, verbose);
                }, "stochastic [" + text::to_string(optimizer) + "]", table);
        }

        table.print(std::cout);
}

int main(int argc, char *argv[])
{
        ncv::init();

        const size_t cmd_samples = 8 * 1024;
        const size_t cmd_rows = 16;
        const size_t cmd_cols = 16;
        const size_t cmd_outputs = 9;

        // create task
        synthetic_shapes_task_t task(
                "rows=" + text::to_string(cmd_rows) + "," +
                "cols=" + text::to_string(cmd_cols) + "," +
                "color=luma" + "," +
                "dims=" + text::to_string(cmd_outputs) + "," +
                "size=" + text::to_string(cmd_samples));
        task.load("");
	task.describe();

        // create training & validation samples
        sampler_t tsampler(task);
        tsampler.setup(sampler_t::atype::annotated);

        sampler_t vsampler(task);
        tsampler.split(80, vsampler);

        // construct models
        const string_t lmodel0;
        const string_t lmodel1 = lmodel0 + "linear:dims=16;act-snorm;";
        const string_t lmodel2 = lmodel1 + "linear:dims=16;act-snorm;";
        const string_t lmodel3 = lmodel2 + "linear:dims=16;act-snorm;";

        string_t cmodel;
        cmodel = cmodel + "conv:dims=8,rows=5,cols=5;pool-max;act-snorm;";
        cmodel = cmodel + "conv:dims=8,rows=3,cols=3;act-snorm;";

        const string_t outlayer = "linear:dims=" + text::to_string(cmd_outputs) + ";";

        strings_t cmd_networks =
        {
                lmodel0 + outlayer,
                lmodel1 + outlayer,
                lmodel2 + outlayer,
                lmodel3 + outlayer,

                cmodel + outlayer
        };

        const strings_t cmd_losses = { "classnll", "logistic" }; //loss_manager_t::instance().ids();
        const strings_t cmd_criteria = { "avg" }; //criterion_manager_t::instance().ids();

        // vary the model
        for (const string_t& cmd_network : cmd_networks)
        {
                log_info() << "<<< running network [" << cmd_network << "] ...";

                const rmodel_t model = model_manager_t::instance().get("forward-network", cmd_network);
                assert(model);
                model->resize(task, true);

                // vary the loss
                for (const string_t& cmd_loss : cmd_losses)
                {
                        log_info() << "<<< running loss [" << cmd_loss << "] ...";

                        const rloss_t loss = loss_manager_t::instance().get(cmd_loss);
                        assert(loss);

                        // vary the criteria
                        for (const string_t& cmd_criterion : cmd_criteria)
                        {
                                log_info() << "<<< running criterion [" << cmd_criterion << "] ...";

                                test_optimizers(task, *model, tsampler, vsampler, *loss, cmd_criterion,
                                                "loss [" + cmd_loss + "], criterion [" + cmd_criterion + "]");
                        }
                }

                log_info();
        }

        // OK
        log_info() << done;
        return EXIT_SUCCESS;
}
<commit_msg>explicit color mode<commit_after>#include "libnanocv/nanocv.h"
#include "libnanocv/tasks/task_synthetic_shapes.h"
#include "libnanocv/util/thread.h"
#include "libnanocv/util/measure.hpp"
#include "libnanocv/util/tabulator.h"
#include "libnanocv/trainers/batch.h"
#include "libnanocv/trainers/minibatch.h"
#include "libnanocv/trainers/stochastic.h"

using namespace ncv;

template
<
        typename ttrainer
>
void test_optimizer(model_t& model, ttrainer trainer, const string_t& name, tabulator_t& table)
{
        const size_t cmd_trials = 16;

        stats_t<scalar_t> tvalues;
        stats_t<scalar_t> vvalues;
        stats_t<scalar_t> terrors;
        stats_t<scalar_t> verrors;

        log_info() << "<<< running " << name << " ...";

        const size_t usec = ncv::measure_robustly_usec([&] ()
        {
                model.random_params();

                const trainer_result_t result = trainer();

                tvalues(result.m_opt_state.m_tvalue);
                vvalues(result.m_opt_state.m_vvalue);

                terrors(result.m_opt_state.m_terror_avg);
                verrors(result.m_opt_state.m_verror_avg);
        }, cmd_trials);

        table.append(name)
                << tvalues.avg() << terrors.avg() << vvalues.avg() << verrors.avg()
                << (usec / 1000);
}

void test_optimizers(
        const task_t& task, model_t& model, const sampler_t& tsampler, const sampler_t& vsampler,
        const loss_t& loss, const string_t& criterion,
        const string_t& config_name)
{
        const size_t cmd_iterations = 32;
        const size_t cmd_epochs = cmd_iterations;
        const scalar_t cmd_epsilon = 1e-4;
        const bool verbose = false;

        // batch optimizers
        const auto batch_optimizers =
        {
                batch_optimizer::GD,
                batch_optimizer::CGD,
                batch_optimizer::CGD_CD,
                batch_optimizer::CGD_DY,
                batch_optimizer::CGD_FR,
                batch_optimizer::CGD_HS,
                batch_optimizer::CGD_LS,
                batch_optimizer::CGD_N,
                batch_optimizer::CGD_PR,
                batch_optimizer::LBFGS
        };

        // minibatch optimizers
        const auto minibatch_optimizers =
        {
                batch_optimizer::GD,
                batch_optimizer::CGD,
                batch_optimizer::CGD_CD,
                batch_optimizer::CGD_DY,
                batch_optimizer::CGD_FR,
                batch_optimizer::CGD_HS,
                batch_optimizer::CGD_LS,
                batch_optimizer::CGD_N,
                batch_optimizer::CGD_PR,
                batch_optimizer::LBFGS
        };

        // stochastic optimizers
        const auto stochastic_optimizers =
        {
                stochastic_optimizer::SG,
                stochastic_optimizer::SGA,
                stochastic_optimizer::SIA,
                stochastic_optimizer::AG,
                stochastic_optimizer::ADAGRAD,
                stochastic_optimizer::ADADELTA
        };

        // run optimizers and collect results
        tabulator_t table("optimizer\\");
        table.header() << "train loss" << "train error" << "valid loss" << "valid error" << "time [msec]";

        for (batch_optimizer optimizer : batch_optimizers)
        {
                test_optimizer(model, [&] ()
                {
                        return ncv::batch_train(
                                model, task, tsampler, vsampler, ncv::n_threads(),
                                loss, criterion, optimizer, cmd_iterations, cmd_epsilon, verbose);
                }, "batch [" + text::to_string(optimizer) + "]", table);
        }

        for (batch_optimizer optimizer : minibatch_optimizers)
        {
                test_optimizer(model, [&] ()
                {
                        return ncv::minibatch_train(
                                model, task, tsampler, vsampler, ncv::n_threads(),
                                loss, criterion, optimizer, cmd_epochs, cmd_epsilon, verbose);
                }, "minibatch [" + text::to_string(optimizer) + "]", table);
        }

        for (stochastic_optimizer optimizer : stochastic_optimizers)
        {
                test_optimizer(model, [&] ()
                {
                        return ncv::stochastic_train(
                                model, task, tsampler, vsampler, ncv::n_threads(),
                                loss, criterion, optimizer, cmd_epochs, verbose);
                }, "stochastic [" + text::to_string(optimizer) + "]", table);
        }

        table.print(std::cout);
}

int main(int argc, char *argv[])
{
        ncv::init();

        const size_t cmd_samples = 8 * 1024;
        const size_t cmd_rows = 16;
        const size_t cmd_cols = 16;
        const size_t cmd_outputs = 9;
        const color_mode cmd_color = color_mode::rgba;

        // create task
        synthetic_shapes_task_t task(
                "rows=" + text::to_string(cmd_rows) + "," +
                "cols=" + text::to_string(cmd_cols) + "," +
                "color=" + text::to_string(cmd_color) + "," +
                "dims=" + text::to_string(cmd_outputs) + "," +
                "size=" + text::to_string(cmd_samples));
        task.load("");
	task.describe();

        // create training & validation samples
        sampler_t tsampler(task);
        tsampler.setup(sampler_t::atype::annotated);

        sampler_t vsampler(task);
        tsampler.split(80, vsampler);

        // construct models
        const string_t lmodel0;
        const string_t lmodel1 = lmodel0 + "linear:dims=16;act-snorm;";
        const string_t lmodel2 = lmodel1 + "linear:dims=16;act-snorm;";
        const string_t lmodel3 = lmodel2 + "linear:dims=16;act-snorm;";

        string_t cmodel;
        cmodel = cmodel + "conv:dims=8,rows=5,cols=5;pool-max;act-snorm;";
        cmodel = cmodel + "conv:dims=8,rows=3,cols=3;act-snorm;";

        const string_t outlayer = "linear:dims=" + text::to_string(cmd_outputs) + ";";

        strings_t cmd_networks =
        {
                lmodel0 + outlayer,
                lmodel1 + outlayer,
                lmodel2 + outlayer,
                lmodel3 + outlayer,

                cmodel + outlayer
        };

        const strings_t cmd_losses = { "classnll", "logistic" }; //loss_manager_t::instance().ids();
        const strings_t cmd_criteria = { "avg" }; //criterion_manager_t::instance().ids();

        // vary the model
        for (const string_t& cmd_network : cmd_networks)
        {
                log_info() << "<<< running network [" << cmd_network << "] ...";

                const rmodel_t model = model_manager_t::instance().get("forward-network", cmd_network);
                assert(model);
                model->resize(task, true);

                // vary the loss
                for (const string_t& cmd_loss : cmd_losses)
                {
                        log_info() << "<<< running loss [" << cmd_loss << "] ...";

                        const rloss_t loss = loss_manager_t::instance().get(cmd_loss);
                        assert(loss);

                        // vary the criteria
                        for (const string_t& cmd_criterion : cmd_criteria)
                        {
                                log_info() << "<<< running criterion [" << cmd_criterion << "] ...";

                                test_optimizers(task, *model, tsampler, vsampler, *loss, cmd_criterion,
                                                "loss [" + cmd_loss + "], criterion [" + cmd_criterion + "]");
                        }
                }

                log_info();
        }

        // OK
        log_info() << done;
        return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <algorithm>
#include <vector>
using namespace std;

//TODO object oriented SAT solver? performance issues? readability? maintainability? extensibility?

#define UNDEFINED -1
#define TRUE 1
#define FALSE 0
#define DECISION_MARK 0

/* Global problem "sizes" */
uint numVariables;
uint numClauses;

/* Clauses and related data structures */
vector<vector<int> > clauses;
vector<vector<int> > positiveClauses;
vector<vector<int> > negativeClauses;

/* Model & backtrack stack */
vector<int> model;
vector<int> modelStack;
uint indexOfNextLitToPropagate;
uint decisionLevel;

/* Heuristic related variables */
vector<double> activity; //TODO would it be better to store activity for each literal? (instead of each variable) i.e., positive vs negative appearances
double activityIncrement;
int conflicts;
int activityIncrementUpdateRate = 10; //TODO is this strategy right? which value is best suited?

/* Statistics */
uint propagations;
uint decisions;

/**
 * Returns the variable that this literal represents
 */
inline uint var(int literal) {
	return abs(literal);
}

/**
 * Reads the input problem file from the stdin stream and initializes
 * any remaining necessary data structures and variables.
 */
void initializeWithParsedInput() {
	// Skip comments
	char c = cin.get();
	while (c == 'c') {
		while (c != '\n')
			c = cin.get();
		c = cin.get();
	}

	// Read "cnf numVars numClauses"
	string aux;
	cin >> aux >> numVariables >> numClauses;
	clauses.resize(numClauses);

	// Initialize positive and negative appearances
	positiveClauses.resize(numVariables + 1);
	negativeClauses.resize(numVariables + 1);

	// Read clauses
	for (uint clause = 0; clause < numClauses; ++clause) {
		int literal;
		while (cin >> literal and literal != 0) {
			// add to the list of clauses
			clauses[clause].push_back(literal);

			// add to the list of positive-negative literals
			if (literal > 0) {
				positiveClauses[var(literal)].push_back(clause);
			}
			else {
				negativeClauses[var(literal)].push_back(clause);
			}
		}
	}

	// Initialize the remaining necessary variables
		// model and backtrack stack
	model.resize(numVariables + 1, UNDEFINED);
	indexOfNextLitToPropagate = 0;
	decisionLevel = 0;
		// heuristic
	activity.resize(numVariables + 1, 0.0);
	activityIncrement = 1.0;
	conflicts = 0;
		// statistics
	propagations = 0;
	decisions = 0;
}

/**
 * TODO comment
 */
int valueForLiteral(int literal) {
//TODO could this be faster? there is a lot of if-else branching here!
	if (literal >= 0) {
		return model[literal];
	}
	else {
		if (model[-literal] == UNDEFINED) {
			return UNDEFINED;
		}
		else {
			return 1 - model[-literal];
		}
	}
}

/**
 * The current interpretation (model) is updated with the appropriate value
 * that will make the passed literal become true in the clause where it appeared.
 * The model stack is also increased, pushing the new value on top.
 *
 * @param literal the literal that will become true after the model update
 */
void setLiteralToTrue(int literal) {
	modelStack.push_back(literal);
	if (literal > 0) {
		model[literal] = TRUE;
	}
	else {
		model[-literal] = FALSE;
	}
}

/**
 * Updates the activity counter of the given literal. The activity increment
 * applied is also updated, in order to give more importance to recent activity.
 *
 * @param literal the literal which activity is to be updated
 */
void updateActivityForLiteral(int literal) {
	//cout << "CONFLICT for literal: " << literal << endl;
	//update the activity increment if necessary (every X conflicts)
	++conflicts;
	if ((conflicts % activityIncrementUpdateRate) == 0) {
		activityIncrement *= 1.1;
	}

	//update the activity of the variable (we are not distinguishing between positive
	// and negative literals here)
	int variable = var(literal);
	activity[variable] += activityIncrement;
}

//TODO document
bool propagateGivesConflict() {
	while (indexOfNextLitToPropagate < modelStack.size()) {
		//retrieve the literal to "be propagated"
		int literalToPropagate = modelStack[indexOfNextLitToPropagate];
		//move forward the "pointer" to the next literal that will be propagated
		++indexOfNextLitToPropagate;

		++propagations; //profiling purposes only

		//traverse only positive/negative appearances
		//cout << "PROPAGATION: propagating literal: " << literalToPropagate << endl;
		vector<int> clausesToPropagate = literalToPropagate > 0 ?
				negativeClauses[var(literalToPropagate)] :
				positiveClauses[var(literalToPropagate)];

		//traverse the clauses
		for (uint i = 0; i < clausesToPropagate.size(); ++i) {
			//cout << "PROPAGATION: propagating literal " << literalToPropagate << " in clause: " << clausesToPropagate[i] << endl;

			//retrieve the next clause
			vector<int> clause = clauses[clausesToPropagate[i]];

			//necessary variables initialization
			bool isSomeLiteralTrue = false;
			int undefinedLiterals = 0;
			int lastUndefinedLiteral = 0;

			//cout <<"PROPAGATION: propagating clause: ";
			//traverse the clause
			for (uint k = 0; /* FIXME uncomment this: not isSomeLiteralTrue and */k < clause.size(); ++k) {
				//cout << clause[k] << "  ";
				int value = valueForLiteral(clause[k]);
				if (value == TRUE) {
					isSomeLiteralTrue = true;
				}
				else if (value == UNDEFINED) {
					++undefinedLiterals;
					lastUndefinedLiteral = clause[k];
				}
			}
			//cout << endl;
			if (not isSomeLiteralTrue and undefinedLiterals == 0) {
				// A conflict has been found! All literals are false!
				updateActivityForLiteral(literalToPropagate);
				return true;
			}
			else if (not isSomeLiteralTrue and undefinedLiterals == 1) {
				// The 'lastUndefinedLiteral' is "propagated", because it is the only one
				//  remaining in its clause that is undefined and all of the other literals
				//  of the clause are false
				// With the propagation, this literal is added to the stack, too!
				//cout << "UNIT PROPAGATION: the following literal is propagated by the current propagating literal: " << lastUndefinedLiteral << endl;
				setLiteralToTrue(lastUndefinedLiteral);
			}
		}
	}
	return false;
}

//TODO document
void backtrack() {
	//TODO could this backtrack be faster? backjump? (non chronological backtrack)
	uint i = modelStack.size() - 1;
	int literal = 0;
	while (modelStack[i] != DECISION_MARK) { // 0 is the  mark
		literal = modelStack[i];
		model[var(literal)] = UNDEFINED;
		modelStack.pop_back();
		--i;
	}
	// at this point, literal is the last decision
	modelStack.pop_back(); // remove the  mark
	--decisionLevel;
	indexOfNextLitToPropagate = modelStack.size();
	setLiteralToTrue(-literal);  // reverse last decision
}

/**
 * Selects the next undefined variable from the current interpretation (model)
 * that will be decided and propagated. The heuristic used is based on variable
 * activity, in order to quickly find any possible contradictions.
 *
 * @return the next variable to be decided within the DPLL procedure or 0 if no
 * variable is currently undefined
 */
int getNextDecisionLiteral() {
	++decisions; //profiling purpose only
	double maximumActivity = 0.0;
	int mostActiveVariable = 0; // in case no variable is undefined, it will not be modified
	for (uint i = 1; i <= numVariables; ++i) {
		// check only undefined variables
		if (model[i] == UNDEFINED) {
			//cout << i << "  variable is UNDEFINED" << endl;
			// search for the most active variable
			if (activity[i] >= maximumActivity) {
				maximumActivity = activity[i];
				mostActiveVariable = i;
			}
		}
	}
	//return the most active variable or, if none is undefined, 0
	//cout << "DECISION: variable: " << mostActiveVariable << endl;
	return mostActiveVariable;
}

/**
 * Checks the model (interpretation) against the set of clauses, looking
 * for a contradiction. If any such contradiction is found, the program
 * exits and prints the conflicting clause.
 */
void checkmodel() {
	for (int i = 0; i < numClauses; ++i) {
		bool someTrue = false;
		for (int j = 0; not someTrue and j < clauses[i].size(); ++j) {
			someTrue = (valueForLiteral(clauses[i][j]) == TRUE);
		}
		if (not someTrue) {
			cout << "Error in model, clause is not satisfied:";
			for (int j = 0; j < clauses[i].size(); ++j) {
				cout << clauses[i][j] << " ";
			}
			cout << endl;
			exit(1);
		}
	}
}

/**
 * Exits the program with the appropriate output code. A model check
 * is also performed, in order to avoid errors.
 *
 * @param satisfiable whether the problem was found to be satisfiable or not
 */
void exitWithSatisfiability(bool satisfiable) {
	if (satisfiable) {
		checkmodel();
		cout << "SATISFIABLE" << endl;
		exit(20);
	}
	else {
		cout << "UNSATISFIABLE" << endl;
		exit(10);
	}
}

//TODO document
void executeDPLL() {
	// DPLL algorithm
	while (true) {
		while (propagateGivesConflict()) {
			if (decisionLevel == 0) {
				//there are no more possible decisions (variable assignments),
				// which means that the problem is unsatisfiable
				exitWithSatisfiability(false);
			}
			backtrack();
		}
		int decisionLit = getNextDecisionLiteral();
		if (decisionLit == 0) {
			exitWithSatisfiability(true);
		}
		// start new decision level:
		modelStack.push_back(DECISION_MARK);  // push mark indicating new
		++indexOfNextLitToPropagate;
		++decisionLevel;
		setLiteralToTrue(decisionLit); // now push decisionLit on top of the mark
	}
}

/**
 * Checks for any unit clause and sets the appropriate values in the
 * model accordingly. If a contradiction is found among these unit clauses,
 * early failure is triggered.
 */
void checkUnitClauses() {
	for (uint i = 0; i < numClauses; ++i) {
		if (clauses[i].size() == 1) {
			int literal = clauses[i][0];
			int value = valueForLiteral(literal);
			if (value == FALSE) {
				// This condition will only occur if at least a couple of unit clauses
				//  exist with opposite literals (p and ¬p, for example). When the first
				//  unit clause is used to set a value in the model (see the next condition),
				//  the second unit clause with the same variable will cause a contradiction
				//  to be found, i.e., the problem is unsatisfiable!
				exitWithSatisfiability(false);
			}
			else if (value == UNDEFINED) {
				setLiteralToTrue(literal);
			}
		}
		//TODO could unit clauses be "deleted"? (at least avoid their traversal further on)
	}
}

/**
 * Main program. It reads the SAT problem from the stdin stream, checks unit clauses and
 * executes the DPLL algorithm.
 */
int main() {
	// Read the problem file (available at the stdin stream) and
	//  initialize the rest of necessary variables
	initializeWithParsedInput();

	// Take care of initial unit clauses, if any
	checkUnitClauses();

	// Execute the main DPLL procedure
	executeDPLL();
}
<commit_msg>removed unnecessary debug logs<commit_after>#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <algorithm>
#include <vector>
using namespace std;

//TODO object oriented SAT solver? performance issues? readability? maintainability? extensibility?

#define UNDEFINED -1
#define TRUE 1
#define FALSE 0
#define DECISION_MARK 0

/* Global problem "sizes" */
uint numVariables;
uint numClauses;

/* Clauses and related data structures */
vector<vector<int> > clauses;
vector<vector<int> > positiveClauses;
vector<vector<int> > negativeClauses;

/* Model & backtrack stack */
vector<int> model;
vector<int> modelStack;
uint indexOfNextLitToPropagate;
uint decisionLevel;

/* Heuristic related variables */
vector<double> activity; //TODO would it be better to store activity for each literal? (instead of each variable) i.e., positive vs negative appearances
double activityIncrement;
int conflicts;
int activityIncrementUpdateRate = 10; //TODO is this strategy right? which value is best suited?

/* Statistics */
uint propagations;
uint decisions;

/**
 * Returns the variable that this literal represents
 */
inline uint var(int literal) {
	return abs(literal);
}

/**
 * Reads the input problem file from the stdin stream and initializes
 * any remaining necessary data structures and variables.
 */
void initializeWithParsedInput() {
	// Skip comments
	char c = cin.get();
	while (c == 'c') {
		while (c != '\n')
			c = cin.get();
		c = cin.get();
	}

	// Read "cnf numVars numClauses"
	string aux;
	cin >> aux >> numVariables >> numClauses;
	clauses.resize(numClauses);

	// Initialize positive and negative appearances
	positiveClauses.resize(numVariables + 1);
	negativeClauses.resize(numVariables + 1);

	// Read clauses
	for (uint clause = 0; clause < numClauses; ++clause) {
		int literal;
		while (cin >> literal and literal != 0) {
			// add to the list of clauses
			clauses[clause].push_back(literal);

			// add to the list of positive-negative literals
			if (literal > 0) {
				positiveClauses[var(literal)].push_back(clause);
			}
			else {
				negativeClauses[var(literal)].push_back(clause);
			}
		}
	}

	// Initialize the remaining necessary variables
		// model and backtrack stack
	model.resize(numVariables + 1, UNDEFINED);
	indexOfNextLitToPropagate = 0;
	decisionLevel = 0;
		// heuristic
	activity.resize(numVariables + 1, 0.0);
	activityIncrement = 1.0;
	conflicts = 0;
		// statistics
	propagations = 0;
	decisions = 0;
}

/**
 * TODO comment
 */
int valueForLiteral(int literal) {
//TODO could this be faster? there is a lot of if-else branching here!
	if (literal >= 0) {
		return model[literal];
	}
	else {
		if (model[-literal] == UNDEFINED) {
			return UNDEFINED;
		}
		else {
			return 1 - model[-literal];
		}
	}
}

/**
 * The current interpretation (model) is updated with the appropriate value
 * that will make the passed literal become true in the clause where it appeared.
 * The model stack is also increased, pushing the new value on top.
 *
 * @param literal the literal that will become true after the model update
 */
void setLiteralToTrue(int literal) {
	modelStack.push_back(literal);
	if (literal > 0) {
		model[literal] = TRUE;
	}
	else {
		model[-literal] = FALSE;
	}
}

/**
 * Updates the activity counter of the given literal. The activity increment
 * applied is also updated, in order to give more importance to recent activity.
 *
 * @param literal the literal which activity is to be updated
 */
void updateActivityForLiteral(int literal) {
	//update the activity increment if necessary (every X conflicts)
	++conflicts;
	if ((conflicts % activityIncrementUpdateRate) == 0) {
		activityIncrement *= 1.1;
	}

	//update the activity of the variable (we are not distinguishing between positive
	// and negative literals here)
	int variable = var(literal);
	activity[variable] += activityIncrement;
}

//TODO document
bool propagateGivesConflict() {
	while (indexOfNextLitToPropagate < modelStack.size()) {
		//retrieve the literal to "be propagated"
		int literalToPropagate = modelStack[indexOfNextLitToPropagate];
		//move forward the "pointer" to the next literal that will be propagated
		++indexOfNextLitToPropagate;

		++propagations; //profiling purposes only

		//traverse only positive/negative appearances
		vector<int> clausesToPropagate = literalToPropagate > 0 ?
				negativeClauses[var(literalToPropagate)] :
				positiveClauses[var(literalToPropagate)];

		//traverse the clauses
		for (uint i = 0; i < clausesToPropagate.size(); ++i) {
			//retrieve the next clause
			vector<int> clause = clauses[clausesToPropagate[i]];

			//necessary variables initialization
			bool isSomeLiteralTrue = false;
			int undefinedLiterals = 0;
			int lastUndefinedLiteral = 0;

			//traverse the clause
			for (uint k = 0; not isSomeLiteralTrue and k < clause.size(); ++k) {
				int value = valueForLiteral(clause[k]);
				if (value == TRUE) {
					isSomeLiteralTrue = true;
				}
				else if (value == UNDEFINED) {
					++undefinedLiterals;
					lastUndefinedLiteral = clause[k];
				}
			}
			if (not isSomeLiteralTrue and undefinedLiterals == 0) {
				// A conflict has been found! All literals are false!
				updateActivityForLiteral(literalToPropagate);
				return true;
			}
			else if (not isSomeLiteralTrue and undefinedLiterals == 1) {
				// The 'lastUndefinedLiteral' is "propagated", because it is the only one
				//  remaining in its clause that is undefined and all of the other literals
				//  of the clause are false
				// With the propagation, this literal is added to the stack, too!
				setLiteralToTrue(lastUndefinedLiteral);
			}
		}
	}
	return false;
}

//TODO document
void backtrack() {
	//TODO could this backtrack be faster? backjump? (non chronological backtrack)
	uint i = modelStack.size() - 1;
	int literal = 0;
	while (modelStack[i] != DECISION_MARK) { // 0 is the  mark
		literal = modelStack[i];
		model[var(literal)] = UNDEFINED;
		modelStack.pop_back();
		--i;
	}
	// at this point, literal is the last decision
	modelStack.pop_back(); // remove the  mark
	--decisionLevel;
	indexOfNextLitToPropagate = modelStack.size();
	setLiteralToTrue(-literal);  // reverse last decision
}

/**
 * Selects the next undefined variable from the current interpretation (model)
 * that will be decided and propagated. The heuristic used is based on variable
 * activity, in order to quickly find any possible contradictions.
 *
 * @return the next variable to be decided within the DPLL procedure or 0 if no
 * variable is currently undefined
 */
int getNextDecisionLiteral() {
	++decisions; //profiling purpose only
	double maximumActivity = 0.0;
	int mostActiveVariable = 0; // in case no variable is undefined, it will not be modified
	for (uint i = 1; i <= numVariables; ++i) {
		// check only undefined variables
		if (model[i] == UNDEFINED) {
			// search for the most active variable
			if (activity[i] >= maximumActivity) {
				maximumActivity = activity[i];
				mostActiveVariable = i;
			}
		}
	}
	//return the most active variable or, if none is undefined, 0
	return mostActiveVariable;
}

/**
 * Checks the model (interpretation) against the set of clauses, looking
 * for a contradiction. If any such contradiction is found, the program
 * exits and prints the conflicting clause.
 */
void checkmodel() {
	for (int i = 0; i < numClauses; ++i) {
		bool someTrue = false;
		for (int j = 0; not someTrue and j < clauses[i].size(); ++j) {
			someTrue = (valueForLiteral(clauses[i][j]) == TRUE);
		}
		if (not someTrue) {
			cout << "Error in model, clause is not satisfied:";
			for (int j = 0; j < clauses[i].size(); ++j) {
				cout << clauses[i][j] << " ";
			}
			cout << endl;
			exit(1);
		}
	}
}

/**
 * Exits the program with the appropriate output code. A model check
 * is also performed, in order to avoid errors.
 *
 * @param satisfiable whether the problem was found to be satisfiable or not
 */
void exitWithSatisfiability(bool satisfiable) {
	if (satisfiable) {
		checkmodel();
		cout << "SATISFIABLE" << endl;
		exit(20);
	}
	else {
		cout << "UNSATISFIABLE" << endl;
		exit(10);
	}
}

//TODO document
void executeDPLL() {
	// DPLL algorithm
	while (true) {
		while (propagateGivesConflict()) {
			if (decisionLevel == 0) {
				//there are no more possible decisions (variable assignments),
				// which means that the problem is unsatisfiable
				exitWithSatisfiability(false);
			}
			backtrack();
		}
		int decisionLit = getNextDecisionLiteral();
		if (decisionLit == 0) {
			exitWithSatisfiability(true);
		}
		// start new decision level:
		modelStack.push_back(DECISION_MARK);  // push mark indicating new
		++indexOfNextLitToPropagate;
		++decisionLevel;
		setLiteralToTrue(decisionLit); // now push decisionLit on top of the mark
	}
}

/**
 * Checks for any unit clause and sets the appropriate values in the
 * model accordingly. If a contradiction is found among these unit clauses,
 * early failure is triggered.
 */
void checkUnitClauses() {
	for (uint i = 0; i < numClauses; ++i) {
		if (clauses[i].size() == 1) {
			int literal = clauses[i][0];
			int value = valueForLiteral(literal);
			if (value == FALSE) {
				// This condition will only occur if at least a couple of unit clauses
				//  exist with opposite literals (p and ¬p, for example). When the first
				//  unit clause is used to set a value in the model (see the next condition),
				//  the second unit clause with the same variable will cause a contradiction
				//  to be found, i.e., the problem is unsatisfiable!
				exitWithSatisfiability(false);
			}
			else if (value == UNDEFINED) {
				setLiteralToTrue(literal);
			}
		}
		//TODO could unit clauses be "deleted"? (at least avoid their traversal further on)
	}
}

/**
 * Main program. It reads the SAT problem from the stdin stream, checks unit clauses and
 * executes the DPLL algorithm.
 */
int main() {
	// Read the problem file (available at the stdin stream) and
	//  initialize the rest of necessary variables
	initializeWithParsedInput();

	// Take care of initial unit clauses, if any
	checkUnitClauses();

	// Execute the main DPLL procedure
	executeDPLL();
}
<|endoftext|>


<commit_before>#include <map>
#include <iostream>

#include "commands.hpp"

namespace commands
{
	std::map<std::string, int(*)(Shell *, Shell::command *)> internal =
	{
		{"quit",    &quit},
		{"exit",    &quit},
		{"logout",  &quit},
		{"help",    &help},
		{"echo",    &echo},
		{"clr",     &clr},
		{"killall", &killall},
		{"pause",   &pause},
		{"dir",     &dir},
		{"cd",      &cd},
		{"jobs",    &jobs},
		{"environ", &environ},
	};

	int quit(Shell *shell, Shell::command *cmd)
	{

	}

	int help(Shell *shell, Shell::command *cmd)
	{

	}

	int echo(Shell *shell, Shell::command *cmd)
	{

	}

	int clr(Shell *shell, Shell::command *cmd)
	{
		std::cout << "\033[2J\033[1;1H";
	}

	int killall(Shell *shell, Shell::command *cmd)
	{

	}

	int pause(Shell *shell, Shell::command *cmd)
	{
		std::cout << "Console paused. Press <ENTER> to resume.";

		while (std::cin.get() != '\n');
	}

	int dir(Shell *shell, Shell::command *cmd)
	{

	}

	int cd(Shell *shell, Shell::command *cmd)
	{

	}

	int jobs(Shell *shell, Shell::command *cmd)
	{

	}

	int environ(Shell *shell, Shell::command *cmd)
	{

	}
}
<commit_msg>Impliment the quit command<commit_after>#include <map>
#include <iostream>

#include "commands.hpp"

namespace commands
{
	std::map<std::string, int(*)(Shell *, Shell::command *)> internal =
	{
		{"quit",    &quit},
		{"exit",    &quit},
		{"logout",  &quit},
		{"help",    &help},
		{"echo",    &echo},
		{"clr",     &clr},
		{"killall", &killall},
		{"pause",   &pause},
		{"dir",     &dir},
		{"cd",      &cd},
		{"jobs",    &jobs},
		{"environ", &environ},
	};

	int quit(Shell *shell, Shell::command *cmd)
	{
		shell->finish();
	}

	int help(Shell *shell, Shell::command *cmd)
	{

	}

	int echo(Shell *shell, Shell::command *cmd)
	{

	}

	int clr(Shell *shell, Shell::command *cmd)
	{
		std::cout << "\033[2J\033[1;1H";
	}

	int killall(Shell *shell, Shell::command *cmd)
	{

	}

	int pause(Shell *shell, Shell::command *cmd)
	{
		std::cout << "Console paused. Press <ENTER> to resume.";

		while (std::cin.get() != '\n');
	}

	int dir(Shell *shell, Shell::command *cmd)
	{

	}

	int cd(Shell *shell, Shell::command *cmd)
	{

	}

	int jobs(Shell *shell, Shell::command *cmd)
	{

	}

	int environ(Shell *shell, Shell::command *cmd)
	{

	}
}
<|endoftext|>


<commit_before>#include <regex>
#include <string.h>
#include "lynxbot.h"
#include "sed.h"
#include "stringparse.h"

struct sedinfo {
	char *regex;
	char *replace;
	int global;
	int ignore;
	int error;
	int errtok;
};

static int parsecmd(struct sedinfo *s, char *cmd);
static void puterr(char *out, size_t max, struct sedinfo *s);
static char *readbrackets(char *s);

/* sed: perform a basic sed substitution command on input */
int sed(char *s, size_t max, const char *input, const char *sedcmd)
{
	char cmd[MAX_MSG];
	struct sedinfo sedbuf;
	std::regex pattern;
	auto type = std::regex_constants::format_sed;

	strncpy(cmd, sedcmd, MAX_MSG);
	if (!parsecmd(&sedbuf, cmd)) {
		puterr(s, max, &sedbuf);
		return 0;
	}

	try {
		if (!sedbuf.ignore)
			pattern = std::regex(sedbuf.regex);
		else
			pattern = std::regex(sedbuf.regex, std::regex::icase);
	} catch (std::regex_error) {
		_sprintf(s, max, "sed: invalid regex");
		return 0;
	}

	if (!sedbuf.global)
		type |= std::regex_constants::format_first_only;
	_sprintf(s, max, "%s", std::regex_replace(input, pattern,
				sedbuf.replace, type).c_str());
	return 1;
}

#define INVCMD 1
#define UNTERM 2
#define BADOPT 3

/* parsecmd: break up the sed command into its parts */
static int parsecmd(struct sedinfo *s, char *cmd)
{
	char *t;
	int delim;

	s->global = s->ignore = 0;
	if (cmd[0] != 's') {
		s->error = INVCMD;
		s->errtok = cmd[0];
		return 0;
	}
	if (!(delim = cmd[1]) || !*(s->regex = cmd + 2)) {
		s->error = UNTERM;
		return 0;
	}
	t = s->regex;
	for (t = s->regex; *t; ++t) {
		if (*t == '(' || *t == '[') {
			if (!(t = readbrackets(t))) {
				s->error = UNTERM;
				return 0;
			}
		} else if (*t == delim) {
			if (*(t - 1) != '\\')
				break;
			shift_l(t - 1);
			--t;
		}
	}
	if (!t) {
		s->error = UNTERM;
		return 0;
	}
	*t++ = '\0';
	if (!*(s->replace = t)) {
		s->error = UNTERM;
		return 0;
	}
	while ((t = strchr(t, delim)) && *(t - 1) == '\\')
		shift_l(t - 1);
	if (!t) {
		s->error = UNTERM;
		return 0;
	}
	*t++ = '\0';
	for (; *t; ++t) {
		switch (*t) {
		case 'g':
			s->global = 1;
			break;
		case 'i':
			s->ignore = 1;
			break;
		default:
			s->error = BADOPT;
			s->errtok = *t;
			return 0;
		}
	}

	return 1;
}

/* puterr: write error string corresponding to s->error to out */
static void puterr(char *out, size_t max, struct sedinfo *s)
{
	switch (s->error) {
	case INVCMD:
		_sprintf(out, max, "sed: invalid command '%c'", s->errtok);
		break;
	case UNTERM:
		_sprintf(out, max, "sed: unterminated 's' command");
		break;
	case BADOPT:
		_sprintf(out, max, "sed: unkown option to 's' command "
				"-- '%c'", s->errtok);
		break;
	default:
		break;
	}
}

/* readbrackets: read over a bracketed block */
static char *readbrackets(char *s)
{
	int end;

	end = *s == '(' ? ')' : ']';
	for (++s; *s && *s != end; ++s) {
		if (*s == '\\' && s[1] == end)
			shift_l(s);
	}
	return *s ? s : NULL;
}
<commit_msg>sed: bracket fixes<commit_after>#include <regex>
#include <string.h>
#include "lynxbot.h"
#include "sed.h"
#include "stringparse.h"

struct sedinfo {
	char *regex;
	char *replace;
	int global;
	int ignore;
	int error;
	int errtok;
};

static int parsecmd(struct sedinfo *s, char *cmd);
static void puterr(char *out, size_t max, struct sedinfo *s);
static char *readbrackets(char *s);

/* sed: perform a basic sed substitution command on input */
int sed(char *s, size_t max, const char *input, const char *sedcmd)
{
	char cmd[MAX_MSG];
	struct sedinfo sedbuf;
	std::regex pattern;
	auto type = std::regex_constants::format_sed;

	strncpy(cmd, sedcmd, MAX_MSG);
	if (!parsecmd(&sedbuf, cmd)) {
		puterr(s, max, &sedbuf);
		return 0;
	}

	try {
		if (!sedbuf.ignore)
			pattern = std::regex(sedbuf.regex);
		else
			pattern = std::regex(sedbuf.regex, std::regex::icase);
	} catch (std::regex_error) {
		_sprintf(s, max, "sed: invalid regex");
		return 0;
	}

	if (!sedbuf.global)
		type |= std::regex_constants::format_first_only;
	_sprintf(s, max, "%s", std::regex_replace(input, pattern,
				sedbuf.replace, type).c_str());
	return 1;
}

#define INVCMD 1
#define UNTERM 2
#define BADOPT 3

/* parsecmd: break up the sed command into its parts */
static int parsecmd(struct sedinfo *s, char *cmd)
{
	char *t;
	int delim;

	s->global = s->ignore = 0;
	if (cmd[0] != 's') {
		s->error = INVCMD;
		s->errtok = cmd[0];
		return 0;
	}
	if (!(delim = cmd[1]) || !*(s->regex = cmd + 2)) {
		s->error = UNTERM;
		return 0;
	}
	t = s->regex;
	for (t = s->regex; *t; ++t) {
		if ((*t == '(' || *t == '[')
				&& (t == s->regex || *(t - 1) != '\\')) {
			if (!(t = readbrackets(t))) {
				s->error = UNTERM;
				return 0;
			}
		} else if (*t == delim) {
			if (*(t - 1) != '\\')
				break;
			shift_l(t - 1);
			--t;
		}
	}
	if (!t) {
		s->error = UNTERM;
		return 0;
	}
	*t++ = '\0';
	if (!*(s->replace = t)) {
		s->error = UNTERM;
		return 0;
	}
	while ((t = strchr(t, delim)) && *(t - 1) == '\\')
		shift_l(t - 1);
	if (!t) {
		s->error = UNTERM;
		return 0;
	}
	*t++ = '\0';
	for (; *t; ++t) {
		switch (*t) {
		case 'g':
			s->global = 1;
			break;
		case 'i':
			s->ignore = 1;
			break;
		default:
			s->error = BADOPT;
			s->errtok = *t;
			return 0;
		}
	}

	return 1;
}

/* puterr: write error string corresponding to s->error to out */
static void puterr(char *out, size_t max, struct sedinfo *s)
{
	switch (s->error) {
	case INVCMD:
		_sprintf(out, max, "sed: invalid command '%c'", s->errtok);
		break;
	case UNTERM:
		_sprintf(out, max, "sed: unterminated 's' command");
		break;
	case BADOPT:
		_sprintf(out, max, "sed: unkown option to 's' command "
				"-- '%c'", s->errtok);
		break;
	default:
		break;
	}
}

/* readbrackets: read over a bracketed block */
static char *readbrackets(char *s)
{
	int end;

	end = *s == '(' ? ')' : ']';
	for (++s; *s && *s != end; ++s) {
		if (*s == '\\' && s[1] == end)
			++s;
	}
	return *s ? s : NULL;
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "dll_test.hpp"

#include "dll/neural/dense_layer.hpp"
#include "dll/neural/activation_layer.hpp"
#include "dll/transform/scale_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/trainer/stochastic_gradient_descent.hpp"

#include "cifar/cifar10_reader.hpp"

// Fully-Connected Network on CIFAR-10

TEST_CASE("cifar/dense/sgd/1", "[dense][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::dense_desc<3 * 32 * 32, 1000>::layer_t,
            dll::dense_desc<1000, 500>::layer_t,
            dll::dense_desc<500, 10>::layer_t>,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = cifar::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 3 * 32 * 32>>(2000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->display();

    dbn->learning_rate = 0.01;
    dbn->momentum = 0.9;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 50);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}
<commit_msg>Basic tests for CIFAR-10<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "dll_test.hpp"

#include "dll/neural/dense_layer.hpp"
#include "dll/neural/conv_layer.hpp"
#include "dll/pooling/mp_layer.hpp"
#include "dll/neural/activation_layer.hpp"
#include "dll/transform/scale_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/trainer/stochastic_gradient_descent.hpp"

#include "cifar/cifar10_reader.hpp"

// Fully-Connected Network on CIFAR-10

TEST_CASE("cifar/dense/sgd/1", "[dense][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::dense_desc<3 * 32 * 32, 1000>::layer_t,
            dll::dense_desc<1000, 500>::layer_t,
            dll::dense_desc<500, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = cifar::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 3 * 32 * 32>>(2000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->display();

    dbn->learning_rate = 0.01;
    dbn->momentum = 0.9;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 50);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE("cifar/conv/sgd/1", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<3, 32, 32, 6, 5, 5>::layer_t,
            dll::conv_desc<6, 28, 28, 6, 5, 5>::layer_t,
            dll::dense_desc<6 * 24 * 24, 500>::layer_t,
            dll::dense_desc<500, 10, dll::activation<dll::function::SOFTMAX>>::layer_t
        >,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = cifar::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 3, 32, 32>>(1000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->display();

    dbn->learning_rate = 0.01;
    dbn->momentum = 0.9;

    FT_CHECK(50, 6e-2);
    TEST_CHECK(0.2);
}

TEST_CASE("cifar/conv/sgd/2", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<3, 32, 32, 12, 5, 5, dll::activation<dll::function::RELU>>::layer_t,
            dll::mp_layer_3d_desc<12, 28, 28, 1, 2, 2>::layer_t,
            dll::conv_desc<12, 14, 14, 24, 3, 3, dll::activation<dll::function::RELU>>::layer_t,
            dll::mp_layer_3d_desc<24, 12, 12, 1, 2, 2>::layer_t,
            dll::dense_desc<24 * 6 * 6, 64, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_desc<64, 10, dll::activation<dll::function::SOFTMAX>>::layer_t
        >,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::batch_size<50>>::dbn_t dbn_t;

    auto dataset = cifar::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 3, 32, 32>>(5000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->display();

    dbn->learning_rate = 0.001;
    dbn->momentum = 0.9;

    FT_CHECK(50, 6e-2);
    TEST_CHECK(0.2);
}
<|endoftext|>


<commit_before>#include "orgcalendar.h"

orgCalendar::orgCalendar(const std::weak_ptr<Notebook> notes, const std::weak_ptr<Settings> settings, QWidget *parent) :
    QCalendarWidget(parent)
{
    this->notes = notes.lock();
    this->settings = settings.lock();
    this->setFirstDayOfWeek(Qt::Monday);
    this->setGridVisible(true);
    this->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
}

void orgCalendar::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
{
    QCalendarWidget::paintCell(painter, rect, date);
    if(date == QDate::currentDate())
    {
        painter->save ();

        int penSize = 3;
        QPen pen(Qt::blue, penSize, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
        painter->setPen(pen);
        painter->setBrush(Qt::transparent);
        painter->setRenderHint(QPainter::Antialiasing);

        painter->drawRect(QRect(rect.left() + penSize, rect.top() + penSize,
                                rect.width() - penSize*2, rect.height() - penSize*2));

        painter->restore ();
    }
    if(notes->contains(date))
    {
        painter->save ();
        QRect circleRect = rect;
        int cellHeight = (rect.top() - rect.bottom()) / 2;
        circleRect.setLeft(rect.center().x() - cellHeight);
        circleRect.setRight(rect.center().x() + cellHeight);
        circleRect.setBottom(circleRect.bottom() - 3);
        circleRect.setTop(circleRect.top() + 3);

        QPen pen(Qt::red, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
        painter->setPen(pen);
        painter->setBrush(Qt::transparent);
        painter->setRenderHint(QPainter::Antialiasing);
        painter->drawEllipse(circleRect);

        painter->restore ();
    }
}

void orgCalendar::showToday()
{
    setSelectedDate(QDate::currentDate());
    setFocus();
}
<commit_msg>now displays number of notes on date<commit_after>#include "orgcalendar.h"

orgCalendar::orgCalendar(const std::weak_ptr<Notebook> notes, const std::weak_ptr<Settings> settings, QWidget *parent) :
    QCalendarWidget(parent)
{
    this->notes = notes.lock();
    this->settings = settings.lock();
    this->setFirstDayOfWeek(Qt::Monday);
    this->setGridVisible(true);
    this->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
}

void orgCalendar::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const
{
    QCalendarWidget::paintCell(painter, rect, date);
    if(date == QDate::currentDate())
    {
        painter->save ();

        int penSize = 3;
        QPen pen(Qt::blue, penSize, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
        painter->setPen(pen);
        painter->setBrush(Qt::transparent);
        painter->setRenderHint(QPainter::Antialiasing);

        painter->drawRect(QRect(rect.left() + penSize, rect.top() + penSize,
                                rect.width() - penSize*2, rect.height() - penSize*2));

        painter->restore ();
    }
    int count = notes->contains(date);
    if(count > 0)
    {
        painter->save ();
        QRect circleRect = rect;
        int cellHeight = (rect.top() - rect.bottom()) / 2;
        circleRect.setLeft(rect.center().x() - cellHeight);
        circleRect.setRight(rect.center().x() + cellHeight);
        circleRect.setBottom(circleRect.bottom() - 3);
        circleRect.setTop(circleRect.top() + 3);

        QPen pen(Qt::red, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
        painter->setPen(pen);
        painter->setBrush(Qt::transparent);
        painter->setRenderHint(QPainter::Antialiasing);
        painter->drawEllipse(circleRect);
        if(count > 1)
        {
            painter->drawText(rect.right() - 17, rect.bottom() - 5, QString::number(count));
        }

        painter->restore ();
    }
}

void orgCalendar::showToday()
{
    setSelectedDate(QDate::currentDate());
    setFocus();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008 Rivo Laks <rivolaks@hot.ee>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "glwidget.h"

#include "camera.h"
#include "fpscounter.h"
#include "textrenderer.h"
#include "glpainter.h"

#include <QtOpenGL/QGLContext>
#include <QtOpenGL/QGLFormat>

#include <core/debughelper.h>

using namespace GluonGraphics;

GLWidget::GLWidget(QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) :
        QGLWidget(parent, shareWidget, f)
{
    init();
}

GLWidget::GLWidget(QGLContext* context, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) :
        QGLWidget(context, parent, shareWidget, f)
{
    init();
}

GLWidget::GLWidget(const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) :
        QGLWidget(format, parent, shareWidget, f)
{
    init();
}

GLWidget::~GLWidget()
{
    //delete mCamera;
    delete mFpsCounter;
    delete mTextRenderer;
}

void GLWidget::init()
{
    mCamera = 0;
    mFpsCounter = 0;
    mTextRenderer = 0;
    mAutomaticClear = true;
    mClearColor = QVector4D(0, 0, 0, 0);
    mGLInitialized = false;
    mShowFps = false;
    mWireframeMode = false;
    mShortcutsEnabled = true;
    //m_engine=0;

    QAction* a;
    a = new QAction(this);
    a->setShortcut(Qt::META + Qt::Key_F);
    connect(a, SIGNAL(triggered()), this, SLOT(toggleShowFps()));
    addAction(a);
    mShortcuts.append(a);
    a = new QAction(this);
    a->setShortcut(Qt::META + Qt::Key_W);
    connect(a, SIGNAL(triggered()), this, SLOT(toggleWireframeMode()));
    addAction(a);
    mShortcuts.append(a);
    glInit();
}

void GLWidget::setShortcutsEnabled( bool enabled)
{
    if (enabled == mShortcutsEnabled) {
        return;
    }
    mShortcutsEnabled = enabled;
    foreach (QAction* a, mShortcuts) {
        a->setEnabled(enabled);
    }
}

void GLWidget::toggleShowFps()
{
    mShowFps = !mShowFps;
    update();
}

void GLWidget::toggleWireframeMode()
{
    mWireframeMode = !mWireframeMode;
    update();
}

void GLWidget::setClearColor(const QVector4D& c)
{
    mClearColor = c;
    if (mGLInitialized) {
        // TODO: what if this is called when context isn't current?
        glClearColor(mClearColor.x(), mClearColor.y(), mClearColor.z(), mClearColor.w());
    }
}

void GLWidget::setAutomaticClear(bool clear)
{
    mAutomaticClear = clear;
}

void GLWidget::setErrorText(const QString& text)
{
    mErrorText = text;
    update();
}

GluonGraphics::TextRenderer* GLWidget::textRenderer() const
{
    if (!mTextRenderer) {
        mTextRenderer = new GluonGraphics::TextRenderer();
    }
    return mTextRenderer;

}

void GLWidget::initializeGL()
{

    mGLInitialized = true;

    // Create camera and fps counter
    mCamera =new Camera();
    //connect(Engine::instance(), SIGNAL(activeCameraChanged(GluonGraphics::Camera*)), SLOT(setCamera(GluonGraphics::Camera*)));

    //connect(Engine::instance(), SIGNAL(activeCameraChanged(GluonGraphics::Camera*)), SLOT(setCamera(GluonGraphics::Camera*)));

    mFpsCounter = new GluonGraphics::FPSCounter;

    // Set some defaults
    // TODO: make sure we're in RGBA mode
    setClearColor(mClearColor);
    glShadeModel(GL_SMOOTH);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glMatrixMode(GL_PROJECTION);
    //glDisable(GL_DEPTH_TEST);

    // Enable depth testing if we have depth
//     if (context()->format().depth()) {
//         glEnable(GL_DEPTH_TEST);
//     }

    // Set up camera
    camera()->setPosition(QVector3D(0, 0, 20));
    camera()->setLookAt(QVector3D(0, 0, 1));
    camera()->setUp(QVector3D(0, 1, 0));
    camera()->setDepthRange(1, 100);

}

void GLWidget::resizeGL(int width, int height)
{
    DEBUG_FUNC_NAME
    m_viewportWidth = width;
    m_viewportHeight = height;

    if(mCamera)
    {

        camera()->setViewport(0, 0, width, height);
        camera()->setAspect(width/(float)height);
        camera()->applyViewport();
        camera()->applyPerspective();
//         camera()->applyOrtho();

    }

}

void GLWidget::paintGL()
{
    makeCurrent();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    QGLWidget::paintGL();

    // If error text has been set then show it and return
    if (!mErrorText.isNull()) {
        DEBUG_BLOCK
        DEBUG_TEXT(mErrorText);
        return;
    }

    // Advance the counter
    fpsCounter()->nextFrame();

    // Clear buffers
    if (mAutomaticClear) {
        setClearColor(mClearColor);
        if (context()->format().depth()) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        } else {
            glClear(GL_COLOR_BUFFER_BIT);
        }
    }

    // Apply camera
    if(mCamera)
        mCamera->applyView();

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    if (mWireframeMode) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }

    render();

    glPopAttrib();

    if (mShowFps) {
        textRenderer()->begin(this);
        textRenderer()->draw(5, 0, "FPS: " + fpsCounter()->fpsString());
        textRenderer()->end();
    }
}

void GLWidget::drawItems()
{
    ItemList items = Engine::instance()->items();
    foreach (Item *it, items)
    {
        it->paintGL();
    }
}

void GLWidget::render()
{

    glBegin(GL_LINES) ;
      glColor3f(0,1,0) ;
      glVertex3f(0,0,0) ;
      glVertex3f(0,5,0) ;
      glEnd() ;

      glBegin(GL_LINES) ;
        glColor3f(1,0,0) ;
        glVertex3f(0,0,0) ;
        glVertex3f(5,0,0) ;
        glEnd() ;

        glBegin(GL_LINES) ;
          glColor3f(0,0,1) ;
          glVertex3f(0,0,0) ;
          glVertex3f(0,0,5) ;
          glEnd() ;

  //if (m_engine!=0)
    drawItems();
}

void GLWidget::setCamera(Camera* camera)
{
    mCamera = camera;
    resizeGL(m_viewportWidth, m_viewportHeight);
}

#include "glwidget.moc"
<commit_msg>Restore camera functionality<commit_after>/*
 * Copyright (C) 2008 Rivo Laks <rivolaks@hot.ee>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "glwidget.h"

#include "camera.h"
#include "fpscounter.h"
#include "textrenderer.h"
#include "glpainter.h"

#include <QtOpenGL/QGLContext>
#include <QtOpenGL/QGLFormat>

#include <core/debughelper.h>

using namespace GluonGraphics;

GLWidget::GLWidget(QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) :
        QGLWidget(parent, shareWidget, f)
{
    init();
}

GLWidget::GLWidget(QGLContext* context, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) :
        QGLWidget(context, parent, shareWidget, f)
{
    init();
}

GLWidget::GLWidget(const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) :
        QGLWidget(format, parent, shareWidget, f)
{
    init();
}

GLWidget::~GLWidget()
{
    //delete mCamera;
    delete mFpsCounter;
    delete mTextRenderer;
}

void GLWidget::init()
{
    mCamera = 0;
    mFpsCounter = 0;
    mTextRenderer = 0;
    mAutomaticClear = true;
    mClearColor = QVector4D(0, 0, 0, 0);
    mGLInitialized = false;
    mShowFps = true;
    mWireframeMode = false;
    mShortcutsEnabled = true;
    //m_engine=0;

    QAction* a;
    a = new QAction(this);
    a->setShortcut(Qt::META + Qt::Key_F);
    connect(a, SIGNAL(triggered()), this, SLOT(toggleShowFps()));
    addAction(a);
    mShortcuts.append(a);
    a = new QAction(this);
    a->setShortcut(Qt::META + Qt::Key_W);
    connect(a, SIGNAL(triggered()), this, SLOT(toggleWireframeMode()));
    addAction(a);
    mShortcuts.append(a);
    glInit();
}

void GLWidget::setShortcutsEnabled( bool enabled)
{
    if (enabled == mShortcutsEnabled) {
        return;
    }
    mShortcutsEnabled = enabled;
    foreach (QAction* a, mShortcuts) {
        a->setEnabled(enabled);
    }
}

void GLWidget::toggleShowFps()
{
    mShowFps = !mShowFps;
    update();
}

void GLWidget::toggleWireframeMode()
{
    mWireframeMode = !mWireframeMode;
    update();
}

void GLWidget::setClearColor(const QVector4D& c)
{
    mClearColor = c;
    if (mGLInitialized) {
        // TODO: what if this is called when context isn't current?
        glClearColor(mClearColor.x(), mClearColor.y(), mClearColor.z(), mClearColor.w());
    }
}

void GLWidget::setAutomaticClear(bool clear)
{
    mAutomaticClear = clear;
}

void GLWidget::setErrorText(const QString& text)
{
    mErrorText = text;
    update();
}

GluonGraphics::TextRenderer* GLWidget::textRenderer() const
{
    if (!mTextRenderer) {
        mTextRenderer = new GluonGraphics::TextRenderer();
    }
    return mTextRenderer;

}

void GLWidget::initializeGL()
{

    mGLInitialized = true;

    // Create camera and fps counter
    mCamera = Engine::instance()->activeCamera();
    connect(Engine::instance(), SIGNAL(activeCameraChanged(GluonGraphics::Camera*)), SLOT(setCamera(GluonGraphics::Camera*)));

    //connect(Engine::instance(), SIGNAL(activeCameraChanged(GluonGraphics::Camera*)), SLOT(setCamera(GluonGraphics::Camera*)));

    mFpsCounter = new GluonGraphics::FPSCounter;

    // Set some defaults
    // TODO: make sure we're in RGBA mode
    setClearColor(mClearColor);
    glShadeModel(GL_SMOOTH);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glMatrixMode(GL_PROJECTION);
    //glDisable(GL_DEPTH_TEST);

    // Enable depth testing if we have depth
//     if (context()->format().depth()) {
//         glEnable(GL_DEPTH_TEST);
//     }

    // Set up camera
    //camera()->setPosition(QVector3D(0, 0, 20));
    //camera()->setLookAt(QVector3D(0, 0, 1));
    //camera()->setUp(QVector3D(0, 1, 0));
    //camera()->setDepthRange(1, 100);

}

void GLWidget::resizeGL(int width, int height)
{
    makeCurrent();

    m_viewportWidth = width;
    m_viewportHeight = height;

    if(mCamera)
    {

        camera()->setViewport(0, 0, width, height);
        camera()->setAspect(width/(float)height);
        camera()->applyViewport();
        //camera()->applyPerspective();
        camera()->applyOrtho();
    }
}

void GLWidget::paintGL()
{
    makeCurrent();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    QGLWidget::paintGL();

    // If error text has been set then show it and return
    if (!mErrorText.isNull()) {
        DEBUG_BLOCK
        DEBUG_TEXT(mErrorText);
        return;
    }

    // Advance the counter
    fpsCounter()->nextFrame();

    // Clear buffers
    if (mAutomaticClear) {
        setClearColor(mClearColor);
        if (context()->format().depth()) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        } else {
            glClear(GL_COLOR_BUFFER_BIT);
        }
    }

    // Apply camera
    if(mCamera)
        mCamera->applyView();

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    if (mWireframeMode) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }

    render();

    glPopAttrib();

    if (mShowFps) {
        textRenderer()->begin(this);
        textRenderer()->draw(5, 0, "FPS: " + fpsCounter()->fpsString());
        textRenderer()->end();
    }
}

void GLWidget::drawItems()
{
    ItemList items = Engine::instance()->items();
    foreach (Item *it, items)
    {
        it->paintGL();
    }
}

void GLWidget::render()
{

    /*glBegin(GL_LINES) ;
      glColor3f(0,1,0) ;
      glVertex3f(0,0,0) ;
      glVertex3f(0,5,0) ;
      glEnd() ;

      glBegin(GL_LINES) ;
        glColor3f(1,0,0) ;
        glVertex3f(0,0,0) ;
        glVertex3f(5,0,0) ;
        glEnd() ;

        glBegin(GL_LINES) ;
          glColor3f(0,0,1) ;
          glVertex3f(0,0,0) ;
          glVertex3f(0,0,5) ;
          glEnd() ;*/

  //if (m_engine!=0)
    drawItems();
}

void GLWidget::setCamera(Camera* camera)
{
    mCamera = camera;
    resizeGL(m_viewportWidth, m_viewportHeight);
}

#include "glwidget.moc"
<|endoftext|>