<commit_before>#include <avr/io.h>
#include <util/delay.h>
#include "output/PWMOut.h"

PWMOut pwm0(&TCCR0A, &TCCR0B, &OCR0A, &DDRB, PB0, COM0A0, COM0A1);
PWMOut pwm1(&TCCR0A, &TCCR0B, &OCR0B, &DDRB, PB1, COM0B0, COM0B1);

int main(void) {

    uint8_t x;
    while (1) {

        for (x = 0; x < 255; x++) {
            pwm0.write(x);
            pwm1.write(255 - x);
            _delay_ms(4);
        }

        for (x = 255; x > 0; x--) {
            pwm0.write(x);
            pwm1.write(255 - x);
            _delay_ms(4);
        }

    }
}
<commit_msg>first try on pin change interrupts<commit_after>#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "output/PWMOut.h"
#include "output/DOut.h"

PWMOut pwm0(&TCCR0A, &TCCR0B, &OCR0A, &DDRB, PB0, COM0A0, COM0A1);
DOut led1(&PORTB, &DDRB, PB1);
//PWMOut pwm1(&TCCR0A, &TCCR0B, &OCR0B, &DDRB, PB1, COM0B0, COM0B1);

int main(void) {

    cli();
    GIMSK |= (1 << PCIE); // turns on pin change interrupts
    PCMSK |= (1 << PCINT3); // turn on interrupts on pins PB2,
    sei();

    DDRB &= ~(1 << PB3); // PB3 as input
    PORTB |= (1 << PB3); // internal pullup pb3

    uint8_t x;
    while (1) {
        for (x = 0; x < 255; x++) {
            pwm0.write(x);
            _delay_ms(4);
        }
        _delay_ms(1000);
    }
}

ISR(PCINT0_vect) {

    if (!(PINB & (1 << PB3))) {
        led1.toggle();
    }

}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>

#include "base/misc.hh"
#include "dev/etherpkt.hh"
#include "sim/serialize.hh"

using namespace std;

void
PacketData::serialize(const string &base, ostream &os)
{
    paramOut(os, base + ".length", length);
    arrayParamOut(os, base + ".data", data, length);
}

void
PacketData::unserialize(const string &base, Checkpoint *cp,
                        const string &section)
{
    paramIn(cp, section, base + ".length", length);
    arrayParamIn(cp, section, base + ".data", data, length);
}
<commit_msg>Improve checkpointing of ethernet packets a bit.<commit_after>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>

#include "base/misc.hh"
#include "dev/etherpkt.hh"
#include "sim/serialize.hh"

using namespace std;

void
PacketData::serialize(const string &base, ostream &os)
{
    paramOut(os, base + ".length", length);
    arrayParamOut(os, base + ".data", data, length);
}

void
PacketData::unserialize(const string &base, Checkpoint *cp,
                        const string &section)
{
    paramIn(cp, section, base + ".length", length);
    if (length)
        arrayParamIn(cp, section, base + ".data", data, length);
}
<|endoftext|>


<commit_before>#include <GL/glew.h> // to load OpenGL extensions at runtime
#include <GLFW/glfw3.h> // to set up the OpenGL context and manage window lifecycle and inputs

#include <stdio.h>
#include <iostream>

/// The main function

int main () {
	std::cout << "Hello !" << std::endl;
	return 0;
}<commit_msg>Added GLFW initialization and loop<commit_after>#include <GL/glew.h> // to load OpenGL extensions at runtime
#include <GLFW/glfw3.h> // to set up the OpenGL context and manage window lifecycle and inputs

#include <stdio.h>
#include <iostream>

#define INITIAL_SIZE_WIDTH 800
#define INITIAL_SIZE_HEIGHT 600

/// The main function

int main () {
	// Initialize glfw, which will create and setup an OpenGL context.
	if (!glfwInit()) {
		std::cerr << "ERROR: could not start GLFW3" << std::endl;
		return 1;
	}

	// On OS X, the correct OpenGL profile and version to use have to be explicitely defined.
	#ifdef __APPLE__
	glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 2);
	glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
	glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	#endif

	// Create a window with a given size. Width and height are macros as we will need them again.
	GLFWwindow* window = glfwCreateWindow(INITIAL_SIZE_WIDTH, INITIAL_SIZE_HEIGHT,"GL_Template", NULL, NULL);
	if (!window) {
		std::cerr << "ERROR: could not open window with GLFW3" << std::endl;
		glfwTerminate();
		return 1;
	}

	// Bind the OpenGL context and the new window.
	glfwMakeContextCurrent(window);

	// Start the display/interaction loop.
	while (!glfwWindowShouldClose(window)) {

		// Update the content of the window.
		// ...

		// Update events (inputs,...).
		glfwPollEvents();
	}

	// Remove the window.
	glfwDestroyWindow(window);
	// Close GL context and any other GLFW resources.
	glfwTerminate();
	return 0;
}<|endoftext|>


<commit_before>// Convert DMD CodeView debug information to PDB files
// Copyright (c) 2009-2010 by Rainer Schuetze, All Rights Reserved
//
// License for redistribution is given by the Artistic License 2.0
// see file LICENSE for further details

#include "PEImage.h"
#include "cv2pdb.h"
#include "symutil.h"

#include <direct.h>

double
#include "../VERSION"
;

#ifdef UNICODE
#define T_toupper	towupper
#define T_getdcwd	_wgetdcwd
#define T_strlen	wcslen
#define T_strcpy	wcscpy
#define T_strcat	wcscat
#define T_strstr	wcsstr
#define T_strncmp	wcsncmp
#define T_strtoul	wcstoul
#define T_strtod	wcstod
#define T_strrchr	wcsrchr
#define T_unlink	_wremove
#define T_main		wmain
#define SARG		"%S"
#define T_stat		_wstat
#else
#define T_toupper	toupper
#define T_getdcwd	_getdcwd
#define T_strlen	strlen
#define T_strcpy	strcpy
#define T_strcat	strcat
#define T_strstr	strstr
#define T_strncmp	strncmp
#define T_strtoul	strtoul
#define T_strtod	strtod
#define T_strrchr	strrchr
#define T_unlink	unlink
#define T_main		main
#define SARG		"%s"
#define T_stat		stat
#endif

void fatal(const char *message, ...)
{
	va_list argptr;
	va_start(argptr, message);
	vprintf(message, argptr);
	va_end(argptr);
	printf("\n");
	exit(1);
}

void makefullpath(TCHAR* pdbname)
{
	TCHAR* pdbstart = pdbname;
	TCHAR fullname[260];
	TCHAR* pfullname = fullname;

	int drive = 0;
	if (pdbname[0] && pdbname[1] == ':')
	{
		if (pdbname[2] == '\\' || pdbname[2] == '/')
			return;
		drive = T_toupper (pdbname[0]) - 'A' + 1;
		pdbname += 2;
	}
	else
	{
		drive = _getdrive();
	}

	if (*pdbname != '\\' && *pdbname != '/')
	{
		T_getdcwd(drive, pfullname, sizeof(fullname)/sizeof(fullname[0]) - 2);
		pfullname += T_strlen(pfullname);
		if (pfullname[-1] != '\\')
			*pfullname++ = '\\';
	}
	else
	{
		*pfullname++ = 'a' - 1 + drive;
		*pfullname++ = ':';
	}
	T_strcpy(pfullname, pdbname);
	T_strcpy(pdbstart, fullname);

	for(TCHAR*p = pdbstart; *p; p++)
		if (*p == '/')
			*p = '\\';

	// remove relative parts "./" and "../"
	while (TCHAR* p = T_strstr (pdbstart, TEXT("\\.\\")))
		T_strcpy(p, p + 2);

	while (TCHAR* p = T_strstr (pdbstart, TEXT("\\..\\")))
	{
		for (TCHAR* q = p - 1; q >= pdbstart; q--)
			if (*q == '\\')
			{
				T_strcpy(q, p + 3);
				break;
			}
	}
}

TCHAR* changeExtension(TCHAR* dbgname, const TCHAR* exename, const TCHAR* ext)
{
	T_strcpy(dbgname, exename);
	TCHAR *pDot = T_strrchr(dbgname, '.');
	if (!pDot || pDot <= T_strrchr(dbgname, '/') || pDot <= T_strrchr(dbgname, '\\'))
		T_strcat(dbgname, ext);
	else
		T_strcpy(pDot, ext);
	return dbgname;
}

int T_main(int argc, TCHAR* argv[])
{
	double Dversion = 2.072;
	const TCHAR* pdbref = 0;
	DebugLevel debug = DebugLevel{};

	CoInitialize(nullptr);

	while (argc > 1 && argv[1][0] == '-')
	{
		argv++;
		argc--;
		if (argv[0][1] == '-')
			break;
		if (argv[0][1] == 'D')
			Dversion = T_strtod(argv[0] + 2, 0);
		else if (argv[0][1] == 'C')
			Dversion = 0;
		else if (argv[0][1] == 'n')
			demangleSymbols = false;
		else if (argv[0][1] == 'e')
			useTypedefEnum = true;
		else if (!T_strncmp(&argv[0][1], TEXT("debug"), 5)) // debug[level]
		{
			debug = (DebugLevel)T_strtoul(&argv[0][6], 0, 0);
			if (!debug) {
				debug = DbgBasic;
			}

			fprintf(stderr, "Debug set to %x\n", debug);
		}
		else if (argv[0][1] == 's' && argv[0][2])
			dotReplacementChar = (char)argv[0][2];
		else if (argv[0][1] == 'p' && argv[0][2])
			pdbref = argv[0] + 2;
		else
			fatal("unknown option: " SARG, argv[0]);
	}

	if (argc < 2)
	{
		printf("Convert DMD CodeView/DWARF debug information to PDB files, Version %g\n", VERSION);
		printf("Copyright (c) 2009-2012 by Rainer Schuetze, All Rights Reserved\n");
		printf("\n");
		printf("License for redistribution is given by the Artistic License 2.0\n");
		printf("see file LICENSE for further details\n");
		printf("\n");
		printf("usage: " SARG " [-D<version>|-C|-n|-e|-s<C>|-p<embedded-pdb>] <exe-file> [new-exe-file] [pdb-file]\n", argv[0]);
		return -1;
	}

	PEImage exe, dbg, *img = NULL;
	TCHAR dbgname[MAX_PATH];

	if (!exe.loadExe(argv[1]))
		fatal(SARG ": %s", argv[1], exe.getLastError());
	if (exe.countCVEntries() || exe.hasDWARF())
		img = &exe;
	else
	{
		// try DBG file alongside executable
		changeExtension(dbgname, argv[1], TEXT(".dbg"));
		struct _stat buffer;
		if (T_stat(dbgname, &buffer) != 0)
			fatal(SARG ": no codeview debug entries found", argv[1]);
		if (!dbg.loadExe(dbgname))
			fatal(SARG ": %s", dbgname, dbg.getLastError());
		if (dbg.countCVEntries() == 0)
			fatal(SARG ": no codeview debug entries found", dbgname);

		img = &dbg;
	}

	CV2PDB cv2pdb(*img, debug);
	cv2pdb.Dversion = Dversion;
	cv2pdb.initLibraries();

	TCHAR* outname = argv[1];
	if (argc > 2 && argv[2][0])
		outname = argv[2];

	TCHAR pdbname[260];
	if (argc > 3)
		T_strcpy (pdbname, argv[3]);
	else
	{
		T_strcpy (pdbname, outname);
		TCHAR *pDot = T_strrchr (pdbname, '.');
		if (!pDot || pDot <= T_strrchr (pdbname, '/') || pDot <= T_strrchr (pdbname, '\\'))
			T_strcat (pdbname, TEXT(".pdb"));
		else
			T_strcpy (pDot, TEXT(".pdb"));
	}
	makefullpath(pdbname);

	T_unlink(pdbname);

	if(!cv2pdb.openPDB(pdbname, pdbref))
		fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

	if(exe.hasDWARF())
	{
		if(!exe.relocateDebugLineInfo(0x400000))
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if(!cv2pdb.createDWARFModules())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if(!cv2pdb.addDWARFTypes())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if(!cv2pdb.addDWARFLines())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addDWARFPublics())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.writeDWARFImage(outname))
			fatal(SARG ": %s", outname, cv2pdb.getLastError());
	}
	else
	{
		if (!cv2pdb.initSegMap())
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if (!cv2pdb.initGlobalSymbols())
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if (!cv2pdb.initGlobalTypes())
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if (!cv2pdb.createModules())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addTypes())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addSymbols())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addSrcLines())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addPublics())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!exe.isDBG())
 			if (!cv2pdb.writeImage(outname, exe))
				fatal(SARG ": %s", outname, cv2pdb.getLastError());
	}

	return 0;
}
<commit_msg>fix version display<commit_after>// Convert DMD CodeView debug information to PDB files
// Copyright (c) 2009-2010 by Rainer Schuetze, All Rights Reserved
//
// License for redistribution is given by the Artistic License 2.0
// see file LICENSE for further details

#include "PEImage.h"
#include "cv2pdb.h"
#include "symutil.h"

#include <direct.h>

double
#include "../VERSION"
;

#ifdef UNICODE
#define T_toupper	towupper
#define T_getdcwd	_wgetdcwd
#define T_strlen	wcslen
#define T_strcpy	wcscpy
#define T_strcat	wcscat
#define T_strstr	wcsstr
#define T_strncmp	wcsncmp
#define T_strtoul	wcstoul
#define T_strtod	wcstod
#define T_strrchr	wcsrchr
#define T_unlink	_wremove
#define T_main		wmain
#define SARG		"%S"
#define T_stat		_wstat
#else
#define T_toupper	toupper
#define T_getdcwd	_getdcwd
#define T_strlen	strlen
#define T_strcpy	strcpy
#define T_strcat	strcat
#define T_strstr	strstr
#define T_strncmp	strncmp
#define T_strtoul	strtoul
#define T_strtod	strtod
#define T_strrchr	strrchr
#define T_unlink	unlink
#define T_main		main
#define SARG		"%s"
#define T_stat		stat
#endif

void fatal(const char *message, ...)
{
	va_list argptr;
	va_start(argptr, message);
	vprintf(message, argptr);
	va_end(argptr);
	printf("\n");
	exit(1);
}

void makefullpath(TCHAR* pdbname)
{
	TCHAR* pdbstart = pdbname;
	TCHAR fullname[260];
	TCHAR* pfullname = fullname;

	int drive = 0;
	if (pdbname[0] && pdbname[1] == ':')
	{
		if (pdbname[2] == '\\' || pdbname[2] == '/')
			return;
		drive = T_toupper (pdbname[0]) - 'A' + 1;
		pdbname += 2;
	}
	else
	{
		drive = _getdrive();
	}

	if (*pdbname != '\\' && *pdbname != '/')
	{
		T_getdcwd(drive, pfullname, sizeof(fullname)/sizeof(fullname[0]) - 2);
		pfullname += T_strlen(pfullname);
		if (pfullname[-1] != '\\')
			*pfullname++ = '\\';
	}
	else
	{
		*pfullname++ = 'a' - 1 + drive;
		*pfullname++ = ':';
	}
	T_strcpy(pfullname, pdbname);
	T_strcpy(pdbstart, fullname);

	for(TCHAR*p = pdbstart; *p; p++)
		if (*p == '/')
			*p = '\\';

	// remove relative parts "./" and "../"
	while (TCHAR* p = T_strstr (pdbstart, TEXT("\\.\\")))
		T_strcpy(p, p + 2);

	while (TCHAR* p = T_strstr (pdbstart, TEXT("\\..\\")))
	{
		for (TCHAR* q = p - 1; q >= pdbstart; q--)
			if (*q == '\\')
			{
				T_strcpy(q, p + 3);
				break;
			}
	}
}

TCHAR* changeExtension(TCHAR* dbgname, const TCHAR* exename, const TCHAR* ext)
{
	T_strcpy(dbgname, exename);
	TCHAR *pDot = T_strrchr(dbgname, '.');
	if (!pDot || pDot <= T_strrchr(dbgname, '/') || pDot <= T_strrchr(dbgname, '\\'))
		T_strcat(dbgname, ext);
	else
		T_strcpy(pDot, ext);
	return dbgname;
}

int T_main(int argc, TCHAR* argv[])
{
	double Dversion = 2.072;
	const TCHAR* pdbref = 0;
	DebugLevel debug = DebugLevel{};

	CoInitialize(nullptr);

	while (argc > 1 && argv[1][0] == '-')
	{
		argv++;
		argc--;
		if (argv[0][1] == '-')
			break;
		if (argv[0][1] == 'D')
			Dversion = T_strtod(argv[0] + 2, 0);
		else if (argv[0][1] == 'C')
			Dversion = 0;
		else if (argv[0][1] == 'n')
			demangleSymbols = false;
		else if (argv[0][1] == 'e')
			useTypedefEnum = true;
		else if (!T_strncmp(&argv[0][1], TEXT("debug"), 5)) // debug[level]
		{
			debug = (DebugLevel)T_strtoul(&argv[0][6], 0, 0);
			if (!debug) {
				debug = DbgBasic;
			}

			fprintf(stderr, "Debug set to %x\n", debug);
		}
		else if (argv[0][1] == 's' && argv[0][2])
			dotReplacementChar = (char)argv[0][2];
		else if (argv[0][1] == 'p' && argv[0][2])
			pdbref = argv[0] + 2;
		else
			fatal("unknown option: " SARG, argv[0]);
	}

	if (argc < 2)
	{
		printf("Convert DMD CodeView/DWARF debug information to PDB files, Version %.02f\n", VERSION);
		printf("Copyright (c) 2009-2012 by Rainer Schuetze, All Rights Reserved\n");
		printf("\n");
		printf("License for redistribution is given by the Artistic License 2.0\n");
		printf("see file LICENSE for further details\n");
		printf("\n");
		printf("usage: " SARG " [-D<version>|-C|-n|-e|-s<C>|-p<embedded-pdb>] <exe-file> [new-exe-file] [pdb-file]\n", argv[0]);
		return -1;
	}

	PEImage exe, dbg, *img = NULL;
	TCHAR dbgname[MAX_PATH];

	if (!exe.loadExe(argv[1]))
		fatal(SARG ": %s", argv[1], exe.getLastError());
	if (exe.countCVEntries() || exe.hasDWARF())
		img = &exe;
	else
	{
		// try DBG file alongside executable
		changeExtension(dbgname, argv[1], TEXT(".dbg"));
		struct _stat buffer;
		if (T_stat(dbgname, &buffer) != 0)
			fatal(SARG ": no codeview debug entries found", argv[1]);
		if (!dbg.loadExe(dbgname))
			fatal(SARG ": %s", dbgname, dbg.getLastError());
		if (dbg.countCVEntries() == 0)
			fatal(SARG ": no codeview debug entries found", dbgname);

		img = &dbg;
	}

	CV2PDB cv2pdb(*img, debug);
	cv2pdb.Dversion = Dversion;
	cv2pdb.initLibraries();

	TCHAR* outname = argv[1];
	if (argc > 2 && argv[2][0])
		outname = argv[2];

	TCHAR pdbname[260];
	if (argc > 3)
		T_strcpy (pdbname, argv[3]);
	else
	{
		T_strcpy (pdbname, outname);
		TCHAR *pDot = T_strrchr (pdbname, '.');
		if (!pDot || pDot <= T_strrchr (pdbname, '/') || pDot <= T_strrchr (pdbname, '\\'))
			T_strcat (pdbname, TEXT(".pdb"));
		else
			T_strcpy (pDot, TEXT(".pdb"));
	}
	makefullpath(pdbname);

	T_unlink(pdbname);

	if(!cv2pdb.openPDB(pdbname, pdbref))
		fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

	if(exe.hasDWARF())
	{
		if(!exe.relocateDebugLineInfo(0x400000))
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if(!cv2pdb.createDWARFModules())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if(!cv2pdb.addDWARFTypes())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if(!cv2pdb.addDWARFLines())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addDWARFPublics())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.writeDWARFImage(outname))
			fatal(SARG ": %s", outname, cv2pdb.getLastError());
	}
	else
	{
		if (!cv2pdb.initSegMap())
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if (!cv2pdb.initGlobalSymbols())
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if (!cv2pdb.initGlobalTypes())
			fatal(SARG ": %s", argv[1], cv2pdb.getLastError());

		if (!cv2pdb.createModules())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addTypes())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addSymbols())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addSrcLines())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!cv2pdb.addPublics())
			fatal(SARG ": %s", pdbname, cv2pdb.getLastError());

		if (!exe.isDBG())
 			if (!cv2pdb.writeImage(outname, exe))
				fatal(SARG ": %s", outname, cv2pdb.getLastError());
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>

#include "lib/bios_opencv/frame_grabber/video_file.h"
#include "lib/bios_opencv/filter_chain/filter_chain.h"
#include "lib/bios_opencv/filter/all_filters.h"

using namespace std;
using namespace BiosOpenCV;

int main(int argc, const char * argv[])
{
  bool paused = false;

  // Set step to true to execute at least once to allow Display filters to initialize
  // an opencv window
  bool step = true;

  FilterChain filters;

  cv::Mat original;

#if defined(USE_VIDEO_FILE)
  std::string filename = "./video_samples/sample.mp4";
  if (argc >= 2) {
    filename = std::string(argv[1]);
  }
  VideoFile frameGrabber(filename);
  paused = true;
  std::cout << "Watch it. Video is currently paused. Press p to pause/unpause, s to step and esc to quit" << std::endl;
#endif

  filters.add(new GrabFrame(original, &frameGrabber));
  filters.add(new Display(original, "Original"));

  do {
    if (!paused || step) {
      filters.execute();
      step = false;
    }

    char key = cv::waitKey(10);
    if(key == 'p') {
      paused = !paused;
    } else if (key == 's') {
      step = true;
    } else if (key == 27) {
      break;
    }

  } while (true);

  return 0;
}
<commit_msg>Threshold to find potty backplate<commit_after>#include <iostream>

#include "lib/bios_opencv/frame_grabber/video_file.h"
#include "lib/bios_opencv/filter_chain/filter_chain.h"
#include "lib/bios_opencv/filter/all_filters.h"

using namespace std;
using namespace BiosOpenCV;

int main(int argc, const char * argv[])
{
  bool paused = false;

  // Set step to true to execute at least once to allow Display filters to initialize
  // an opencv window
  bool step = true;

  FilterChain filters;

  cv::Mat original;
  cv::Mat processed;

#if defined(USE_VIDEO_FILE)
  std::string filename = "./video_samples/sample.mp4";
  if (argc >= 2) {
    filename = std::string(argv[1]);
  }
  VideoFile frameGrabber(filename);
  paused = true;
  std::cout << "Watch it. Video is currently paused. Press p to pause/unpause, s to step and esc to quit" << std::endl;
#endif

  filters.add(new GrabFrame(original, &frameGrabber));
  filters.add(new GrayScale(original, processed));
  filters.add(new BinaryThreshold(processed, 140));
  filters.add(new Display(processed, "Processed"));

  do {
    if (!paused || step) {
      filters.execute();
      step = false;
    }

    char key = cv::waitKey(10);
    if(key == 'p') {
      paused = !paused;
    } else if (key == 's') {
      step = true;
    } else if (key == 27) {
      break;
    }

  } while (true);

  return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Fake Frog                                                                  *
 * An Arduino-based project to build a frog-shaped temperature logger.        *
 * Author: David Lougheed. Copyright 2017.                                    *
 ******************************************************************************/

#define VERSION "0.1.0"

// Includes

#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal.h>

#include <SD.h>
#include <RTClib.h>

// Compile-Time Settings

#define SERIAL_LOGGING          true    // Log to the serial display for debug.
#define FILE_LOGGING            true    // Log to file on SD card. (recommended)
#define DISPLAY_ENABLED         true    // Show menus and information on an LCD.
#define NUM_SAMPLES             10      // Samples get averaged to reduce noise.
#define SAMPLE_DELAY            10      // Milliseconds between samples.

// Hardware Settings

#define THERMISTOR_PIN          A0
#define THERMISTOR_SERIES_RES   10000
#define THERMISTOR_RES_NOM      10000   // Nominal resistance, R0.
#define THERMISTOR_B_COEFF      3950    // Beta coefficient of the thermistor.
#define THERMISTOR_TEMP_NOM     25      // Nominal temperature of R0.

#define SD_CARD_PIN             10
#define RTC_PIN_1               4
#define RTC_PIN_2               5
#define LCD_PIN_RS              6
#define LCD_PIN_EN              7
#define LCD_PIN_DB4             8
#define LCD_PIN_DB5             9
#define LCD_PIN_DB6             11
#define LCD_PIN_DB7             12

#define LCD_ROWS                2
#define LCD_COLUMNS             16

#define RTC_TYPE                RTC_PCF8523

// Other Compile-Time Constants

#define MAX_LOG_FILES           1000
#define MAX_DATA_FILES          1000

// Globals

bool serial_logging_started = false;

File log_file;
File data_file;

RTC_TYPE rtc;

LiquidCrystal* lcd;

// To save memory, use global data point variables.
DateTime now;
char formatted_timestamp[] = "0000-00-00T00:00:00";
char* data_file_entry_buffer = (char*) malloc(sizeof(char) * 50);
double latest_temperature;

/*
    DISPLAY MODES (ALL WITH LOGGING)
    0: Idle
    1: Information (clock, space usage)
    2: RTC Editor
*/
uint8_t display_mode = 0;

uint16_t i; // 16-bit iterator

// Utility Methods

// Log a generic message.
void log(const char* msg, bool with_newline = true) {
    if (SERIAL_LOGGING) {
        if(!serial_logging_started) {
            Serial.begin(9600);
            Serial.println();
            serial_logging_started = true;
        }

        if (with_newline) {
            Serial.println(msg);
        } else {
            Serial.print(msg);
        }
    }

    if (FILE_LOGGING) {
        if (log_file) {
            if (with_newline) {
                log_file.println(msg);
            } else {
                log_file.print(msg);
            }
            log_file.flush();
        }
    }
}

// Log an error message. Uses standard log method, then hangs forever.
void log_error(const char* msg, bool with_newline = true) {
    log(msg, with_newline);
    while (true); // Loop forever
}

void update_screen() {
    if (DISPLAY_ENABLED && lcd) {
        lcd->clear();

        switch (display_mode) {
            case 1:
                lcd->print("TBD");
                break;
            case 2:
                lcd->print("TBD");
                break;
            case 0:
            default:
                break;
        }
    }
}

void switch_display_mode(uint8_t m) {
    display_mode = m;
    update_screen();
}

// Data Methods

// Update the global formatted timestamp string with the contents of 'now'.
void update_formatted_timestamp() {
    sprintf(formatted_timestamp, "%u-%u-%uT%u:%u:%u", now.year(),
        now.month(), now.day(), now.hour(), now.minute(), now.second());
}

void take_reading() {
    now = rtc.now();

    latest_temperature = 0;

    for (i = 0; i < NUM_SAMPLES; i++) {
        latest_temperature += (double) analogRead(THERMISTOR_PIN);
        delay(SAMPLE_DELAY);
    }

    // Formulas: T = 1/(1/B * ln(R/R_0) + (1/T0)) - 273.15 (celcius)
    //           R = sr / (1023 / mean_of_samples - 1)
    //           sr = thermistor series resistance

    latest_temperature = THERMISTOR_SERIES_RES
        / (1023 / (latest_temperature / NUM_SAMPLES) - 1); // Resistance
    latest_temperature = 1 / ((log(latest_temperature / THERMISTOR_RES_NOM)
        / THERMISTOR_B_COEFF) + 1 / (THERMISTOR_TEMP_NOM + 273.15)) - 273.15;
}

void save_reading_to_card() {
    if (data_file) {
        update_formatted_timestamp();
        sprintf(data_file_entry_buffer, "%.2f,%s", latest_temperature,
            formatted_timestamp);
        data_file.println(data_file_entry_buffer);
        data_file.flush();
    }
}

// Main Methods

void setup() {
    // TODO: Set up pins

    // SET UP EXTERNAL ANALOG VOLTAGE REFERENCE
    // Typically from 3.3V Arduino supply. This reduces the voltage noise seen
    // from reading analog values.
    analogReference(EXTERNAL);

    // INITIALIZE SD CARD
    log("Initializing SD card... ", false);
    pinMode(SD_CARD_PIN, OUTPUT);
    if (!SD.begin()) {
        log_error("Failed.");
    }
    log("Done.");

    // SET UP LOG FILE
    if (FILE_LOGGING) {
        log("Creating log file... ", false);
        char log_file_name[] = "log_000.txt";
        for (i = 0; i < MAX_LOG_FILES; i++) {
            // Increment until we can find a log file slot.

            // Need to add 32 to get ASCII number characters.
            log_file_name[6] = i / 100 + 32;
            log_file_name[7] = i / 10 + 32;
            log_file_name[8] = i % 10 + 32;

            if (!SD.exists(log_file_name)) {
                log_file = SD.open(log_file_name, FILE_WRITE);
                break;
            }
        }
        if (log_file) {
            log("Done.");
        } else {
            log_error("Failed.");
        }
    }

    // SET UP RTC
    log("Initializing RTC...", false);
    Wire.begin();
    if (!rtc.begin()) {
        log_error("Failed.");
    }
    log("Done.");

    // TODO: Calibrate RTC

    // SET UP DATA FILE
    log("Creating data file...");
    char data_file_name[] = "data_000.csv";
    for (i = 0; i < MAX_DATA_FILES; i++) {
        // Increment until we can find a data file slot.

        // Need to add 32 to get ASCII digit characters.
        data_file_name[6] = i / 100 + 32;
        data_file_name[7] = i / 10 + 32;
        data_file_name[8] = i % 10 + 32;

        if (!SD.exists(data_file_name)) {
            data_file = SD.open(data_file_name, FILE_WRITE);
            break;
        }
    }
    if (data_file) {
        log("Done.");
    } else {
        log_error("Failed.");
    }

    // PRINT DATA FILE CSV HEADERS
    data_file.println("Timestamp,Temperature");
    data_file.flush();

    // SET UP LCD
    if (DISPLAY_ENABLED) {
        lcd = new LiquidCrystal(LCD_PIN_RS, LCD_PIN_EN, LCD_PIN_DB4,
            LCD_PIN_DB5, LCD_PIN_DB6, LCD_PIN_DB7);
        lcd->begin(LCD_COLUMNS, LCD_ROWS);
    }

    // Finished everything!
    now = rtc.now();
    update_formatted_timestamp();
    log("Data logger started at ", false);
    log(formatted_timestamp, false);
    log(". Software version: ", false);
    log(VERSION);
}

void loop() {
    // TODO: (Optional) Exit sleep

    take_reading();
    save_reading_to_card();

    // TODO: (Optional) Enter sleep

    delay(1000);
}
<commit_msg>Move temperature calculation into a dedicated function (for future re-use with error calculation).<commit_after>/******************************************************************************
 * Fake Frog                                                                  *
 * An Arduino-based project to build a frog-shaped temperature logger.        *
 * Author: David Lougheed. Copyright 2017.                                    *
 ******************************************************************************/

#define VERSION "0.1.0"

// Includes

#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal.h>

#include <SD.h>
#include <RTClib.h>

// Compile-Time Settings

#define SERIAL_LOGGING          true    // Log to the serial display for debug.
#define FILE_LOGGING            true    // Log to file on SD card. (recommended)
#define DISPLAY_ENABLED         true    // Show menus and information on an LCD.
#define NUM_SAMPLES             10      // Samples get averaged to reduce noise.
#define SAMPLE_DELAY            10      // Milliseconds between samples.

// Hardware Settings

#define THERMISTOR_PIN          A0
#define THERMISTOR_SERIES_RES   10000
#define THERMISTOR_RES_NOM      10000   // Nominal resistance, R0.
#define THERMISTOR_B_COEFF      3950    // Beta coefficient of the thermistor.
#define THERMISTOR_TEMP_NOM     25      // Nominal temperature of R0.

#define SD_CARD_PIN             10
#define RTC_PIN_1               4
#define RTC_PIN_2               5
#define LCD_PIN_RS              6
#define LCD_PIN_EN              7
#define LCD_PIN_DB4             8
#define LCD_PIN_DB5             9
#define LCD_PIN_DB6             11
#define LCD_PIN_DB7             12

#define LCD_ROWS                2
#define LCD_COLUMNS             16

#define RTC_TYPE                RTC_PCF8523

// Other Compile-Time Constants

#define MAX_LOG_FILES           1000
#define MAX_DATA_FILES          1000

// Globals

bool serial_logging_started = false;

File log_file;
File data_file;

RTC_TYPE rtc;

LiquidCrystal* lcd;

// To save memory, use global data point variables.
DateTime now;
char formatted_timestamp[] = "0000-00-00T00:00:00";
char* data_file_entry_buffer = (char*) malloc(sizeof(char) * 50);
double latest_resistance;
double latest_temperature;

/*
    DISPLAY MODES (ALL WITH LOGGING)
    0: Idle
    1: Information (clock, space usage)
    2: RTC Editor
*/
uint8_t display_mode = 0;

uint16_t i; // 16-bit iterator

// Utility Methods

// Log a generic message.
void log(const char* msg, bool with_newline = true) {
    if (SERIAL_LOGGING) {
        if(!serial_logging_started) {
            Serial.begin(9600);
            Serial.println();
            serial_logging_started = true;
        }

        if (with_newline) {
            Serial.println(msg);
        } else {
            Serial.print(msg);
        }
    }

    if (FILE_LOGGING) {
        if (log_file) {
            if (with_newline) {
                log_file.println(msg);
            } else {
                log_file.print(msg);
            }
            log_file.flush();
        }
    }
}

// Log an error message. Uses standard log method, then hangs forever.
void log_error(const char* msg, bool with_newline = true) {
    log(msg, with_newline);
    while (true); // Loop forever
}

void update_screen() {
    if (DISPLAY_ENABLED && lcd) {
        lcd->clear();

        switch (display_mode) {
            case 1:
                lcd->print("TBD");
                break;
            case 2:
                lcd->print("TBD");
                break;
            case 0:
            default:
                break;
        }
    }
}

void switch_display_mode(uint8_t m) {
    display_mode = m;
    update_screen();
}

// Data Methods

// Update the global formatted timestamp string with the contents of 'now'.
void update_formatted_timestamp() {
    sprintf(formatted_timestamp, "%u-%u-%uT%u:%u:%u", now.year(),
        now.month(), now.day(), now.hour(), now.minute(), now.second());
}

double resistance_to_temperature(double resistance) {
    // Formula: T = 1/(1/B * ln(R/R_0) + (1/T0)) - 273.15 (celcius)
    return 1 / ((log(resistance / THERMISTOR_RES_NOM) / THERMISTOR_B_COEFF) + 1
        / (THERMISTOR_TEMP_NOM + 273.15)) - 273.15;
}

void take_reading() {
    now = rtc.now();

    latest_resistance = 0;

    for (i = 0; i < NUM_SAMPLES; i++) {
        latest_resistance += (double) analogRead(THERMISTOR_PIN);
        delay(SAMPLE_DELAY);
    }

    // Formulas: R = sr / (1023 / mean_of_samples - 1)
    //           sr = thermistor series resistance

    latest_resistance = THERMISTOR_SERIES_RES
        / (1023 / (latest_resistance / NUM_SAMPLES) - 1); // Resistance
    latest_temperature = resistance_to_temperature(latest_resistance);

    // TODO: Error calculations
}

void save_reading_to_card() {
    if (data_file) {
        update_formatted_timestamp();
        sprintf(data_file_entry_buffer, "%.2f,%s", latest_temperature,
            formatted_timestamp);
        data_file.println(data_file_entry_buffer);
        data_file.flush();
    }
}

// Main Methods

void setup() {
    // TODO: Set up pins

    // SET UP EXTERNAL ANALOG VOLTAGE REFERENCE
    // Typically from 3.3V Arduino supply. This reduces the voltage noise seen
    // from reading analog values.
    analogReference(EXTERNAL);

    // INITIALIZE SD CARD
    log("Initializing SD card... ", false);
    pinMode(SD_CARD_PIN, OUTPUT);
    if (!SD.begin()) {
        log_error("Failed.");
    }
    log("Done.");

    // SET UP LOG FILE
    if (FILE_LOGGING) {
        log("Creating log file... ", false);
        char log_file_name[] = "log_000.txt";
        for (i = 0; i < MAX_LOG_FILES; i++) {
            // Increment until we can find a log file slot.

            // Need to add 32 to get ASCII number characters.
            log_file_name[6] = i / 100 + 32;
            log_file_name[7] = i / 10 + 32;
            log_file_name[8] = i % 10 + 32;

            if (!SD.exists(log_file_name)) {
                log_file = SD.open(log_file_name, FILE_WRITE);
                break;
            }
        }
        if (log_file) {
            log("Done.");
        } else {
            log_error("Failed.");
        }
    }

    // SET UP RTC
    log("Initializing RTC...", false);
    Wire.begin();
    if (!rtc.begin()) {
        log_error("Failed.");
    }
    log("Done.");

    // TODO: Calibrate RTC

    // SET UP DATA FILE
    log("Creating data file...");
    char data_file_name[] = "data_000.csv";
    for (i = 0; i < MAX_DATA_FILES; i++) {
        // Increment until we can find a data file slot.

        // Need to add 32 to get ASCII digit characters.
        data_file_name[6] = i / 100 + 32;
        data_file_name[7] = i / 10 + 32;
        data_file_name[8] = i % 10 + 32;

        if (!SD.exists(data_file_name)) {
            data_file = SD.open(data_file_name, FILE_WRITE);
            break;
        }
    }
    if (data_file) {
        log("Done.");
    } else {
        log_error("Failed.");
    }

    // PRINT DATA FILE CSV HEADERS
    data_file.println("Timestamp,Temperature");
    data_file.flush();

    // SET UP LCD
    if (DISPLAY_ENABLED) {
        lcd = new LiquidCrystal(LCD_PIN_RS, LCD_PIN_EN, LCD_PIN_DB4,
            LCD_PIN_DB5, LCD_PIN_DB6, LCD_PIN_DB7);
        lcd->begin(LCD_COLUMNS, LCD_ROWS);
    }

    // Finished everything!
    now = rtc.now();
    update_formatted_timestamp();
    log("Data logger started at ", false);
    log(formatted_timestamp, false);
    log(". Software version: ", false);
    log(VERSION);
}

void loop() {
    // TODO: (Optional) Exit sleep

    take_reading();
    save_reading_to_card();

    // TODO: (Optional) Enter sleep

    delay(1000);
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

struct tree
{
	tree *leftSon;
	tree *rightSon;
	int value;
};

void addNumber(tree *binaryTree, int value)
{
	if (value == binaryTree->value)
	{
		cout << "     " << endl;
		return;
	}
	else
	{
		if (value < binaryTree->value)
		{
			if (!binaryTree->leftSon)
			{
				binaryTree->leftSon = new tree{ nullptr, nullptr, value };
			}
			else
			{
				addNumber(binaryTree->leftSon, value);
			}
		}
		else
		{
			if (!binaryTree->rightSon)
			{
				binaryTree->rightSon = new tree{ nullptr, nullptr, value };
			}
			else
			{
				addNumber(binaryTree->rightSon, value);
			}
		}
	}
}

bool foundingOfNumber(tree *binaryTree, int value)
{
	if (binaryTree->value != value)
	{
		if (binaryTree->value > value)
		{
			if (binaryTree->leftSon)
			{
				return foundingOfNumber(binaryTree->leftSon, value);
			}
			else
			{
				cout << "    " << endl << endl;
				return false;
			}
		}
		if (binaryTree->value < value)
		{
			if (binaryTree->rightSon)
			{
				return foundingOfNumber(binaryTree->rightSon, value);
			}
			else
			{
				cout << "    " << endl << endl;
				return false;
			}
		}
	}
	else
	{
		cout << "    " << endl << endl;
		return true;
	}
}

void printBinaryTreeIncrease(tree *binaryTree)
{
	if (binaryTree->leftSon)
	{
		printBinaryTreeIncrease(binaryTree->leftSon);
	}
	cout << binaryTree->value << " ";
	if (binaryTree->rightSon)
	{
		printBinaryTreeIncrease(binaryTree->rightSon);
	}
}

void printBinaryTreeDecrease(tree *binaryTree)
{
	if (binaryTree->rightSon)
	{
		printBinaryTreeDecrease(binaryTree->rightSon);
	}
	cout << binaryTree->value << " ";
	if (binaryTree->leftSon)
	{
		printBinaryTreeDecrease(binaryTree->leftSon);
	}
}

void deleteElementFromTree(tree *binaryTree, int value)
{
	if ((binaryTree->value > value) || (binaryTree->value < value))
	{
		if (binaryTree->value > value)
		{
			deleteElementFromTree(binaryTree->leftSon, value);
			return;
		}
		else
		{
			deleteElementFromTree(binaryTree->rightSon, value);
			return;
		}
	}
	if (!(binaryTree->leftSon || binaryTree->rightSon))
	{
		delete binaryTree;
		binaryTree = nullptr;
		return;
	}
	if ((!binaryTree->leftSon) && binaryTree->rightSon)
	{
		tree *oldElement = binaryTree;
		binaryTree->rightSon = binaryTree->rightSon;
		delete oldElement;
		return;
	}
	if (binaryTree->leftSon && (!binaryTree->rightSon))
	{
		tree *oldElement = binaryTree;
		binaryTree->rightSon = binaryTree->leftSon;
		delete oldElement;
		return;
	}
}

int main()
{
	setlocale(LC_ALL, "Russian");
	int command = -1;
	cout << " ,  ,     ";
	int numberInRoot = 0;
	cin >> numberInRoot;
	cout << endl;
	tree *root = new tree{ nullptr, nullptr, numberInRoot };
	cout << "  " << endl << endl;
	while (command != 0)
	{
		cout << " 0  " << endl;
		cout << " 1   " << endl;
		cout << " 2   " << endl;
		cout << " 3      " << endl;
		cout << " 4       " << endl;
		cout << " 5       " << endl;
		cin >> command;
		switch (command)
		{
		case (1):
		{
			cout << " ,      ";
			int number = 0;
			cin >> number;
			cout << endl;
			addNumber(root, number);
			break;
		}
		case(2):
		{
			cout << "    : ";
			int number = 0;
			cin >> number;
			cout << endl;
			if (foundingOfNumber(root, number))
			{
				deleteElementFromTree(root, number);
			}
			break;
		}
		case(3):
		{
			cout << "    ";
			int number = 0;
			cin >> number;
			cout << endl;
			foundingOfNumber(root, number);
			break;
		}
		case(4):
		{
			printBinaryTreeIncrease(root);
			cout << endl;
			break;
		}
		case(5):
		{
			printBinaryTreeDecrease(root);
			cout << endl;
			break;
		}
		}
	}
	return 0;
}<commit_msg>Complete Deleting end finish HomeWork 7.1<commit_after>#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

struct tree
{
	tree *leftSon;
	tree *rightSon;
	int value;
};

void addNumber(tree *&binaryTree, int value)
{
	if (value == binaryTree->value)
	{
		cout << "     " << endl;
		return;
	}
	else
	{
		if (value < binaryTree->value)
		{
			if (!binaryTree->leftSon)
			{
				binaryTree->leftSon = new tree{ nullptr, nullptr, value };
			}
			else
			{
				addNumber(binaryTree->leftSon, value);
			}
		}
		else
		{
			if (!binaryTree->rightSon)
			{
				binaryTree->rightSon = new tree{ nullptr, nullptr, value };
			}
			else
			{
				addNumber(binaryTree->rightSon, value);
			}
		}
	}
}

bool foundingOfNumber(tree *&binaryTree, int value)
{
	if (binaryTree->value != value)
	{
		if (binaryTree->value > value)
		{
			if (binaryTree->leftSon)
			{
				return foundingOfNumber(binaryTree->leftSon, value);
			}
			else
			{
				cout << "    " << endl << endl;
				return false;
			}
		}
		if (binaryTree->value < value)
		{
			if (binaryTree->rightSon)
			{
				return foundingOfNumber(binaryTree->rightSon, value);
			}
			else
			{
				cout << "    " << endl << endl;
				return false;
			}
		}
	}
	else
	{
		cout << "    " << endl << endl;
		return true;
	}
}

void printBinaryTreeIncrease(tree *&binaryTree)
{
	if (binaryTree->leftSon)
	{
		printBinaryTreeIncrease(binaryTree->leftSon);
	}
	cout << binaryTree->value << " ";
	if (binaryTree->rightSon)
	{
		printBinaryTreeIncrease(binaryTree->rightSon);
	}
}

void printBinaryTreeDecrease(tree *&binaryTree)
{
	if (binaryTree->rightSon)
	{
		printBinaryTreeDecrease(binaryTree->rightSon);
	}
	cout << binaryTree->value << " ";
	if (binaryTree->leftSon)
	{
		printBinaryTreeDecrease(binaryTree->leftSon);
	}
}

void deleteElementFromTree(tree *&binaryTree, int value)
{
	if ((binaryTree->value > value) || (binaryTree->value < value))
	{
		if (binaryTree->value > value)
		{
			deleteElementFromTree(binaryTree->leftSon, value);
			return;
		}
		else
		{
			deleteElementFromTree(binaryTree->rightSon, value);
			return;
		}
	}
	if (!(binaryTree->leftSon || binaryTree->rightSon))
	{
		delete binaryTree;
		binaryTree = nullptr;
		return;
	}
	if ((!binaryTree->leftSon) && binaryTree->rightSon)
	{
		tree *oldElement = binaryTree;
		binaryTree = binaryTree->rightSon;
		delete oldElement;
		oldElement = nullptr;
		return;
	}
	if (binaryTree->leftSon && (!binaryTree->rightSon))
	{
		tree *oldElement = binaryTree;
		binaryTree = binaryTree->leftSon;
		delete oldElement;
		oldElement = nullptr;
		return;
	}
	tree *&newElement = binaryTree->leftSon;
	while (newElement->rightSon)
	{
		newElement = newElement->rightSon;
	}
	binaryTree->value = newElement->value;
	deleteElementFromTree(newElement, newElement->value);
}

int main()
{
	setlocale(LC_ALL, "Russian");
	int command = -1;
	cout << " ,  ,     ";
	int numberInRoot = 0;
	cin >> numberInRoot;
	cout << endl;
	tree *root = new tree{ nullptr, nullptr, numberInRoot };
	cout << "  " << endl << endl;
	while (command != 0)
	{
		cout << " 0  " << endl;
		cout << " 1   " << endl;
		cout << " 2   " << endl;
		cout << " 3      " << endl;
		cout << " 4       " << endl;
		cout << " 5       " << endl;
		cin >> command;
		switch (command)
		{
		case (1):
		{
			cout << " ,      ";
			int number = 0;
			cin >> number;
			cout << endl;
			addNumber(root, number);
			break;
		}
		case(2):
		{
			cout << "    : ";
			int number = 0;
			cin >> number;
			cout << endl;
			if (foundingOfNumber(root, number))
			{
				deleteElementFromTree(root, number);
			}
			break;
		}
		case(3):
		{
			cout << "    ";
			int number = 0;
			cin >> number;
			cout << endl;
			foundingOfNumber(root, number);
			break;
		}
		case(4):
		{
			printBinaryTreeIncrease(root);
			cout << endl;
			break;
		}
		case(5):
		{
			printBinaryTreeDecrease(root);
			cout << endl;
			break;
		}
		}
	}
	return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2010 - 2013 Leap Motion. All rights reserved. Proprietary and confidential.
#include "stdafx.h"
#include "CoreThreadTest.h"
#include "Autowired.h"
#include "TestFixtures/SimpleThreaded.h"
#include <boost/thread/thread.hpp>
#include <boost/thread.hpp>

class SpamguardTest:
  public CoreThread
{
public:
  SpamguardTest(void):
    m_hit(false),
    m_multiHit(false)
  {
  }

  bool m_hit;
  bool m_multiHit;

  void Run(void) override {
    if(m_hit) {
      m_multiHit = true;
      return;
    }

    m_hit = false;

    boost::unique_lock<boost::mutex> lk(m_lock);
    m_stateCondition.wait(lk, [this] () {return ShouldStop();});
  }
};

TEST_F(CoreThreadTest, VerifyStartSpam) {
  // Create our thread class:
  AutoRequired<SpamguardTest> instance;

  m_create->InitiateCoreThreads();

  // This shouldn't cause another thread to be created:
  instance->Start(std::shared_ptr<Object>(new Object));

  EXPECT_FALSE(instance->m_multiHit) << "Thread was run more than once unexpectedly";
}

class InvokesIndefiniteWait:
  public CoreThread
{
public:
  virtual void Run(void) override {
    AcceptDispatchDelivery();

    // Wait for one event using an indefinite timeout, then quit:
    WaitForEvent(boost::chrono::steady_clock::time_point::max());
  }
};

TEST_F(CoreThreadTest, VerifyIndefiniteDelay) {
  AutoRequired<InvokesIndefiniteWait> instance;
  m_create->InitiateCoreThreads();

  // Verify that the instance does not quit until we pend something:
  ASSERT_FALSE(instance->WaitFor(boost::chrono::milliseconds(10))) << "Thread instance exited prematurely, when it should have been waiting indefinitely";

  // Now we pend an arbitrary event and verify that we can wait:
  *instance += [] {};
  ASSERT_TRUE(instance->WaitFor(boost::chrono::milliseconds(10))) << "Instance did not exit after an event was pended which should have woken up its dispatch loop";
}

TEST_F(CoreThreadTest, VerifyNestedTermination) {
  std::shared_ptr<SimpleThreaded> st;

  // Insert a thread into a second-order subcontext:
  {
    AutoCreateContext outer;
    CurrentContextPusher outerPshr(outer);
    AutoRequired<SimpleThreaded>();
    outer->InitiateCoreThreads();

    {
      AutoCreateContext ctxt;
      CurrentContextPusher pshr(ctxt);
      ctxt->InitiateCoreThreads();
      st = AutoRequired<SimpleThreaded>();
    }
  }

  // Everything should be running by now:
  ASSERT_TRUE(st->IsRunning()) << "Child thread was not running as expected";

  // Shut down the enclosing context:
  m_create->SignalTerminate(true);

  // Verify that the child thread has stopped:
  ASSERT_FALSE(st->IsRunning()) << "Child thread was running even though the enclosing context was terminated";
}

class SleepEvent : public virtual EventReceiver
{
public:
  virtual Deferred SleepFor(int seconds) = 0;
  virtual Deferred SleepForThenThrow(int seconds) = 0;
};

class ListenThread :
  public CoreThread,
  public SleepEvent
{
public:
  ListenThread() : CoreThread("ListenThread") {}

  Deferred SleepFor(int seconds) override {
    boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
    if(ShouldStop())
      throw std::runtime_error("Execution aborted");

    return Deferred(this);
  }

  Deferred SleepForThenThrow(int seconds) override {
    return Deferred(this);
  }
};

TEST_F(CoreThreadTest, VerifyDispatchQueueShutdown) {
  AutoCreateContext ctxt;
  CurrentContextPusher pusher(ctxt);

  AutoRequired<ListenThread> listener;
  try
  {
    ctxt->InitiateCoreThreads();
    listener->DelayUntilCanAccept();

    AutoFired<SleepEvent> evt;

    // Spam in a bunch of events:
    for(size_t i = 100; i--;)
      evt(&SleepEvent::SleepFor)(0);

    // Graceful termination then enclosing context shutdown:
    listener->Stop(true);
    ctxt->SignalShutdown(true);
  }
  catch (...) {}

  ASSERT_EQ(listener->GetDispatchQueueLength(), static_cast<size_t>(0));
}

TEST_F(CoreThreadTest, VerifyNoLeakOnExecptions) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<ListenThread> listener;
  std::shared_ptr<std::string> value(new std::string("sentinal"));

  std::weak_ptr<std::string> watcher(value);
  try
  {
    ctxt->InitiateCoreThreads();
    listener->DelayUntilCanAccept();

    *listener += [value] { throw std::exception(); };
    value.reset();
    ctxt->SignalShutdown(true);
  }
  catch (...) {}

  ASSERT_TRUE(watcher.expired()) << "Leaked memory on exception in a dispatch event";
}

TEST_F(CoreThreadTest, VerifyDelayedDispatchQueueSimple) {
  // Run our threads immediately, no need to wait
  m_create->InitiateCoreThreads();

  // Create a thread which we'll use just to pend dispatch events:
  AutoRequired<CoreThread> t;

  // Thread should be running by now:
  ASSERT_TRUE(t->IsRunning()) << "Thread added to a running context was not marked running";

  // Delay until the dispatch loop is actually running, then wait an additional 1ms to let the
  // WaitForEvent call catch on:
  t->DelayUntilCanAccept();
  boost::this_thread::sleep_for(boost::chrono::milliseconds(1));

  // These are flags--we'll set them to true as the test proceeds
  std::shared_ptr<bool> x(new bool(false));
  std::shared_ptr<bool> y(new bool(false));

  // Pend a delayed event first, and then an immediate event right afterwards:
  *t += boost::chrono::milliseconds(25), [x] { *x = true; };
  *t += [y] { *y = true; };

  // Verify that, after 1ms, the first event is called and the second event is NOT called:
  boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
  ASSERT_TRUE(*y) << "A simple ready call was not dispatched within 10ms of being pended";
  ASSERT_FALSE(*x) << "An event which should not have been executed for 25ms was executed early";

  // Now delay another 90ms and see if the second event got called:
  boost::this_thread::sleep_for(boost::chrono::milliseconds(90));
  ASSERT_TRUE(*x) << "A delayed event was not made ready and executed as expected";
}

TEST_F(CoreThreadTest, VerifyNoDelayDoubleFree) {
  m_create->InitiateCoreThreads();

  // We won't actually be referencing this, we just want to make sure it's not destroyed early
  std::shared_ptr<bool> x(new bool);

  // This deferred pend will never actually be executed:
  AutoRequired<CoreThread> t;
  t->DelayUntilCanAccept();
  *t += boost::chrono::hours(1), [x] {};

  // Verify that we have exactly one pended event at this point.
  ASSERT_EQ(1UL, t->GetDispatchQueueLength()) << "Dispatch queue had an unexpected number of pended events";

  // Verify that the shared pointer isn't unique at this point.  If it is, it's because our CoreThread deleted
  // the event even though it was supposed to have pended it.
  ASSERT_FALSE(x.unique()) << "A pended event was freed before it was called, and appears to be present in a dispatch queue";
}

TEST_F(CoreThreadTest, VerifyDoublePendedDispatchDelay) {
  // Immediately pend threads:
  m_create->InitiateCoreThreads();

  // Some variables that we will set to true as the test proceeds:
  std::shared_ptr<bool> x(new bool(false));
  std::shared_ptr<bool> y(new bool(false));

  // Create a thread as before, and pend a few events.  The order, here, is important.  We intentionally
  // pend an event that won't happen for awhile, in order to trick the dispatch queue into waiting for
  // a lot longer than it should for the next event.
  AutoRequired<CoreThread> t;
  t->DelayUntilCanAccept();
  *t += boost::chrono::hours(1), [x] { *x = true; };

  // Now pend an event that will be ready just about right away:
  *t += boost::chrono::nanoseconds(1), [y] { *y = true; };

  // Delay for a short period of time, then check our variable states:
  boost::this_thread::sleep_for(boost::chrono::milliseconds(10));

  // This one shouldn't have been hit yet, it isn't scheduled to be hit for 10s
  ASSERT_FALSE(*x) << "A delayed dispatch was invoked extremely early";

  // This one should have been ready almost at the same time as it was pended
  ASSERT_TRUE(*y) << "An out-of-order delayed dispatch was not executed in time as expected";
}

TEST_F(CoreThreadTest, VerifyTimedSort) {
  m_create->InitiateCoreThreads();
  AutoRequired<CoreThread> t;

  std::vector<size_t> v;

  // Pend a stack of lambdas.  Each lambda waits 3i milliseconds, and pushes the value
  // i to the back of a vector.  If the delay method is implemented correctly, the resulting
  // vector will always wind up sorted, no matter how we push elements to the queue.
  // To doubly verify this property, we don't trivially increment i from the minimum to the
  // maximum--rather, we use a simple PRNG called a linear congruential generator and hop around
  // the interval [1...12] instead.
  for(size_t i = 1; i != 0; i = (i * 5 + 1) % 16)
    *t += boost::chrono::milliseconds(i * 3), [&v, i] { v.push_back(i); };

  // Delay 50ms for the thread to finish up.  Technically this is 11ms more than we need.
  boost::this_thread::sleep_for(boost::chrono::seconds(1));

  // Verify that the resulting vector is sorted.
  ASSERT_TRUE(std::is_sorted(v.begin(), v.end())) << "A timed sort implementation did not generate a sorted sequence as expected";
}

TEST_F(CoreThreadTest, VerifyPendByTimePoint) {
  m_create->InitiateCoreThreads();
  AutoRequired<CoreThread> t;
  t->DelayUntilCanAccept();

  // Pend by an absolute time point, nothing really special here
  std::shared_ptr<bool> x(new bool(false));
  *t += (boost::chrono::high_resolution_clock::now() + boost::chrono::milliseconds(1)), [&x] { *x = true; };

  // Verify that we hit this after one ms of delay
  ASSERT_FALSE(*x) << "A timepoint-based delayed dispatch was invoked early";
  boost::this_thread::sleep_for(boost::chrono::milliseconds(2));
  ASSERT_TRUE(*x) << "A timepoint-based delayed dispatch was not invoked in a timely fashion";
}

template<ThreadPriority priority>
class JustIncrementsANumber:
  public CoreThread
{
public:
  JustIncrementsANumber():
    val(0)
  {}

  volatile int64_t val;

  // This will be a hotly contested conditional variable
  AutoRequired<boost::mutex> contended;

  void Run(void) override {
    ElevatePriority p(*this, priority);
    while(!ShouldStop()) {
      // Obtain the lock and then increment our value:
      boost::lock_guard<boost::mutex> lk(*contended);
      val++;
    }
  }
};

#ifdef _MSC_VER
TEST_F(CoreThreadTest, VerifyCanBoostPriority) {
  // Create two spinners and kick them off at the same time:
  AutoRequired<JustIncrementsANumber<ThreadPriority::Normal>> lower;
  AutoRequired<JustIncrementsANumber<ThreadPriority::AboveNormal>> higher;
  m_create->InitiateCoreThreads();

  // Poke the conditional variable a lot:
  AutoRequired<boost::mutex> contended;
  for(size_t i = 100; i--;) {
    // We sleep while holding contention lock to force waiting threads into the sleep queue.  The reason we have to do
    // this is due to the way that mutex is implemented under the hood.  The STL mutex uses a high-frequency variable
    // and attempts to perform a CAS (check-and-set) on this variable.  If it succeeds, the lock is obtained; if it
    // fails, it will put the thread into a non-ready state by calling WaitForSingleObject on Windows or one of the
    // mutex_lock methods on Unix.
    //
    // When a thread can't be run, it's moved from the OS's ready queue to the sleep queue.  The scheduler knows that
    // the thread can be moved back to the ready queue if a particular object is signalled, but in the case of a lock,
    // only one of the threads waiting on the object can actually be moved to the ready queue.  It's at THIS POINT that
    // the operating system consults the thread priority--if only thread can be moved over, then the highest priority
    // thread will wind up in the ready queue every time.
    //
    // Thread priority does _not_ necessarily influence the amount of time the scheduler allocates allocated to a ready
    // thread with respect to other threads of the same process.  This is why we hold the lock for a full millisecond,
    // in order to force the thread over to the sleep queue and ensure that the priority resolution mechanism is
    // directly tested.
    boost::lock_guard<boost::mutex> lk(*contended);
    boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
  }

  // Need to terminate before we try running a comparison.
  m_create->SignalTerminate();

  ASSERT_LE(lower->val, higher->val) << "A lower-priority thread was moved out of the sleep queue more frequently than a high-priority thread";
}
#else
#pragma message "Warning:  SetThreadPriority not implemented on Unix"
#endif<commit_msg>Relaxing another test constraint so that bypass behavior is evaluated separately<commit_after>// Copyright (c) 2010 - 2013 Leap Motion. All rights reserved. Proprietary and confidential.
#include "stdafx.h"
#include "CoreThreadTest.h"
#include "Autowired.h"
#include "TestFixtures/SimpleThreaded.h"
#include <boost/thread/thread.hpp>
#include <boost/thread.hpp>

class SpamguardTest:
  public CoreThread
{
public:
  SpamguardTest(void):
    m_hit(false),
    m_multiHit(false)
  {
  }

  bool m_hit;
  bool m_multiHit;

  void Run(void) override {
    if(m_hit) {
      m_multiHit = true;
      return;
    }

    m_hit = false;

    boost::unique_lock<boost::mutex> lk(m_lock);
    m_stateCondition.wait(lk, [this] () {return ShouldStop();});
  }
};

TEST_F(CoreThreadTest, VerifyStartSpam) {
  // Create our thread class:
  AutoRequired<SpamguardTest> instance;

  m_create->InitiateCoreThreads();

  // This shouldn't cause another thread to be created:
  instance->Start(std::shared_ptr<Object>(new Object));

  EXPECT_FALSE(instance->m_multiHit) << "Thread was run more than once unexpectedly";
}

class InvokesIndefiniteWait:
  public CoreThread
{
public:
  virtual void Run(void) override {
    AcceptDispatchDelivery();

    // Wait for one event using an indefinite timeout, then quit:
    WaitForEvent(boost::chrono::steady_clock::time_point::max());
  }
};

TEST_F(CoreThreadTest, VerifyIndefiniteDelay) {
  AutoRequired<InvokesIndefiniteWait> instance;
  m_create->InitiateCoreThreads();

  // Verify that the instance does not quit until we pend something:
  ASSERT_FALSE(instance->WaitFor(boost::chrono::milliseconds(10))) << "Thread instance exited prematurely, when it should have been waiting indefinitely";

  // Now we pend an arbitrary event and verify that we can wait:
  *instance += [] {};
  ASSERT_TRUE(instance->WaitFor(boost::chrono::milliseconds(10))) << "Instance did not exit after an event was pended which should have woken up its dispatch loop";
}

TEST_F(CoreThreadTest, VerifyNestedTermination) {
  std::shared_ptr<SimpleThreaded> st;

  // Insert a thread into a second-order subcontext:
  {
    AutoCreateContext outer;
    CurrentContextPusher outerPshr(outer);
    AutoRequired<SimpleThreaded>();
    outer->InitiateCoreThreads();

    {
      AutoCreateContext ctxt;
      CurrentContextPusher pshr(ctxt);
      ctxt->InitiateCoreThreads();
      st = AutoRequired<SimpleThreaded>();
    }
  }

  // Everything should be running by now:
  ASSERT_TRUE(st->IsRunning()) << "Child thread was not running as expected";

  // Shut down the enclosing context:
  m_create->SignalTerminate(true);

  // Verify that the child thread has stopped:
  ASSERT_FALSE(st->IsRunning()) << "Child thread was running even though the enclosing context was terminated";
}

class SleepEvent : public virtual EventReceiver
{
public:
  virtual Deferred SleepFor(int seconds) = 0;
  virtual Deferred SleepForThenThrow(int seconds) = 0;
};

class ListenThread :
  public CoreThread,
  public SleepEvent
{
public:
  ListenThread() : CoreThread("ListenThread") {}

  Deferred SleepFor(int seconds) override {
    boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
    if(ShouldStop())
      throw std::runtime_error("Execution aborted");

    return Deferred(this);
  }

  Deferred SleepForThenThrow(int seconds) override {
    return Deferred(this);
  }
};

TEST_F(CoreThreadTest, VerifyDispatchQueueShutdown) {
  AutoCreateContext ctxt;
  CurrentContextPusher pusher(ctxt);

  AutoRequired<ListenThread> listener;
  try
  {
    ctxt->InitiateCoreThreads();
    listener->DelayUntilCanAccept();

    AutoFired<SleepEvent> evt;

    // Spam in a bunch of events:
    for(size_t i = 100; i--;)
      evt(&SleepEvent::SleepFor)(0);

    // Graceful termination then enclosing context shutdown:
    listener->Stop(true);
    ctxt->SignalShutdown(true);
  }
  catch (...) {}

  ASSERT_EQ(listener->GetDispatchQueueLength(), static_cast<size_t>(0));
}

TEST_F(CoreThreadTest, VerifyNoLeakOnExecptions) {
  AutoCreateContext ctxt;
  CurrentContextPusher pshr(ctxt);

  AutoRequired<ListenThread> listener;
  std::shared_ptr<std::string> value(new std::string("sentinal"));

  std::weak_ptr<std::string> watcher(value);
  try
  {
    ctxt->InitiateCoreThreads();
    listener->DelayUntilCanAccept();

    *listener += [value] { throw std::exception(); };
    value.reset();
    ctxt->SignalShutdown(true);
  }
  catch (...) {}

  ASSERT_TRUE(watcher.expired()) << "Leaked memory on exception in a dispatch event";
}

TEST_F(CoreThreadTest, VerifyDelayedDispatchQueueSimple) {
  // Run our threads immediately, no need to wait
  m_create->InitiateCoreThreads();

  // Create a thread which we'll use just to pend dispatch events:
  AutoRequired<CoreThread> t;

  // Thread should be running by now:
  ASSERT_TRUE(t->IsRunning()) << "Thread added to a running context was not marked running";

  // Delay until the dispatch loop is actually running, then wait an additional 1ms to let the
  // WaitForEvent call catch on:
  t->DelayUntilCanAccept();
  boost::this_thread::sleep_for(boost::chrono::milliseconds(1));

  // These are flags--we'll set them to true as the test proceeds
  std::shared_ptr<bool> x(new bool(false));
  std::shared_ptr<bool> y(new bool(false));

  // Pend a delayed event first, and then an immediate event right afterwards:
  *t += boost::chrono::hours(1), [x] { *x = true; };
  *t += [y] { *y = true; };

  // Verify that, after 10ms, the first event is called and the second event is NOT called:
  boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
  ASSERT_TRUE(*y) << "A simple ready call was not dispatched within 10ms of being pended";
  ASSERT_FALSE(*x) << "An event which should not have been executed for 25ms was executed early";
}

TEST_F(CoreThreadTest, VerifyNoDelayDoubleFree) {
  m_create->InitiateCoreThreads();

  // We won't actually be referencing this, we just want to make sure it's not destroyed early
  std::shared_ptr<bool> x(new bool);

  // This deferred pend will never actually be executed:
  AutoRequired<CoreThread> t;
  t->DelayUntilCanAccept();
  *t += boost::chrono::hours(1), [x] {};

  // Verify that we have exactly one pended event at this point.
  ASSERT_EQ(1UL, t->GetDispatchQueueLength()) << "Dispatch queue had an unexpected number of pended events";

  // Verify that the shared pointer isn't unique at this point.  If it is, it's because our CoreThread deleted
  // the event even though it was supposed to have pended it.
  ASSERT_FALSE(x.unique()) << "A pended event was freed before it was called, and appears to be present in a dispatch queue";
}

TEST_F(CoreThreadTest, VerifyDoublePendedDispatchDelay) {
  // Immediately pend threads:
  m_create->InitiateCoreThreads();

  // Some variables that we will set to true as the test proceeds:
  std::shared_ptr<bool> x(new bool(false));
  std::shared_ptr<bool> y(new bool(false));

  // Create a thread as before, and pend a few events.  The order, here, is important.  We intentionally
  // pend an event that won't happen for awhile, in order to trick the dispatch queue into waiting for
  // a lot longer than it should for the next event.
  AutoRequired<CoreThread> t;
  t->DelayUntilCanAccept();
  *t += boost::chrono::hours(1), [x] { *x = true; };

  // Now pend an event that will be ready just about right away:
  *t += boost::chrono::nanoseconds(1), [y] { *y = true; };

  // Delay for a short period of time, then check our variable states:
  boost::this_thread::sleep_for(boost::chrono::milliseconds(10));

  // This one shouldn't have been hit yet, it isn't scheduled to be hit for 10s
  ASSERT_FALSE(*x) << "A delayed dispatch was invoked extremely early";

  // This one should have been ready almost at the same time as it was pended
  ASSERT_TRUE(*y) << "An out-of-order delayed dispatch was not executed in time as expected";
}

TEST_F(CoreThreadTest, VerifyTimedSort) {
  m_create->InitiateCoreThreads();
  AutoRequired<CoreThread> t;

  std::vector<size_t> v;

  // Pend a stack of lambdas.  Each lambda waits 3i milliseconds, and pushes the value
  // i to the back of a vector.  If the delay method is implemented correctly, the resulting
  // vector will always wind up sorted, no matter how we push elements to the queue.
  // To doubly verify this property, we don't trivially increment i from the minimum to the
  // maximum--rather, we use a simple PRNG called a linear congruential generator and hop around
  // the interval [1...12] instead.
  for(size_t i = 1; i != 0; i = (i * 5 + 1) % 16)
    *t += boost::chrono::milliseconds(i * 3), [&v, i] { v.push_back(i); };

  // Delay 50ms for the thread to finish up.  Technically this is 11ms more than we need.
  boost::this_thread::sleep_for(boost::chrono::seconds(1));

  // Verify that the resulting vector is sorted.
  ASSERT_TRUE(std::is_sorted(v.begin(), v.end())) << "A timed sort implementation did not generate a sorted sequence as expected";
}

TEST_F(CoreThreadTest, VerifyPendByTimePoint) {
  m_create->InitiateCoreThreads();
  AutoRequired<CoreThread> t;
  t->DelayUntilCanAccept();

  // Pend by an absolute time point, nothing really special here
  std::shared_ptr<bool> x(new bool(false));
  *t += (boost::chrono::high_resolution_clock::now() + boost::chrono::milliseconds(1)), [&x] { *x = true; };

  // Verify that we hit this after one ms of delay
  ASSERT_FALSE(*x) << "A timepoint-based delayed dispatch was invoked early";
  boost::this_thread::sleep_for(boost::chrono::milliseconds(2));
  ASSERT_TRUE(*x) << "A timepoint-based delayed dispatch was not invoked in a timely fashion";
}

template<ThreadPriority priority>
class JustIncrementsANumber:
  public CoreThread
{
public:
  JustIncrementsANumber():
    val(0)
  {}

  volatile int64_t val;

  // This will be a hotly contested conditional variable
  AutoRequired<boost::mutex> contended;

  void Run(void) override {
    ElevatePriority p(*this, priority);
    while(!ShouldStop()) {
      // Obtain the lock and then increment our value:
      boost::lock_guard<boost::mutex> lk(*contended);
      val++;
    }
  }
};

#ifdef _MSC_VER
TEST_F(CoreThreadTest, VerifyCanBoostPriority) {
  // Create two spinners and kick them off at the same time:
  AutoRequired<JustIncrementsANumber<ThreadPriority::Normal>> lower;
  AutoRequired<JustIncrementsANumber<ThreadPriority::AboveNormal>> higher;
  m_create->InitiateCoreThreads();

  // Poke the conditional variable a lot:
  AutoRequired<boost::mutex> contended;
  for(size_t i = 100; i--;) {
    // We sleep while holding contention lock to force waiting threads into the sleep queue.  The reason we have to do
    // this is due to the way that mutex is implemented under the hood.  The STL mutex uses a high-frequency variable
    // and attempts to perform a CAS (check-and-set) on this variable.  If it succeeds, the lock is obtained; if it
    // fails, it will put the thread into a non-ready state by calling WaitForSingleObject on Windows or one of the
    // mutex_lock methods on Unix.
    //
    // When a thread can't be run, it's moved from the OS's ready queue to the sleep queue.  The scheduler knows that
    // the thread can be moved back to the ready queue if a particular object is signalled, but in the case of a lock,
    // only one of the threads waiting on the object can actually be moved to the ready queue.  It's at THIS POINT that
    // the operating system consults the thread priority--if only thread can be moved over, then the highest priority
    // thread will wind up in the ready queue every time.
    //
    // Thread priority does _not_ necessarily influence the amount of time the scheduler allocates allocated to a ready
    // thread with respect to other threads of the same process.  This is why we hold the lock for a full millisecond,
    // in order to force the thread over to the sleep queue and ensure that the priority resolution mechanism is
    // directly tested.
    boost::lock_guard<boost::mutex> lk(*contended);
    boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
  }

  // Need to terminate before we try running a comparison.
  m_create->SignalTerminate();

  ASSERT_LE(lower->val, higher->val) << "A lower-priority thread was moved out of the sleep queue more frequently than a high-priority thread";
}
#else
#pragma message "Warning:  SetThreadPriority not implemented on Unix"
#endif<|endoftext|>


<commit_before>#include "cnn/nodes.h"
#include "cnn/cnn.h"
#include "cnn/training.h"
#include "cnn/gpu-ops.h"
#include "cnn/expr.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/algorithm/string.hpp>

#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <utility>
#include <sstream>
#include <random>

using namespace std;
using namespace cnn;
using namespace cnn::expr;

typedef pair<cnn::real, cnn::real> Datum;

const unsigned num_children = 2;
struct Workload {
  pid_t pid;
  unsigned start;
  unsigned end;
  int pipe[2];
};

struct ModelParameters {
  Parameters* m;
  Parameters* b;
};

void BuildComputationGraph(ComputationGraph& cg, ModelParameters& model_parameters, cnn::real* x_value, cnn::real* y_value) {
  Expression m = parameter(cg, model_parameters.m);
  Expression b = parameter(cg, model_parameters.b);

  Expression x = input(cg, x_value);
  Expression y_star = input(cg, y_value);
  Expression y = m * x + b;
  Expression loss = squared_distance(y, y_star);
}

vector<Datum> ReadData(string filename) {
  vector<Datum> data;
  ifstream fs(filename);
  string line;
  while (getline(fs, line)) {
    if (line.size() > 0 && line[0] == '#') {
      continue;
    }
    vector<string> parts;
    boost::split(parts, line, boost::is_any_of("\t"));
    data.push_back(make_pair(atof(parts[0].c_str()), atof(parts[1].c_str())));
  }
  return data;
}

unsigned SpawnChildren(vector<Workload>& workloads) {
  assert (workloads.size() == num_children);
  pid_t pid;
  unsigned cid;
  for (cid = 0; cid < num_children; ++cid) {
    pid = fork();
    if (pid == -1) {
      cerr << "Fork failed. Exiting ...";
      return 1;
    }
    else if (pid == 0) {
      // children shouldn't continue looping
      break;
    }
    workloads[cid].pid = pid;
  }
  return cid;
}

int RunChild(unsigned cid, ComputationGraph& cg, Trainer* trainer, vector<Workload>& workloads,
    const vector<Datum>& data, cnn::real& x_value, cnn::real& y_value, ModelParameters& model_params) {
  assert (cid >= 0 && cid < num_children);
  unsigned start = workloads[cid].start;
  unsigned end = workloads[cid].end;
  assert (start < end);
  assert (end <= data.size());

  cnn::real loss = 0;
  for (auto it = data.begin() + start; it != data.begin() + end; ++it) {
    auto p = *it;
    x_value = get<0>(p);
    y_value = get<1>(p);
    loss += as_scalar(cg.forward());
    cg.backward();
    trainer->update(1.0);
  }
  loss /= (end - start);

  cnn::real m_end = as_scalar(model_params.m->values);
  cnn::real b_end = as_scalar(model_params.b->values);

  write(workloads[cid].pipe[1], (char*)&m_end, sizeof(cnn::real));
  write(workloads[cid].pipe[1], (char*)&b_end, sizeof(cnn::real));
  write(workloads[cid].pipe[1], (char*)&loss, sizeof(cnn::real));
  return 0;
}

void RunParent(unsigned iter, vector<Workload>& workloads, ModelParameters& model_params, Trainer* trainer) {
  vector<cnn::real> m_values;
  vector<cnn::real> b_values;
  vector<cnn::real> loss_values;
  for(unsigned cid = 0; cid < num_children; ++cid) {
    cnn::real m, b, loss;
    read(workloads[cid].pipe[0], (char*)&m, sizeof(cnn::real));
    read(workloads[cid].pipe[0], (char*)&b, sizeof(cnn::real));
    read(workloads[cid].pipe[0], (char*)&loss, sizeof(cnn::real));
    m_values.push_back(m);
    b_values.push_back(b);
    loss_values.push_back(loss);
    wait(NULL);
  }

  cnn::real m = 0.0;
  cnn::real b = 0.0;
  cnn::real loss = 0.0;
  for (unsigned i = 0; i < m_values.size(); ++i) {
    m += m_values[i];
    b += b_values[i];
    loss += loss_values[i];
  }
  m /= m_values.size();
  b /= b_values.size();

  // Update parameters to use the new m and b values
  TensorTools::SetElements(model_params.m->values, {m});
  TensorTools::SetElements(model_params.b->values, {b});
  trainer->update_epoch();
  cerr << iter << "\t" << "loss = " << loss << "\tm = " << m << "\tb = " << b << endl;
}

int main(int argc, char** argv) {
  cnn::Initialize(argc, argv);

  if (argc < 2) {
    cerr << "Usage: " << argv[0] << " data.txt" << endl;
    cerr << "Where data.txt contains tab-delimited pairs of floats." << endl;
    return 1;
  }
  vector<Datum> data = ReadData(argv[1]);
  vector<Workload> workloads(num_children);

  Model model;
  AdamTrainer sgd(&model, 0.0);

  ComputationGraph cg;
  cnn::real x_value, y_value;
  Parameters* m_param = model.add_parameters({1, 1});
  Parameters* b_param = model.add_parameters({1});
  ModelParameters model_params = {m_param, b_param};
  BuildComputationGraph(cg, model_params, &x_value, &y_value);

  for (unsigned cid = 0; cid < num_children; cid++) {
    unsigned start = (unsigned)(1.0 * cid / num_children * data.size() + 0.5);
    unsigned end = (unsigned)(1.0 * (cid + 1) / num_children * data.size() + 0.5);
    workloads[cid].start = start;
    workloads[cid].end = end;
    pipe(workloads[cid].pipe);
  }

  // train the parameters
  for (unsigned iter = 0; true; ++iter) {
    random_shuffle(data.begin(), data.end());
    unsigned cid = SpawnChildren(workloads);

    if (cid < num_children) {
      return RunChild(cid, cg, &sgd, workloads, data, x_value, y_value, model_params);
    }
    else {
      RunParent(iter, workloads, model_params, &sgd);
    }
  }
}

<commit_msg>more minor cleanup<commit_after>#include "cnn/cnn.h"
#include "cnn/training.h"
#include "cnn/expr.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/algorithm/string.hpp>

#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <utility>
#include <sstream>
#include <random>

using namespace std;
using namespace cnn;
using namespace cnn::expr;

typedef pair<cnn::real, cnn::real> Datum;
const unsigned num_children = 2;

cnn::real ReadReal(int pipe) {
  cnn::real v;
  read(pipe, &v, sizeof(cnn::real));
  return v;
}

void WriteReal(int pipe, cnn::real v) {
  write(pipe, &v, sizeof(cnn::real));
}

cnn::real Mean(const vector<cnn::real>& values) {
  return accumulate(values.begin(), values.end(), 0.0) / values.size();
}

struct Workload {
  pid_t pid;
  unsigned start;
  unsigned end;
  int pipe[2];
};

struct ModelParameters {
  Parameters* m;
  Parameters* b;
};

void BuildComputationGraph(ComputationGraph& cg, ModelParameters& model_parameters, cnn::real* x_value, cnn::real* y_value) {
  Expression m = parameter(cg, model_parameters.m);
  Expression b = parameter(cg, model_parameters.b);

  Expression x = input(cg, x_value);
  Expression y_star = input(cg, y_value);
  Expression y = m * x + b;
  Expression loss = squared_distance(y, y_star);
}

vector<Datum> ReadData(string filename) {
  vector<Datum> data;
  ifstream fs(filename);
  string line;
  while (getline(fs, line)) {
    if (line.size() > 0 && line[0] == '#') {
      continue;
    }
    vector<string> parts;
    boost::split(parts, line, boost::is_any_of("\t"));
    data.push_back(make_pair(atof(parts[0].c_str()), atof(parts[1].c_str())));
  }
  return data;
}

unsigned SpawnChildren(vector<Workload>& workloads) {
  assert (workloads.size() == num_children);
  pid_t pid;
  unsigned cid;
  for (cid = 0; cid < num_children; ++cid) {
    pid = fork();
    if (pid == -1) {
      cerr << "Fork failed. Exiting ...";
      return 1;
    }
    else if (pid == 0) {
      // children shouldn't continue looping
      break;
    }
    workloads[cid].pid = pid;
  }
  return cid;
}

int RunChild(unsigned cid, ComputationGraph& cg, Trainer* trainer, vector<Workload>& workloads,
    const vector<Datum>& data, cnn::real& x_value, cnn::real& y_value, ModelParameters& model_params) {
  assert (cid >= 0 && cid < num_children);
  unsigned start = workloads[cid].start;
  unsigned end = workloads[cid].end;
  assert (start < end);
  assert (end <= data.size());

  cnn::real loss = 0;
  for (auto it = data.begin() + start; it != data.begin() + end; ++it) {
    auto p = *it;
    x_value = get<0>(p);
    y_value = get<1>(p);
    loss += as_scalar(cg.forward());
    cg.backward();
    trainer->update(1.0);
  }
  loss /= (end - start);

  cnn::real m_end = as_scalar(model_params.m->values);
  cnn::real b_end = as_scalar(model_params.b->values);

  write(workloads[cid].pipe[1], (char*)&m_end, sizeof(cnn::real));
  write(workloads[cid].pipe[1], (char*)&b_end, sizeof(cnn::real));
  write(workloads[cid].pipe[1], (char*)&loss, sizeof(cnn::real));
  return 0;
}

void RunParent(unsigned iter, vector<Workload>& workloads, ModelParameters& model_params, Trainer* trainer) {
  vector<cnn::real> m_values;
  vector<cnn::real> b_values;
  vector<cnn::real> loss_values;
  for(unsigned cid = 0; cid < num_children; ++cid) {
    cnn::real m = ReadReal(workloads[cid].pipe[0]);
    cnn::real b = ReadReal(workloads[cid].pipe[0]);
    cnn::real loss = ReadReal(workloads[cid].pipe[0]);
    m_values.push_back(m);
    b_values.push_back(b);
    loss_values.push_back(loss);
    wait(NULL);
  }

  cnn::real m = Mean(m_values);
  cnn::real b = 0.0;
  cnn::real loss = 0.0;
  for (unsigned i = 0; i < m_values.size(); ++i) {
    b += b_values[i];
    loss += loss_values[i];
  }

  b /= b_values.size();

  // Update parameters to use the new m and b values
  TensorTools::SetElements(model_params.m->values, {m});
  TensorTools::SetElements(model_params.b->values, {b});
  trainer->update_epoch();
  cerr << iter << "\t" << "loss = " << loss << "\tm = " << m << "\tb = " << b << endl;
}

int main(int argc, char** argv) {
  cnn::Initialize(argc, argv);

  if (argc < 2) {
    cerr << "Usage: " << argv[0] << " data.txt" << endl;
    cerr << "Where data.txt contains tab-delimited pairs of floats." << endl;
    return 1;
  }
  vector<Datum> data = ReadData(argv[1]);
  vector<Workload> workloads(num_children);

  Model model;
  AdamTrainer sgd(&model, 0.0);

  ComputationGraph cg;
  cnn::real x_value, y_value;
  Parameters* m_param = model.add_parameters({1, 1});
  Parameters* b_param = model.add_parameters({1});
  ModelParameters model_params = {m_param, b_param};
  BuildComputationGraph(cg, model_params, &x_value, &y_value);

  for (unsigned cid = 0; cid < num_children; cid++) {
    unsigned start = (unsigned)(1.0 * cid / num_children * data.size() + 0.5);
    unsigned end = (unsigned)(1.0 * (cid + 1) / num_children * data.size() + 0.5);
    workloads[cid].start = start;
    workloads[cid].end = end;
    pipe(workloads[cid].pipe);
  }

  // train the parameters
  for (unsigned iter = 0; true; ++iter) {
    random_shuffle(data.begin(), data.end());
    unsigned cid = SpawnChildren(workloads);

    if (cid < num_children) {
      return RunChild(cid, cg, &sgd, workloads, data, x_value, y_value, model_params);
    }
    else {
      RunParent(iter, workloads, model_params, &sgd);
    }
  }
}

<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 1 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 10000000000000007;

struct edge {
  int to;
  ll cap;
  int rev;
};

vector<edge> G[100010];
bool used[100010];

void add_edge(int from, int to, ll cap) {
  G[from].push_back((edge){to, cap, (int)G[to].size()});
  G[to].push_back((edge){to, 0, (int)G[to].size()-1});
}

ll dfs(int v, int t, ll f) {
  if (v == t) return f;
  used[v] = true;
  for (auto& e : G[v]) {
    if (!used[e.to] && e.cap > 0) {
      ll d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

ll max_flow(int s, int t) {
  ll flow = 0;
  while (true) {
    fill(used, used+100010, false);
    ll f = dfs(s, t, infty);
    if (f == 0) return flow;
    flow += f;
  }
}

int R, C;
string S[100];
int src, dst;
int vertex = 0;

bool valid(int i, int j) {
  return (0 <= i && i < R && 0 <= j && j < C && S[i][j] == '.');
}

int num(int i, int j) {
  return i * C + j;
}

void add_edge_grid(int i, int j) {
  if (!valid(i, j)) return;
  int now = num(i, j);
  vertex++;
  if (i+j % 2 == 0) {
    for (auto k = 0; k < 4; ++k) {
      int x = i + dx[k];
      int y = j + dy[k];
      if (valid(x, y)) {
        add_edge(now, num(x, y), 1);
#if DEBUG == 1
        cerr << "add_edge(" << now << ", " << num(x, y) << ", 1)" << endl;
#endif
      }
      add_edge(src, now, 1);
    }
  } else {
    add_edge(now, dst, 1);
  }
}

int main () {
  cin >> R >> C;
  for (auto i = 0; i < R; ++i) {
    cin >> S[i];
  }
  src = R * C;
  dst = R * C + 1;
  for (auto i = 0; i < R; ++i) {
    for (auto j = 0; j < C; ++j) {
      add_edge_grid(i, j);
    }
  }
  ll maxi = max_flow(src, dst);
#if DEBUG == 1
  cerr << "vertex = " << vertex << endl;
  cerr << "maxi = " << maxi << endl;
#endif
  cout << vertex - maxi << endl;
}
<commit_msg>tried C2.cpp to 'C'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 10000000000000007;

struct edge {
  int to;
  ll cap;
  int rev;
};

vector<edge> G[100010];
bool used[100010];

void add_edge(int from, int to, ll cap) {
  G[from].push_back((edge){to, cap, (int)G[to].size()});
  G[to].push_back((edge){to, 0, (int)G[to].size()-1});
}

ll dfs(int v, int t, ll f) {
  if (v == t) return f;
  used[v] = true;
  for (auto& e : G[v]) {
    if (!used[e.to] && e.cap > 0) {
      ll d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

ll max_flow(int s, int t) {
  ll flow = 0;
  while (true) {
    fill(used, used+100010, false);
    ll f = dfs(s, t, infty);
    if (f == 0) return flow;
    flow += f;
  }
}

int R, C;
string S[100];
int src, dst;
int vertex = 0;

bool valid(int i, int j) {
  return (0 <= i && i < R && 0 <= j && j < C && S[i][j] == '.');
}

int num(int i, int j) {
  return i * C + j;
}

void add_edge_grid(int i, int j) {
  if (!valid(i, j)) return;
  int now = num(i, j);
  vertex++;
  if ((i+j) % 2 == 0) {
    for (auto k = 0; k < 4; ++k) {
      int x = i + dx[k];
      int y = j + dy[k];
      if (valid(x, y)) {
        add_edge(now, num(x, y), 1);
#if DEBUG == 1
        cerr << "add_edge(" << now << ", " << num(x, y) << ", 1)" << endl;
#endif
      }
      add_edge(src, now, 1);
    }
  } else {
    add_edge(now, dst, 1);
  }
}

int main () {
  cin >> R >> C;
  for (auto i = 0; i < R; ++i) {
    cin >> S[i];
  }
  src = R * C;
  dst = R * C + 1;
  for (auto i = 0; i < R; ++i) {
    for (auto j = 0; j < C; ++j) {
      add_edge_grid(i, j);
    }
  }
  ll maxi = max_flow(src, dst);
#if DEBUG == 1
  cerr << "vertex = " << vertex << endl;
  cerr << "maxi = " << maxi << endl;
#endif
  cout << vertex - maxi << endl;
}
<|endoftext|>


<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbStatisticsXMLFileWriter.h"
#include "otbStreamingStatisticsVectorImageFilter.h"

namespace otb
{
namespace Wrapper
{

class ComputeImagesStatistics: public Application
{
public:
  /** Standard class typedefs. */
  typedef ComputeImagesStatistics Self;
  typedef Application Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ComputeImagesStatistics, otb::Application);

private:
  void DoInit()
  {
    SetName("ComputeImagesStatistics");
    SetDescription("Computes global mean and standard deviation for each band from a set of images and optionally saves the results in an XML file.");
    SetDocName("Compute Images second order statistics");
    SetDocLongDescription("This application computes a global mean and standard deviation for each band of a set of images and optionally saves the results in an XML file. The output XML is intended to be used an input for the TrainImagesClassifier application to normalize samples before learning.");
    SetDocLimitations("Each image of the set must contain the same bands as the others (i.e. same types, in the same order).");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("Documentation of the TrainImagesClassifier application.");

    AddDocTag(Tags::Learning);
    AddDocTag(Tags::Analysis);

    AddParameter(ParameterType_InputImageList, "il", "Input images");
    SetParameterDescription( "il", "List of input images filenames." );

    AddParameter(ParameterType_OutputFilename, "out", "Output XML file");
    SetParameterDescription( "out", "XML filename where the statistics are saved for future reuse." );
    MandatoryOff("out");

   // Doc example parameter settings
   SetDocExampleParameterValue("il", "QB_1_ortho.tif");
   SetDocExampleParameterValue("out", "EstimateImageStatisticsQB1.xml");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    //Statistics estimator
    typedef otb::StreamingStatisticsVectorImageFilter<FloatVectorImageType> StreamingStatisticsVImageFilterType;

    // Samples
    typedef double ValueType;
    typedef itk::VariableLengthVector<ValueType> MeasurementType;

    unsigned int nbSamples = 0;
    unsigned int nbBands = 0;

    // Build a Measurement Vector of mean
    MeasurementType mean;

    // Build a MeasurementVector of variance
    MeasurementType variance;

    FloatVectorImageListType* imageList = GetParameterImageList("il");

    //Iterate over all input images
    for (unsigned int imageId = 0; imageId < imageList->Size(); ++imageId)
      {
      FloatVectorImageType* image = imageList->GetNthElement(imageId);

      if (nbBands == 0)
        {
        nbBands = image->GetNumberOfComponentsPerPixel();
        }
      else if (nbBands != image->GetNumberOfComponentsPerPixel())
        {
        itkExceptionMacro(<< "The image #" << imageId << " has " << image->GetNumberOfComponentsPerPixel()
            << " bands, while the first one has " << nbBands );
        }

      FloatVectorImageType::SizeType size = image->GetLargestPossibleRegion().GetSize();

      //Set the measurement vectors size if it's the first iteration
      if (imageId == 0)
        {
        mean.SetSize(nbBands);
        mean.Fill(0.);
        variance.SetSize(nbBands);
        variance.Fill(0.);
        }

      // Compute Statistics of each VectorImage
      StreamingStatisticsVImageFilterType::Pointer statsEstimator = StreamingStatisticsVImageFilterType::New();
      statsEstimator->SetInput(image);
      statsEstimator->Update();
      mean += statsEstimator->GetMean();
      for (unsigned int itBand = 0; itBand < nbBands; itBand++)
        {
        variance[itBand] += (size[0] * size[1] - 1) * (statsEstimator->GetCovariance())(itBand, itBand);
        }
      //Increment nbSamples
      nbSamples += size[0] * size[1] * nbBands;
      }

    //Divide by the number of input images to get the mean over all layers
    mean /= imageList->Size();
    //Apply the pooled variance formula
    variance /= (nbSamples - imageList->Size());

    MeasurementType stddev;
    stddev.SetSize(nbBands);
    stddev.Fill(0.);
    for (unsigned int i = 0; i < variance.GetSize(); ++i)
      {
      stddev[i] = vcl_sqrt(variance[i]);
      }

    if( HasValue( "out" )==true )
      {
      // Write the Statistics via the statistic writer
      typedef otb::StatisticsXMLFileWriter<MeasurementType> StatisticsWriter;
      StatisticsWriter::Pointer writer = StatisticsWriter::New();
      writer->SetFileName(GetParameterString("out"));
      writer->AddInput("mean", mean);
      writer->AddInput("stddev", stddev);
      writer->Update();
      }
    else
      {
      otbAppLogINFO("Mean: "<<mean<<std::endl);
      otbAppLogINFO("Standard Deviation: "<<stddev<<std::endl);
      }
  }

  itk::LightObject::Pointer m_FilterRef;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ComputeImagesStatistics)
<commit_msg>ENH: provide access to user defined ignored value in ComputeImagesStatistics application<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbStatisticsXMLFileWriter.h"
#include "otbStreamingStatisticsVectorImageFilter.h"

namespace otb
{
namespace Wrapper
{

class ComputeImagesStatistics: public Application
{
public:
  /** Standard class typedefs. */
  typedef ComputeImagesStatistics Self;
  typedef Application Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ComputeImagesStatistics, otb::Application);

private:
  void DoInit()
  {
    SetName("ComputeImagesStatistics");
    SetDescription("Computes global mean and standard deviation for each band from a set of images and optionally saves the results in an XML file.");
    SetDocName("Compute Images second order statistics");
    SetDocLongDescription("This application computes a global mean and standard deviation for each band of a set of images and optionally saves the results in an XML file. The output XML is intended to be used an input for the TrainImagesClassifier application to normalize samples before learning.");
    SetDocLimitations("Each image of the set must contain the same bands as the others (i.e. same types, in the same order).");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("Documentation of the TrainImagesClassifier application.");

    AddDocTag(Tags::Learning);
    AddDocTag(Tags::Analysis);

    AddParameter(ParameterType_InputImageList, "il", "Input images");
    SetParameterDescription( "il", "List of input images filenames." );

    AddParameter(ParameterType_Float, "bv", "Background Value");
    SetParameterDescription( "bv", "Background value to ignore in statistics computation." );
    MandatoryOff("bv");

    AddParameter(ParameterType_OutputFilename, "out", "Output XML file");
    SetParameterDescription( "out", "XML filename where the statistics are saved for future reuse." );
    MandatoryOff("out");

   // Doc example parameter settings
   SetDocExampleParameterValue("il", "QB_1_ortho.tif");
   SetDocExampleParameterValue("out", "EstimateImageStatisticsQB1.xml");
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    //Statistics estimator
    typedef otb::StreamingStatisticsVectorImageFilter<FloatVectorImageType> StreamingStatisticsVImageFilterType;

    // Samples
    typedef double ValueType;
    typedef itk::VariableLengthVector<ValueType> MeasurementType;

    unsigned int nbSamples = 0;
    unsigned int nbBands = 0;

    // Build a Measurement Vector of mean
    MeasurementType mean;

    // Build a MeasurementVector of variance
    MeasurementType variance;

    FloatVectorImageListType* imageList = GetParameterImageList("il");

    //Iterate over all input images
    for (unsigned int imageId = 0; imageId < imageList->Size(); ++imageId)
      {
      FloatVectorImageType* image = imageList->GetNthElement(imageId);

      if (nbBands == 0)
        {
        nbBands = image->GetNumberOfComponentsPerPixel();
        }
      else if (nbBands != image->GetNumberOfComponentsPerPixel())
        {
        itkExceptionMacro(<< "The image #" << imageId << " has " << image->GetNumberOfComponentsPerPixel()
            << " bands, while the first one has " << nbBands );
        }

      FloatVectorImageType::SizeType size = image->GetLargestPossibleRegion().GetSize();

      //Set the measurement vectors size if it's the first iteration
      if (imageId == 0)
        {
        mean.SetSize(nbBands);
        mean.Fill(0.);
        variance.SetSize(nbBands);
        variance.Fill(0.);
        }

      // Compute Statistics of each VectorImage
      StreamingStatisticsVImageFilterType::Pointer statsEstimator = StreamingStatisticsVImageFilterType::New();
      statsEstimator->SetInput(image);
      if( HasValue( "bv" )==true )
        {
        statsEstimator->SetIgnoreUserDefinedValue(true);
        statsEstimator->SetUserIgnoredValue(GetParameterFloat("bv"));
        }
      statsEstimator->Update();
      mean += statsEstimator->GetMean();
      for (unsigned int itBand = 0; itBand < nbBands; itBand++)
        {
        variance[itBand] += (size[0] * size[1] - 1) * (statsEstimator->GetCovariance())(itBand, itBand);
        }
      //Increment nbSamples
      nbSamples += size[0] * size[1] * nbBands;
      }

    //Divide by the number of input images to get the mean over all layers
    mean /= imageList->Size();
    //Apply the pooled variance formula
    variance /= (nbSamples - imageList->Size());

    MeasurementType stddev;
    stddev.SetSize(nbBands);
    stddev.Fill(0.);
    for (unsigned int i = 0; i < variance.GetSize(); ++i)
      {
      stddev[i] = vcl_sqrt(variance[i]);
      }

    if( HasValue( "out" )==true )
      {
      // Write the Statistics via the statistic writer
      typedef otb::StatisticsXMLFileWriter<MeasurementType> StatisticsWriter;
      StatisticsWriter::Pointer writer = StatisticsWriter::New();
      writer->SetFileName(GetParameterString("out"));
      writer->AddInput("mean", mean);
      writer->AddInput("stddev", stddev);
      writer->Update();
      }
    else
      {
      otbAppLogINFO("Mean: "<<mean<<std::endl);
      otbAppLogINFO("Standard Deviation: "<<stddev<<std::endl);
      }
  }

  itk::LightObject::Pointer m_FilterRef;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ComputeImagesStatistics)
<|endoftext|>