<commit_before>#ifndef OBJECTS_H
#define OBJECTS_H

/*
Defines an Object::ref type, which is a tagged pointer type.
Usage:
	Object::ref x = Object::to_ref(1);//smallint
	Object::ref y = Object::to_ref(new(hp) Generic()); //object
	if(is_a<int>(x)) {
		std::cout << "x = " << as_a<int>(x) << std::endl;
	}
	if(is_a<Generic*>(y)) {
		std::cout << "y.field = " << as_a<Generic*>(y)->field
			<< std::endl;
	}
*/

#include<stdint.h>
#include<climits>

#include"unichars.hpp"

#ifdef MY_COMPILER
// without these my compiler signals an error -- stefano
// I suggest you try it now with all_defines.hpp
// included in all source files -- almkglor
#define INTPTR_MIN		(-2147483647-1)
#define INTPTR_MAX		(2147483647)
#endif // MY_COMPILER

class Generic;
class Symbol;
class Cons;
class Closure;
class KClosure;

namespace Object {

/*-----------------------------------------------------------------------------
Declare
-----------------------------------------------------------------------------*/
	class ref;
	template<typename T> struct tag_traits;
	/*assume we won't ever need more than 7 bits of tag*/
	typedef unsigned char tag_type;

	template<typename T> static inline ref to_ref(T);
	template<typename T> static inline bool _is_a(ref);
	template<typename T> static inline T _as_a(ref);

	static inline ref t(void);
	static inline bool _is_t(ref);

	static inline ref nil(void);
	static inline bool _is_nil(ref);

	static inline ref from_a_scaled_int(int);
	static inline int to_a_scaled_int(ref);
}

void throw_TypeError(Object::ref, char const*);
void throw_RangeError(char const*);

template<typename T> static inline bool is_a(Object::ref);
template<typename T> static inline T as_a(Object::ref);

static inline bool is_t(Object::ref);

namespace Object {

/*-----------------------------------------------------------------------------
Configuration
-----------------------------------------------------------------------------*/

	static const unsigned char tag_bits = 2;// can bump up to 3 maybe...

	template<> struct tag_traits<int> {
		static const tag_type tag = 0x1;
	};
	template<> struct tag_traits<Generic*> {
		static const tag_type tag = 0x0;
	};
	template<> struct tag_traits<Symbol*> {
		static const tag_type tag = 0x2;
	};
	template<> struct tag_traits<UnicodeChar> {
		static const tag_type tag = 0x3;
	};

/*-----------------------------------------------------------------------------
Provided information
-----------------------------------------------------------------------------*/

	static const tag_type alignment = 1 << tag_bits;
	static const tag_type tag_mask = alignment - 1;

	/*the real range is the smaller of the range of intptr_t
	shifted down by tag bits, or the range of the `int' type
	*/
	static const intptr_t smallint_min =
		(sizeof(int) >= sizeof(intptr_t)) ?
			INTPTR_MIN >> tag_bits :
		/*otherwise*/
			INT_MIN;
	static const intptr_t smallint_max =
		(sizeof(int) >= sizeof(intptr_t)) ?
			INTPTR_MAX >> tag_bits :
		/*otherwise*/
			INT_MAX;

	/*value for "t"*/
	static const intptr_t t_value = ~((intptr_t) tag_mask);

/*-----------------------------------------------------------------------------
The tagged pointer type
-----------------------------------------------------------------------------*/

	/*stefano prefers to use:
		typedef void* ref;
	or maybe:
		typedef intptr_t ref;
	I may change this later on, but for now
	I want to see whether the conceptual
	separation will help and if compilers,
	in general, will be smart enough to
	optimize away the structure.
	*/
	class ref {
	private:
		intptr_t dat;
		ref(intptr_t x) : dat(x) {}
	public:
		ref(void) : dat(0) {}
		inline bool operator==(ref b) {
			return dat == b.dat;
		}
		inline bool operator!=(ref b) {
			return dat != b.dat;
		}
		inline bool operator!(void) {
			return dat == 0;
		}

		/*safe bool idiom*/
		typedef intptr_t (ref::*unspecified_bool_type);
		inline operator unspecified_bool_type(void) {
			return dat != 0 ? &ref::dat : 0;
		}

		template<typename T> friend ref to_ref(T);
		template<typename T> friend bool _is_a(ref);
		template<typename T> friend T _as_a(ref);

		friend int to_a_scaled_int(ref);
		friend ref from_a_scaled_int(int);

		friend ref t(void);
		friend bool _is_t(ref);
	};

/*-----------------------------------------------------------------------------
Tagged pointer factories
-----------------------------------------------------------------------------*/

	template<typename T>
	static inline ref to_ref(T x) {
		/* default to Generic* */
		return to_ref<Generic*>(x);
	}
	template<>
	static inline ref to_ref<Generic*>(Generic* x) {
		intptr_t tmp = reinterpret_cast<intptr_t>(x);
		#ifdef DEBUG
			if(tmp & tag_mask != 0) {
				throw_RangeError("Misaligned pointer");
			}
		#endif
		return ref(tmp + tag_traits<Generic*>::tag);
	}
	template<>
	static inline ref to_ref<Symbol*>(Symbol* x) {
		intptr_t tmp = reinterpret_cast<intptr_t>(x);
		#ifdef DEBUG
			if(tmp & tag_mask != 0) {
				throw_RangeError("Misaligned pointer");
			}
		#endif
		return ref(tmp + tag_traits<Symbol*>::tag);
	}
	template<>
	static inline ref to_ref<int>(int x) {
		#ifdef DEBUG
			#if (INT_MAX >= INTPTR_MAX) || (INT_MIN <= INTPTR_MIN)
				if(x < smallint_min || x > smallint_max) {
					throw_RangeError(
						"int out of range of smallint"
					);
				}
			#endif
		#endif
		intptr_t tmp = (((intptr_t) x) << tag_bits);
		return ref(tmp + tag_traits<int>::tag);
	}
	template<>
	static inline ref to_ref<UnicodeChar>(UnicodeChar x) {
		intptr_t tmp = x.dat << tag_bits;
		return ref(tmp + tag_traits<UnicodeChar>::tag);
	}

	/*no checking, even in debug mode... achtung!*/
	/*This function is used to convert an int computed using
	Object::to_a_scaled_int back to an Object::ref.  It is not
	intended to be used for any other int's.
	This function is intended for optimized smallint
	mathematics.
	*/
	static inline ref from_a_scaled_int(int x) {
                return ref((((intptr_t) x)<<tag_bits) + tag_traits<int>::tag);
	}

	static inline ref nil(void) {
		return ref();
	}
	static inline ref t(void) {
		return ref(t_value);
	}

/*-----------------------------------------------------------------------------
Tagged pointer checking
-----------------------------------------------------------------------------*/

	static inline bool _is_nil(ref obj) {
		return !obj;
	}
	static inline bool _is_t(ref obj) {
		return obj.dat == t_value;
	}

	template<typename T>
	static inline bool _is_a(ref obj) {
		if(tag_traits<T>::tag != 0x0) {
			return (obj.dat & tag_mask) == tag_traits<T>::tag;
		} else {
			return (obj.dat & tag_mask) == tag_traits<T>::tag
				&& !_is_nil(obj) && !_is_t(obj);
		}
	}

/*-----------------------------------------------------------------------------
Tagged pointer referencing
-----------------------------------------------------------------------------*/

	template<typename T>
	static inline T _as_a(ref obj) {
		#ifdef DEBUG
			if(!_is_a<T>(obj)) {
				throw_TypeError(obj,
					"incorrect type for pointer"
				);
			}
		#endif
		intptr_t tmp = obj.dat;
		return reinterpret_cast<T>(tmp - tag_traits<T>::tag);
		/*use subtraction instead of masking, in order to
		allow smart compilers to merge a field access with
		the tag removal. i.e. the pointers are pointers to
		structures, so they will be accessed via fields, and
		in all probability those fields will be at some
		offset from the actual structure address, meaning
		that the processor itself will perform an addition
		to access the field.  The smart compiler can then
		merge the addition of the field offset with the
		subtraction of the tag.
		*/
	}

	template<>
	static inline int _as_a<int>(ref obj) {
		#ifdef DEBUG
			if(!_is_a<int>(obj)) {
				throw_TypeError(obj,
					"incorrect type for small integer"
				);
			}
		#endif
		intptr_t tmp = obj.dat;
		return (int)(tmp >> tag_bits);
	}

	template<>
	static inline UnicodeChar _as_a<UnicodeChar>(ref obj) {
		uint32_t tmp = obj.dat;
		return UnicodeChar(tmp >> tag_bits);
	}

	/*no checking, even in debug mode... achtung!*/
	/*This function is used to convert a smallint Object::ref
	to a useable int that is equal to the "real" int, shifted
	to the left by the number of tag bits (i.e. scaled).  It
	should be used only for optimizing smallint math operations.
	*/
	static inline int to_a_scaled_int(ref obj) {
		intptr_t tmp = obj.dat;
		return (int)((tmp - tag_traits<int>::tag)>>tag_bits);
		/*use subtraction instead of masking, again to
		allow smart compilers to merge tag adding and
		subtracting.  For example the typical case would
		be something like:

		Object::ref result =
			Object::from_a_scaled_int(
				Object::to_a_scaled_int(a) +
				Object::to_a_scaled_int(b)
			);

		The above case can be reduced by the compiler to:

		intptr_t result =
			(tag_traits<int>::tag +
				a - tag_traits<int>::tag +
				b - tag_traits<int>::tag
			);

		It can then do some maths and cancel out a tag:

		intptr_t result = a + b - tag_traits<int>::tag;
		*/
	}

/*-----------------------------------------------------------------------------
Utility
-----------------------------------------------------------------------------*/

	static inline size_t round_up_to_alignment(size_t x) {
		return
		(x & tag_mask) ?      (x + alignment - (x & tag_mask)) :
		/*otherwise*/         x ;
	}

}

/*-----------------------------------------------------------------------------
Reflectors outside of the namespace
-----------------------------------------------------------------------------*/

template<typename T>
static inline bool is_a(Object::ref obj) {
	return Object::_is_a<T>(obj);
}
template<typename T>
static inline T as_a(Object::ref obj) {
	return Object::_as_a<T>(obj);
}
static inline bool is_nil(Object::ref obj) {
	return Object::_is_nil(obj);
}
static inline bool is_t(Object::ref obj) {
	return Object::_is_t(obj);
}

#endif //OBJECTS_H

<commit_msg>inc/objects.hpp: Modified to remove redundant static inline in some declarations<commit_after>#ifndef OBJECTS_H
#define OBJECTS_H

/*
Defines an Object::ref type, which is a tagged pointer type.
Usage:
	Object::ref x = Object::to_ref(1);//smallint
	Object::ref y = Object::to_ref(new(hp) Generic()); //object
	if(is_a<int>(x)) {
		std::cout << "x = " << as_a<int>(x) << std::endl;
	}
	if(is_a<Generic*>(y)) {
		std::cout << "y.field = " << as_a<Generic*>(y)->field
			<< std::endl;
	}
*/

#include<stdint.h>
#include<climits>

#include"unichars.hpp"

#ifdef MY_COMPILER
// without these my compiler signals an error -- stefano
// I suggest you try it now with all_defines.hpp
// included in all source files -- almkglor
#define INTPTR_MIN		(-2147483647-1)
#define INTPTR_MAX		(2147483647)
#endif // MY_COMPILER

class Generic;
class Symbol;
class Cons;
class Closure;
class KClosure;

namespace Object {

/*-----------------------------------------------------------------------------
Declare
-----------------------------------------------------------------------------*/
	class ref;
	template<typename T> struct tag_traits;
	/*assume we won't ever need more than 7 bits of tag*/
	typedef unsigned char tag_type;

	template<typename T> static inline ref to_ref(T);
	template<typename T> static inline bool _is_a(ref);
	template<typename T> static inline T _as_a(ref);

	static inline ref t(void);
	static inline bool _is_t(ref);

	static inline ref nil(void);
	static inline bool _is_nil(ref);

	static inline ref from_a_scaled_int(int);
	static inline int to_a_scaled_int(ref);
}

void throw_TypeError(Object::ref, char const*);
void throw_RangeError(char const*);

template<typename T> static inline bool is_a(Object::ref);
template<typename T> static inline T as_a(Object::ref);

static inline bool is_t(Object::ref);

namespace Object {

/*-----------------------------------------------------------------------------
Configuration
-----------------------------------------------------------------------------*/

	static const unsigned char tag_bits = 2;// can bump up to 3 maybe...

	template<> struct tag_traits<int> {
		static const tag_type tag = 0x1;
	};
	template<> struct tag_traits<Generic*> {
		static const tag_type tag = 0x0;
	};
	template<> struct tag_traits<Symbol*> {
		static const tag_type tag = 0x2;
	};
	template<> struct tag_traits<UnicodeChar> {
		static const tag_type tag = 0x3;
	};

/*-----------------------------------------------------------------------------
Provided information
-----------------------------------------------------------------------------*/

	static const tag_type alignment = 1 << tag_bits;
	static const tag_type tag_mask = alignment - 1;

	/*the real range is the smaller of the range of intptr_t
	shifted down by tag bits, or the range of the `int' type
	*/
	static const intptr_t smallint_min =
		(sizeof(int) >= sizeof(intptr_t)) ?
			INTPTR_MIN >> tag_bits :
		/*otherwise*/
			INT_MIN;
	static const intptr_t smallint_max =
		(sizeof(int) >= sizeof(intptr_t)) ?
			INTPTR_MAX >> tag_bits :
		/*otherwise*/
			INT_MAX;

	/*value for "t"*/
	static const intptr_t t_value = ~((intptr_t) tag_mask);

/*-----------------------------------------------------------------------------
The tagged pointer type
-----------------------------------------------------------------------------*/

	/*stefano prefers to use:
		typedef void* ref;
	or maybe:
		typedef intptr_t ref;
	I may change this later on, but for now
	I want to see whether the conceptual
	separation will help and if compilers,
	in general, will be smart enough to
	optimize away the structure.
	*/
	class ref {
	private:
		intptr_t dat;
		ref(intptr_t x) : dat(x) {}
	public:
		ref(void) : dat(0) {}
		inline bool operator==(ref b) {
			return dat == b.dat;
		}
		inline bool operator!=(ref b) {
			return dat != b.dat;
		}
		inline bool operator!(void) {
			return dat == 0;
		}

		/*safe bool idiom*/
		typedef intptr_t (ref::*unspecified_bool_type);
		inline operator unspecified_bool_type(void) {
			return dat != 0 ? &ref::dat : 0;
		}

		template<typename T> friend ref to_ref(T);
		template<typename T> friend bool _is_a(ref);
		template<typename T> friend T _as_a(ref);

		friend int to_a_scaled_int(ref);
		friend ref from_a_scaled_int(int);

		friend ref t(void);
		friend bool _is_t(ref);
	};

/*-----------------------------------------------------------------------------
Tagged pointer factories
-----------------------------------------------------------------------------*/

	template<typename T>
	static inline ref to_ref(T x) {
		/* default to Generic* */
		return to_ref<Generic*>(x);
	}
	template<>
	ref to_ref<Generic*>(Generic* x) {
		intptr_t tmp = reinterpret_cast<intptr_t>(x);
		#ifdef DEBUG
			if(tmp & tag_mask != 0) {
				throw_RangeError("Misaligned pointer");
			}
		#endif
		return ref(tmp + tag_traits<Generic*>::tag);
	}
	template<>
	ref to_ref<Symbol*>(Symbol* x) {
		intptr_t tmp = reinterpret_cast<intptr_t>(x);
		#ifdef DEBUG
			if(tmp & tag_mask != 0) {
				throw_RangeError("Misaligned pointer");
			}
		#endif
		return ref(tmp + tag_traits<Symbol*>::tag);
	}
	template<>
	ref to_ref<int>(int x) {
		#ifdef DEBUG
			#if (INT_MAX >= INTPTR_MAX) || (INT_MIN <= INTPTR_MIN)
				if(x < smallint_min || x > smallint_max) {
					throw_RangeError(
						"int out of range of smallint"
					);
				}
			#endif
		#endif
		intptr_t tmp = (((intptr_t) x) << tag_bits);
		return ref(tmp + tag_traits<int>::tag);
	}
	template<>
	ref to_ref<UnicodeChar>(UnicodeChar x) {
		intptr_t tmp = x.dat << tag_bits;
		return ref(tmp + tag_traits<UnicodeChar>::tag);
	}

	/*no checking, even in debug mode... achtung!*/
	/*This function is used to convert an int computed using
	Object::to_a_scaled_int back to an Object::ref.  It is not
	intended to be used for any other int's.
	This function is intended for optimized smallint
	mathematics.
	*/
	static inline ref from_a_scaled_int(int x) {
                return ref((((intptr_t) x)<<tag_bits) + tag_traits<int>::tag);
	}

	static inline ref nil(void) {
		return ref();
	}
	static inline ref t(void) {
		return ref(t_value);
	}

/*-----------------------------------------------------------------------------
Tagged pointer checking
-----------------------------------------------------------------------------*/

	static inline bool _is_nil(ref obj) {
		return !obj;
	}
	static inline bool _is_t(ref obj) {
		return obj.dat == t_value;
	}

	template<typename T>
	static inline bool _is_a(ref obj) {
		if(tag_traits<T>::tag != 0x0) {
			return (obj.dat & tag_mask) == tag_traits<T>::tag;
		} else {
			return (obj.dat & tag_mask) == tag_traits<T>::tag
				&& !_is_nil(obj) && !_is_t(obj);
		}
	}

/*-----------------------------------------------------------------------------
Tagged pointer referencing
-----------------------------------------------------------------------------*/

	template<typename T>
	static inline T _as_a(ref obj) {
		#ifdef DEBUG
			if(!_is_a<T>(obj)) {
				throw_TypeError(obj,
					"incorrect type for pointer"
				);
			}
		#endif
		intptr_t tmp = obj.dat;
		return reinterpret_cast<T>(tmp - tag_traits<T>::tag);
		/*use subtraction instead of masking, in order to
		allow smart compilers to merge a field access with
		the tag removal. i.e. the pointers are pointers to
		structures, so they will be accessed via fields, and
		in all probability those fields will be at some
		offset from the actual structure address, meaning
		that the processor itself will perform an addition
		to access the field.  The smart compiler can then
		merge the addition of the field offset with the
		subtraction of the tag.
		*/
	}

	template<>
	int _as_a<int>(ref obj) {
		#ifdef DEBUG
			if(!_is_a<int>(obj)) {
				throw_TypeError(obj,
					"incorrect type for small integer"
				);
			}
		#endif
		intptr_t tmp = obj.dat;
		return (int)(tmp >> tag_bits);
	}

	template<>
	UnicodeChar _as_a<UnicodeChar>(ref obj) {
		uint32_t tmp = obj.dat;
		return UnicodeChar(tmp >> tag_bits);
	}

	/*no checking, even in debug mode... achtung!*/
	/*This function is used to convert a smallint Object::ref
	to a useable int that is equal to the "real" int, shifted
	to the left by the number of tag bits (i.e. scaled).  It
	should be used only for optimizing smallint math operations.
	*/
	static inline int to_a_scaled_int(ref obj) {
		intptr_t tmp = obj.dat;
		return (int)((tmp - tag_traits<int>::tag)>>tag_bits);
		/*use subtraction instead of masking, again to
		allow smart compilers to merge tag adding and
		subtracting.  For example the typical case would
		be something like:

		Object::ref result =
			Object::from_a_scaled_int(
				Object::to_a_scaled_int(a) +
				Object::to_a_scaled_int(b)
			);

		The above case can be reduced by the compiler to:

		intptr_t result =
			(tag_traits<int>::tag +
				a - tag_traits<int>::tag +
				b - tag_traits<int>::tag
			);

		It can then do some maths and cancel out a tag:

		intptr_t result = a + b - tag_traits<int>::tag;
		*/
	}

/*-----------------------------------------------------------------------------
Utility
-----------------------------------------------------------------------------*/

	static inline size_t round_up_to_alignment(size_t x) {
		return
		(x & tag_mask) ?      (x + alignment - (x & tag_mask)) :
		/*otherwise*/         x ;
	}

}

/*-----------------------------------------------------------------------------
Reflectors outside of the namespace
-----------------------------------------------------------------------------*/

template<typename T>
static inline bool is_a(Object::ref obj) {
	return Object::_is_a<T>(obj);
}
template<typename T>
static inline T as_a(Object::ref obj) {
	return Object::_as_a<T>(obj);
}
static inline bool is_nil(Object::ref obj) {
	return Object::_is_nil(obj);
}
static inline bool is_t(Object::ref obj) {
	return Object::_is_t(obj);
}

#endif //OBJECTS_H

<|endoftext|>


<commit_before><commit_msg>change efficiency corrected multiplicity bin<commit_after><|endoftext|>


<commit_before>#ifndef _SEARCH_HPP_
#define _SEARCH_HPP_

#include <cstdio>
#include <vector>

double walltime(void);
double cputime(void);
void dfpair(FILE *f, const char *key, const char *fmt, ...);

template <class D> struct Result {
	double wallstrt, cpustrt;
	double wallend, cpuend;
	unsigned long expd, gend, reopnd;
	long dups;
	typename D::Cost cost;
	std::vector<typename D::State> path;

	Result(bool dups = false) :
		expd(0), gend(0), reopnd(0),
		dups(-1), cost(D::InfCost) {
		if (dups)
			dups = 0;
		start();
	}

	void start(void) {
		wallstrt = walltime();
		cpustrt = cputime();
	}

	void finish(void) {
		wallend = walltime();
		cpuend = cputime();
	}

	void output(FILE *f) {
		dfpair(f, "state size", "%u", sizeof(typename D::State));
		dfpair(f, "packed state size", "%u", sizeof(typename D::PackedState));
		dfpair(f, "total raw cpu time", "%g", cpuend - cpustrt);
		dfpair(f, "total wall time", "%g", wallend - wallstrt);
		dfpair(f, "total nodes expanded", "%lu", expd);
		dfpair(f, "total nodes generated", "%lu", gend);
		if (dups >= 0)
			dfpair(f, "total nodes duplicated", "%ld", dups);
		dfpair(f, "total reopened", "%ld", reopnd);
		dfpair(f, "total sol cost", "%g", (double) cost);
		dfpair(f, "total sol length", "%lu", (unsigned long) path.size());
	}
};

template <class D> class Search {
public:
	virtual Result<D> search(D &, typename D::State &) = 0;
};

#endif	// _SEARCH_HPP_
<commit_msg>final sol cost/length instead of total.<commit_after>#ifndef _SEARCH_HPP_
#define _SEARCH_HPP_

#include <cstdio>
#include <vector>

double walltime(void);
double cputime(void);
void dfpair(FILE *f, const char *key, const char *fmt, ...);

template <class D> struct Result {
	double wallstrt, cpustrt;
	double wallend, cpuend;
	unsigned long expd, gend, reopnd;
	long dups;
	typename D::Cost cost;
	std::vector<typename D::State> path;

	Result(bool dups = false) :
		expd(0), gend(0), reopnd(0),
		dups(-1), cost(D::InfCost) {
		if (dups)
			dups = 0;
		start();
	}

	void start(void) {
		wallstrt = walltime();
		cpustrt = cputime();
	}

	void finish(void) {
		wallend = walltime();
		cpuend = cputime();
	}

	void output(FILE *f) {
		dfpair(f, "state size", "%u", sizeof(typename D::State));
		dfpair(f, "packed state size", "%u", sizeof(typename D::PackedState));
		dfpair(f, "total raw cpu time", "%g", cpuend - cpustrt);
		dfpair(f, "total wall time", "%g", wallend - wallstrt);
		dfpair(f, "total nodes expanded", "%lu", expd);
		dfpair(f, "total nodes generated", "%lu", gend);
		if (dups >= 0)
			dfpair(f, "total nodes duplicated", "%ld", dups);
		dfpair(f, "total reopened", "%ld", reopnd);
		dfpair(f, "final sol cost", "%g", (double) cost);
		dfpair(f, "final sol length", "%lu", (unsigned long) path.size());
	}
};

template <class D> class Search {
public:
	virtual Result<D> search(D &, typename D::State &) = 0;
};

#endif	// _SEARCH_HPP_
<|endoftext|>


<commit_before>/*
For more information, please see: http://software.sci.utah.edu

The MIT License

Copyright (c) 2012 Scientific Computing and Imaging Institute,
University of Utah.

License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

*/

#include <gtest/gtest.h>
#include <Core/Algorithms/Legacy/Fields/FieldData/ConvertFieldBasisType.h>
#include <Core/Algorithms/Field/Tests/LoadFieldsForAlgoCoreTests.h>
#include <Core/Algorithms/Base/AlgorithmPreconditions.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Core/Datatypes/MatrixComparison.h>
#include <Core/Utils/StringUtil.h>

using namespace SCIRun::Core::Geometry;
using namespace SCIRun::Core::Algorithms::Fields;

TEST(ConvertFieldBasisAlgoTest, TetMeshOnNodeVectorMat)
{
  ConvertFieldBasisTypeAlgo algo;

  FieldHandle tetmesh = LoadTet();

  const int givenBasis = 1;
  EXPECT_EQ(givenBasis, tetmesh->vfield()->basis_order());

  algo.set_option(Parameters::OutputType, "Constant");

  FieldHandle result;
  ASSERT_TRUE(algo.runImpl(tetmesh, result));

  const int expectedBasis = 0;
  EXPECT_EQ(expectedBasis, result->vfield()->basis_order());

  //TODO: compare basis
  FAIL() << "todo";
}

/*
TEST(SetFieldDataTest, TetMeshOnNodeScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnNodeScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TetMeshOnNodeTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnNodeTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TetMeshOnElemScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnElemScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TetMeshOnElemVectorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnElemVectorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TetMeshOnElemTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnElemTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnNodeVectorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeVectorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnNodeScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TriSurfOnNodeTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnElemVectorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnElemVectorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnElemScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnElemScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TriSurfOnElemTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

*/<commit_msg>Macro out mapping matrix for now<commit_after>/*
For more information, please see: http://software.sci.utah.edu

The MIT License

Copyright (c) 2012 Scientific Computing and Imaging Institute,
University of Utah.

License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

*/

#include <gtest/gtest.h>
#include <Core/Algorithms/Legacy/Fields/FieldData/ConvertFieldBasisType.h>
#include <Core/Algorithms/Field/Tests/LoadFieldsForAlgoCoreTests.h>
#include <Core/Algorithms/Base/AlgorithmPreconditions.h>
#include <Core/Datatypes/Legacy/Field/VField.h>
#include <Core/Datatypes/Legacy/Field/FieldInformation.h>
#include <Core/Datatypes/MatrixComparison.h>
#include <Core/Utils/StringUtil.h>

using namespace SCIRun::Core::Geometry;
using namespace SCIRun::Core::Algorithms::Fields;

TEST(ConvertFieldBasisAlgoTest, TetMeshOnNodeVectorMat)
{
  ConvertFieldBasisTypeAlgo algo;

  FieldHandle tetmesh = LoadTet();

  const int givenBasis = 1;
  EXPECT_EQ(givenBasis, tetmesh->vfield()->basis_order());

  algo.set_option(Parameters::OutputType, "Constant");
  algo.set(Parameters::BuildBasisMapping, false);

  FieldHandle result;
  ASSERT_TRUE(algo.runImpl(tetmesh, result));

  const int expectedBasis = 0;
  EXPECT_EQ(expectedBasis, result->vfield()->basis_order());
}

/*
TEST(SetFieldDataTest, TetMeshOnNodeScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnNodeScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TetMeshOnNodeTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnNodeTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TetMeshOnElemScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnElemScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TetMeshOnElemVectorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnElemVectorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TetMeshOnElemTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTet();

  DenseMatrixHandle matrix = TetMeshOnElemTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnNodeVectorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeVectorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnNodeScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TriSurfOnNodeTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnElemVectorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnElemVectorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, TriSurfOnElemScalarMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnElemScalarMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

TEST(SetFieldDataTest, DISABLED_TriSurfOnElemTensorMat)
{
  SetFieldDataAlgo algo;

  FieldHandle tetmesh = LoadTri();

  DenseMatrixHandle matrix = TriSurfOnNodeTensorMat();

  FieldHandle result = algo.run(tetmesh, matrix);

  GetFieldDataAlgo algo1;

  DenseMatrixHandle resultmatrix = algo1.run(result);

  EXPECT_MATRIX_EQ_TOLERANCE(*resultmatrix, *matrix, 1e-16);
}

*/<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <vector>
#include <string>
#include <cmath>

#include <utils.hpp>
#include <Observation.hpp>

#ifndef SNR_HPP
#define SNR_HPP

namespace PulsarSearch {

class snrDedispersedConf {
public:
  snrDedispersedConf();
  ~snrDedispersedConf();
  // Get
  unsigned int getNrSamplesPerBlock() const;
  unsigned int getNrSamplesPerThread() const;
  // Set
  void setNrSamplesPerBlock(unsigned int samples);
  void setNrSamplesPerThread(unsigned int samples);
  // utils
  std::string print() const;

private:
  unsigned int nrSamplesPerBlock;
  unsigned int nrSamplesPerThread;
};

// OpenCL SNR
std::string * getSNRDedispersedOpenCL(const snrDedispersedConf & conf, const std::string & dataType, const AstroData::Observation & observation);

// Implementations
inline unsigned int snrDedispersedConf::getNrSamplesPerBlock() const {
  return nrSamplesPerBlock;
}

inline unsigned int snrDedispersedConf::getNrSamplesPerThread() const {
  return nrSamplesPerThread;
}

inline void snrDedispersedConf::setNrSamplesPerBlock(unsigned int samples) {
  nrSamplesPerBlock = samples;
}

inline void snrDedispersedConf::setNrSamplesPerThread(unsigned int samples) {
  nrSamplesPerThread = samples;
}

} // PulsarSearch

#endif // SNR_HPP

<commit_msg>Reduced the number of parameters.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <vector>
#include <string>
#include <cmath>

#include <utils.hpp>
#include <Observation.hpp>

#ifndef SNR_HPP
#define SNR_HPP

namespace PulsarSearch {

class snrDedispersedConf {
public:
  snrDedispersedConf();
  ~snrDedispersedConf();
  // Get
  unsigned int getNrSamplesPerBlock() const;
  // Set
  void setNrSamplesPerBlock(unsigned int samples);
  // utils
  std::string print() const;

private:
  unsigned int nrSamplesPerBlock;
};

// OpenCL SNR
std::string * getSNRDedispersedOpenCL(const snrDedispersedConf & conf, const std::string & dataType, const AstroData::Observation & observation);

// Implementations
inline unsigned int snrDedispersedConf::getNrSamplesPerBlock() const {
  return nrSamplesPerBlock;
}

inline void snrDedispersedConf::setNrSamplesPerBlock(unsigned int samples) {
  nrSamplesPerBlock = samples;
}

} // PulsarSearch

#endif // SNR_HPP

<|endoftext|>


<commit_before>#ifndef _SNARKFRONT_SHA_224_HPP_
#define _SNARKFRONT_SHA_224_HPP_

#include <array>
#include <cstdint>
#include "Alg.hpp"
#include "Alg_uint.hpp"
#include "AST.hpp"
#include "BitwiseOps.hpp"
#include "Lazy.hpp"
#include "SHA_256.hpp"

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// SHA-224
//

template <typename T, typename MSG, typename U, typename F>
class SHA_224 : public SHA_256<T, MSG, U, F>
{
public:
    typedef T WordType;
    typedef U ByteType;

    typedef std::array<T, 16> MsgType;
    typedef std::array<T, 7> DigType;
    typedef std::array<U, 16 * 4> PreType;

    SHA_224()
        : m_setDigest(false)
    {}

    // overrides base class SHA-256
    const std::array<T, 7>& digest() {
        if (m_setDigest) {
            for (std::size_t i = 0; i < 7; ++i) {
                m_Hleft224[i] = this->m_H[i];
            }

            m_setDigest = false;
        }

        return m_Hleft224;
    }

    // overrides base class SHA-256
    virtual void initHashValue() {
        // set initial hash value (NIST FIPS 180-4 section 5.3.2)
        const std::array<std::uint32_t, 8> a {
            0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
            0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 };

        for (std::size_t i = 0; i < 8; ++i) {
            this->m_H[i] = F::constant(a[i]);
        }
    }

    virtual void afterHash() {
        m_setDigest = true;
    }

private:
    // truncated 224-bit message digest
    std::array<T, 7> m_Hleft224;

    bool m_setDigest;
};

////////////////////////////////////////////////////////////////////////////////
// typedefs
//

namespace zk {
    template <typename FR> using
    SHA224 = SHA_224<AST_Var<Alg_uint32<FR>>,
                     Lazy<AST_Var<Alg_uint32<FR>>, std::uint32_t>,
                     AST_Var<Alg_uint8<FR>>,
                     SHA_Functions<AST_Node<Alg_uint32<FR>>,
                                   AST_Op<Alg_uint32<FR>>,
                                   BitwiseAST<Alg_uint32<FR>, Alg_uint32<FR>>>>;
} // namespace zk

namespace eval {
    typedef SHA_224<std::uint32_t,
                    std::uint32_t,
                    std::uint8_t,
                    SHA_Functions<std::uint32_t,
                                  std::uint32_t,
                                  BitwiseINT<std::uint32_t, std::uint32_t>>>
        SHA224;
} // namespace eval

} // namespace snarkfront

#endif
<commit_msg>BitwiseOps templates<commit_after>#ifndef _SNARKFRONT_SHA_224_HPP_
#define _SNARKFRONT_SHA_224_HPP_

#include <array>
#include <cstdint>
#include "Alg.hpp"
#include "Alg_uint.hpp"
#include "AST.hpp"
#include "BitwiseOps.hpp"
#include "Lazy.hpp"
#include "SHA_256.hpp"

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// SHA-224
//

template <typename T, typename MSG, typename U, typename F>
class SHA_224 : public SHA_256<T, MSG, U, F>
{
public:
    typedef T WordType;
    typedef U ByteType;

    typedef std::array<T, 16> MsgType;
    typedef std::array<T, 7> DigType;
    typedef std::array<U, 16 * 4> PreType;

    SHA_224()
        : m_setDigest(false)
    {}

    // overrides base class SHA-256
    const std::array<T, 7>& digest() {
        if (m_setDigest) {
            for (std::size_t i = 0; i < 7; ++i) {
                m_Hleft224[i] = this->m_H[i];
            }

            m_setDigest = false;
        }

        return m_Hleft224;
    }

    // overrides base class SHA-256
    virtual void initHashValue() {
        // set initial hash value (NIST FIPS 180-4 section 5.3.2)
        const std::array<std::uint32_t, 8> a {
            0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
            0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 };

        for (std::size_t i = 0; i < 8; ++i) {
            this->m_H[i] = F::constant(a[i]);
        }
    }

    virtual void afterHash() {
        m_setDigest = true;
    }

private:
    // truncated 224-bit message digest
    std::array<T, 7> m_Hleft224;

    bool m_setDigest;
};

////////////////////////////////////////////////////////////////////////////////
// typedefs
//

namespace zk {
    template <typename FR> using
    SHA224 = SHA_224<AST_Var<Alg_uint32<FR>>,
                     Lazy<AST_Var<Alg_uint32<FR>>, std::uint32_t>,
                     AST_Var<Alg_uint8<FR>>,
                     SHA_Functions<AST_Node<Alg_uint32<FR>>,
                                   AST_Op<Alg_uint32<FR>>,
                                   BitwiseAST<Alg_uint32<FR>>>>;
} // namespace zk

namespace eval {
    typedef SHA_224<std::uint32_t,
                    std::uint32_t,
                    std::uint8_t,
                    SHA_Functions<std::uint32_t,
                                  std::uint32_t,
                                  BitwiseINT<std::uint32_t>>>
        SHA224;
} // namespace eval

} // namespace snarkfront

#endif
<|endoftext|>


<commit_before>#ifndef _SNARKFRONT_SHA_384_HPP_
#define _SNARKFRONT_SHA_384_HPP_

#include <array>
#include <cstdint>
#include "Alg.hpp"
#include "Alg_uint.hpp"
#include "AST.hpp"
#include "BitwiseOps.hpp"
#include "Lazy.hpp"
#include "SHA_512.hpp"

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// SHA-384
//

template <typename T, typename MSG, typename F>
class SHA_384 : public SHA_512<T, MSG, F>
{
public:
    typedef T WordType;
    typedef std::array<T, 16> MsgType;
    typedef std::array<T, 6> DigType;

    SHA_384()
        : m_setDigest(false)
    {}

    // overrides base class SHA-512
    const std::array<T, 6>& digest() {
        if (m_setDigest) {
            for (std::size_t i = 0; i < 6; ++i) {
                m_Hleft384[i] = this->m_H[i];
            }

            m_setDigest = false;
        }

        return m_Hleft384;
    }

    // overrides base class SHA-512
    virtual void initHashValue() {
        // set initial hash value (NIST FIPS 180-4 section 5.3.4)
        const std::array<uint64_t, 8> a {
            0xcbbb9d5dc1059ed8, 0x629a292a367cd507,
            0x9159015a3070dd17, 0x152fecd8f70e5939,

            0x67332667ffc00b31, 0x8eb44a8768581511,
            0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4 };

        for (std::size_t i = 0; i < 8; ++i) {
            this->m_H[i] = F::constant(a[i]);
        }
    }

    virtual void afterHash() {
        m_setDigest = true;
    }

private:
    // truncated 384-bit message digest
    std::array<T, 6> m_Hleft384;

    bool m_setDigest;
};

////////////////////////////////////////////////////////////////////////////////
// typedefs
//

namespace zk {
    template <typename FR> using
    SHA384 = SHA_384<AST_Var<Alg_uint64<FR>>,
                     Lazy<AST_Var<Alg_uint64<FR>>, std::uint64_t>,
                     SHA_Functions<AST_Node<Alg_uint64<FR>>,
                                   AST_Op<Alg_uint64<FR>>,
                                   BitwiseAST<Alg_uint64<FR>, Alg_uint64<FR>>>>;
} // namespace zk

namespace eval {
typedef SHA_384<std::uint64_t,
                std::uint64_t,
                SHA_Functions<std::uint64_t,
                              std::uint64_t,
                              BitwiseINT<std::uint64_t, std::uint64_t>>>
    SHA384;
} // namespace eval

} // namespace snarkfront

#endif
<commit_msg>8-bit unsigned int array pre-image<commit_after>#ifndef _SNARKFRONT_SHA_384_HPP_
#define _SNARKFRONT_SHA_384_HPP_

#include <array>
#include <cstdint>
#include "Alg.hpp"
#include "Alg_uint.hpp"
#include "AST.hpp"
#include "BitwiseOps.hpp"
#include "Lazy.hpp"
#include "SHA_512.hpp"

namespace snarkfront {

////////////////////////////////////////////////////////////////////////////////
// SHA-384
//

template <typename T, typename MSG, typename U, typename F>
class SHA_384 : public SHA_512<T, MSG, U, F>
{
public:
    typedef T WordType;
    typedef U ByteType;

    typedef std::array<T, 16> MsgType;
    typedef std::array<T, 6> DigType;
    typedef std::array<U, 16 * 8> PreType;

    SHA_384()
        : m_setDigest(false)
    {}

    // overrides base class SHA-512
    const std::array<T, 6>& digest() {
        if (m_setDigest) {
            for (std::size_t i = 0; i < 6; ++i) {
                m_Hleft384[i] = this->m_H[i];
            }

            m_setDigest = false;
        }

        return m_Hleft384;
    }

    // overrides base class SHA-512
    virtual void initHashValue() {
        // set initial hash value (NIST FIPS 180-4 section 5.3.4)
        const std::array<uint64_t, 8> a {
            0xcbbb9d5dc1059ed8, 0x629a292a367cd507,
            0x9159015a3070dd17, 0x152fecd8f70e5939,

            0x67332667ffc00b31, 0x8eb44a8768581511,
            0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4 };

        for (std::size_t i = 0; i < 8; ++i) {
            this->m_H[i] = F::constant(a[i]);
        }
    }

    virtual void afterHash() {
        m_setDigest = true;
    }

private:
    // truncated 384-bit message digest
    std::array<T, 6> m_Hleft384;

    bool m_setDigest;
};

////////////////////////////////////////////////////////////////////////////////
// typedefs
//

namespace zk {
    template <typename FR> using
    SHA384 = SHA_384<AST_Var<Alg_uint64<FR>>,
                     Lazy<AST_Var<Alg_uint64<FR>>, std::uint64_t>,
                     AST_Var<Alg_uint8<FR>>,
                     SHA_Functions<AST_Node<Alg_uint64<FR>>,
                                   AST_Op<Alg_uint64<FR>>,
                                   BitwiseAST<Alg_uint64<FR>, Alg_uint64<FR>>>>;
} // namespace zk

namespace eval {
typedef SHA_384<std::uint64_t,
                std::uint64_t,
                std::uint8_t,
                SHA_Functions<std::uint64_t,
                              std::uint64_t,
                              BitwiseINT<std::uint64_t, std::uint64_t>>>
    SHA384;
} // namespace eval

} // namespace snarkfront

#endif
<|endoftext|>


<commit_before>//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <errno.h>

#include "lldb/Host/Config.h"

#include "GDBRemoteCommunicationReplayServer.h"
#include "ProcessGDBRemoteLog.h"

// C Includes
// C++ Includes
#include <cstring>

// Project includes
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"

using namespace llvm;
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;

GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
    : GDBRemoteCommunication("gdb-remote.server",
                             "gdb-remote.server.rx_packet"),
      m_async_broadcaster(nullptr, "lldb.gdb-remote.server.async-broadcaster"),
      m_async_listener_sp(
          Listener::MakeListener("lldb.gdb-remote.server.async-listener")),
      m_async_thread_state_mutex(), m_skip_acks(false) {
  m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
                                   "async thread continue");
  m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
                                   "async thread should exit");

  const uint32_t async_event_mask =
      eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
  m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster,
                                               async_event_mask);
}

GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() {
  StopAsyncThread();
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
    Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
  StringExtractorGDBRemote packet;
  PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);

  if (packet_result != PacketResult::Success) {
    if (!IsConnected()) {
      error.SetErrorString("lost connection");
      quit = true;
    } else {
      error.SetErrorString("timeout");
    }
    return packet_result;
  }

  m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);

  if (m_skip_acks) {
    const StringExtractorGDBRemote::ServerPacketType packet_type =
        packet.GetServerPacketType();
    switch (packet_type) {
    case StringExtractorGDBRemote::eServerPacketType_nack:
    case StringExtractorGDBRemote::eServerPacketType_ack:
      return PacketResult::Success;
    default:
      break;
    }
  } else if (packet.GetStringRef() == "QStartNoAckMode") {
    m_skip_acks = true;
    m_send_acks = false;
  }

  while (!m_packet_history.empty()) {
    // Pop last packet from the history.
    GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
    m_packet_history.pop_back();

    // We only care about what we received from the server. Skip everything
    // the client sent.
    if (entry.type != GDBRemoteCommunicationHistory::ePacketTypeRecv)
      continue;

    return SendRawPacketNoLock(entry.packet.data, true);
  }

  quit = true;

  return packet_result;
}

LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
    std::vector<
        lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>)

llvm::Error
GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) {
  auto error_or_file = MemoryBuffer::getFile(path.GetPath());
  if (auto err = error_or_file.getError())
    return errorCodeToError(err);

  yaml::Input yin((*error_or_file)->getBuffer());
  yin >> m_packet_history;

  if (auto err = yin.error())
    return errorCodeToError(err);

  // We want to manipulate the vector like a stack so we need to reverse the
  // order of the packets to have the oldest on at the back.
  std::reverse(m_packet_history.begin(), m_packet_history.end());

  return Error::success();
}

bool GDBRemoteCommunicationReplayServer::StartAsyncThread() {
  std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
  if (!m_async_thread.IsJoinable()) {
    // Create a thread that watches our internal state and controls which
    // events make it to clients (into the DCProcess event queue).
    m_async_thread = ThreadLauncher::LaunchThread(
        "<lldb.gdb-remote.server.async>",
        GDBRemoteCommunicationReplayServer::AsyncThread, this, nullptr);
  }

  // Wait for handshake.
  m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);

  return m_async_thread.IsJoinable();
}

void GDBRemoteCommunicationReplayServer::StopAsyncThread() {
  std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);

  if (!m_async_thread.IsJoinable())
    return;

  // Request thread to stop.
  m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);

  // Disconnect client.
  Disconnect();

  // Stop the thread.
  m_async_thread.Join(nullptr);
  m_async_thread.Reset();
}

void GDBRemoteCommunicationReplayServer::ReceivePacket(
    GDBRemoteCommunicationReplayServer &server, bool &done) {
  Status error;
  bool interrupt;
  auto packet_result = server.GetPacketAndSendResponse(std::chrono::seconds(1),
                                                       error, interrupt, done);
  if (packet_result != GDBRemoteCommunication::PacketResult::Success &&
      packet_result !=
          GDBRemoteCommunication::PacketResult::ErrorReplyTimeout) {
    done = true;
  } else {
    server.m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
  }
}

thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) {
  GDBRemoteCommunicationReplayServer *server =
      (GDBRemoteCommunicationReplayServer *)arg;

  EventSP event_sp;
  bool done = false;

  while (true) {
    if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
      const uint32_t event_type = event_sp->GetType();
      if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) {
        switch (event_type) {
        case eBroadcastBitAsyncContinue:
          ReceivePacket(*server, done);
          if (done)
            return {};
          break;
        case eBroadcastBitAsyncThreadShouldExit:
        default:
          return {};
        }
      }
    }
  }

  return {};
}
<commit_msg>[Reproducers] Fix data race found by tsan<commit_after>//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <errno.h>

#include "lldb/Host/Config.h"

#include "GDBRemoteCommunicationReplayServer.h"
#include "ProcessGDBRemoteLog.h"

// C Includes
// C++ Includes
#include <cstring>

// Project includes
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"

using namespace llvm;
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;

GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
    : GDBRemoteCommunication("gdb-remote.server",
                             "gdb-remote.server.rx_packet"),
      m_async_broadcaster(nullptr, "lldb.gdb-remote.server.async-broadcaster"),
      m_async_listener_sp(
          Listener::MakeListener("lldb.gdb-remote.server.async-listener")),
      m_async_thread_state_mutex(), m_skip_acks(false) {
  m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
                                   "async thread continue");
  m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
                                   "async thread should exit");

  const uint32_t async_event_mask =
      eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
  m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster,
                                               async_event_mask);
}

GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() {
  StopAsyncThread();
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
    Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
  std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);

  StringExtractorGDBRemote packet;
  PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);

  if (packet_result != PacketResult::Success) {
    if (!IsConnected()) {
      error.SetErrorString("lost connection");
      quit = true;
    } else {
      error.SetErrorString("timeout");
    }
    return packet_result;
  }

  m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);

  if (m_skip_acks) {
    const StringExtractorGDBRemote::ServerPacketType packet_type =
        packet.GetServerPacketType();
    switch (packet_type) {
    case StringExtractorGDBRemote::eServerPacketType_nack:
    case StringExtractorGDBRemote::eServerPacketType_ack:
      return PacketResult::Success;
    default:
      break;
    }
  } else if (packet.GetStringRef() == "QStartNoAckMode") {
    m_skip_acks = true;
    m_send_acks = false;
  }

  while (!m_packet_history.empty()) {
    // Pop last packet from the history.
    GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
    m_packet_history.pop_back();

    // We only care about what we received from the server. Skip everything
    // the client sent.
    if (entry.type != GDBRemoteCommunicationHistory::ePacketTypeRecv)
      continue;

    return SendRawPacketNoLock(entry.packet.data, true);
  }

  quit = true;

  return packet_result;
}

LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
    std::vector<
        lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>)

llvm::Error
GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) {
  auto error_or_file = MemoryBuffer::getFile(path.GetPath());
  if (auto err = error_or_file.getError())
    return errorCodeToError(err);

  yaml::Input yin((*error_or_file)->getBuffer());
  yin >> m_packet_history;

  if (auto err = yin.error())
    return errorCodeToError(err);

  // We want to manipulate the vector like a stack so we need to reverse the
  // order of the packets to have the oldest on at the back.
  std::reverse(m_packet_history.begin(), m_packet_history.end());

  return Error::success();
}

bool GDBRemoteCommunicationReplayServer::StartAsyncThread() {
  std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
  if (!m_async_thread.IsJoinable()) {
    // Create a thread that watches our internal state and controls which
    // events make it to clients (into the DCProcess event queue).
    m_async_thread = ThreadLauncher::LaunchThread(
        "<lldb.gdb-remote.server.async>",
        GDBRemoteCommunicationReplayServer::AsyncThread, this, nullptr);
  }

  // Wait for handshake.
  m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);

  return m_async_thread.IsJoinable();
}

void GDBRemoteCommunicationReplayServer::StopAsyncThread() {
  std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);

  if (!m_async_thread.IsJoinable())
    return;

  // Request thread to stop.
  m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);

  // Disconnect client.
  Disconnect();

  // Stop the thread.
  m_async_thread.Join(nullptr);
  m_async_thread.Reset();
}

void GDBRemoteCommunicationReplayServer::ReceivePacket(
    GDBRemoteCommunicationReplayServer &server, bool &done) {
  Status error;
  bool interrupt;
  auto packet_result = server.GetPacketAndSendResponse(std::chrono::seconds(1),
                                                       error, interrupt, done);
  if (packet_result != GDBRemoteCommunication::PacketResult::Success &&
      packet_result !=
          GDBRemoteCommunication::PacketResult::ErrorReplyTimeout) {
    done = true;
  } else {
    server.m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
  }
}

thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) {
  GDBRemoteCommunicationReplayServer *server =
      (GDBRemoteCommunicationReplayServer *)arg;

  EventSP event_sp;
  bool done = false;

  while (true) {
    if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
      const uint32_t event_type = event_sp->GetType();
      if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) {
        switch (event_type) {
        case eBroadcastBitAsyncContinue:
          ReceivePacket(*server, done);
          if (done)
            return {};
          break;
        case eBroadcastBitAsyncThreadShouldExit:
        default:
          return {};
        }
      }
    }
  }

  return {};
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"

namespace {

class OptionsUITest : public UITest {
 public:
  OptionsUITest() {
    dom_automation_enabled_ = true;
    // TODO(csilv): Remove when dom-ui options is enabled by default.
    launch_arguments_.AppendSwitch(switches::kEnableTabbedOptions);
  }

  void AssertIsOptionsPage(TabProxy* tab) {
    std::wstring title;
    ASSERT_TRUE(tab->GetTabTitle(&title));
    ASSERT_EQ(L"Chromium Options", title);
  }
};

TEST_F(OptionsUITest, LoadOptionsByURL) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Go to the options tab via URL.
  NavigateToURL(GURL(chrome::kChromeUIOptionsURL));
  AssertIsOptionsPage(tab);
}

TEST_F(OptionsUITest, CommandOpensOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);
}

TEST_F(OptionsUITest, CommandAgainGoesBackToOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);

  // Switch to first tab and run command again.
  ASSERT_TRUE(browser->ActivateTab(0));
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(0, action_max_timeout_ms()));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));

  // Ensure the options ui tab is active.
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(1, action_max_timeout_ms()));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

TEST_F(OptionsUITest, TwoCommandsOneTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

}  // namespace
<commit_msg>Mark CommandAgainGoesBackToOptionsTab as failing<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"

namespace {

class OptionsUITest : public UITest {
 public:
  OptionsUITest() {
    dom_automation_enabled_ = true;
    // TODO(csilv): Remove when dom-ui options is enabled by default.
    launch_arguments_.AppendSwitch(switches::kEnableTabbedOptions);
  }

  void AssertIsOptionsPage(TabProxy* tab) {
    std::wstring title;
    ASSERT_TRUE(tab->GetTabTitle(&title));
    ASSERT_EQ(L"Chromium Options", title);
  }
};

TEST_F(OptionsUITest, LoadOptionsByURL) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Go to the options tab via URL.
  NavigateToURL(GURL(chrome::kChromeUIOptionsURL));
  AssertIsOptionsPage(tab);
}

TEST_F(OptionsUITest, CommandOpensOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);
}

TEST_F(OptionsUITest, FAILS_CommandAgainGoesBackToOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);

  // Switch to first tab and run command again.
  ASSERT_TRUE(browser->ActivateTab(0));
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(0, action_max_timeout_ms()));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));

  // Ensure the options ui tab is active.
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(1, action_max_timeout_ms()));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

TEST_F(OptionsUITest, TwoCommandsOneTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

}  // namespace
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.

#include "chrome/browser/page_menu_model.h"

#include "base/logging.h"
#include "chrome/test/browser_with_test_window_test.h"
#include "chrome/test/menu_model_test.h"
#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"

class PageMenuModelTest : public BrowserWithTestWindowTest,
                          public MenuModelTest {
};

TEST_F(PageMenuModelTest, Basics) {
  PageMenuModel model(&delegate_, browser());
  int itemCount = model.GetItemCount();

  // Verify it has items. The number varies by platform, so we don't check
  // the exact number.
  EXPECT_GT(itemCount, 10);

  // Execute a couple of the items and make sure it gets back to our delegate.
  // We can't use CountEnabledExecutable() here because the encoding menu's
  // delegate is internal, it doesn't use the one we pass in.
  model.ActivatedAt(0);
  EXPECT_TRUE(model.IsEnabledAt(0));
  model.ActivatedAt(3);
  EXPECT_TRUE(model.IsEnabledAt(3));
  EXPECT_EQ(delegate_.execute_count_, 2);
  EXPECT_EQ(delegate_.enable_count_, 2);

  delegate_.execute_count_ = 0;
  delegate_.enable_count_ = 0;

  // Choose something from the zoom submenu and make sure it makes it back to
  // the delegate as well. Use the first submenu as the zoom one.
  int zoomModelIndex = -1;
  for (int i = 0; i < itemCount; ++i) {
    if (model.GetTypeAt(i) == menus::MenuModel::TYPE_SUBMENU) {
      zoomModelIndex = i;
      break;
    }
  }
  EXPECT_GT(zoomModelIndex, -1);
  menus::MenuModel* zoomModel = model.GetSubmenuModelAt(zoomModelIndex);
  EXPECT_TRUE(zoomModel);
  EXPECT_GT(zoomModel->GetItemCount(), 1);
  zoomModel->ActivatedAt(1);
  EXPECT_TRUE(zoomModel->IsEnabledAt(1));
  EXPECT_EQ(delegate_.execute_count_, 1);
  EXPECT_EQ(delegate_.enable_count_, 1);
}
<commit_msg>The test was failing in chromeos build.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
// source code is governed by a BSD-style license that can be found in the
// LICENSE file.

#include "chrome/browser/page_menu_model.h"

#include "base/logging.h"
#include "chrome/test/browser_with_test_window_test.h"
#include "chrome/test/menu_model_test.h"
#include "grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"

class PageMenuModelTest : public BrowserWithTestWindowTest,
                          public MenuModelTest {
};

TEST_F(PageMenuModelTest, Basics) {
  PageMenuModel model(&delegate_, browser());
  int itemCount = model.GetItemCount();

  // Verify it has items. The number varies by platform, so we don't check
  // the exact number.
  EXPECT_GT(itemCount, 10);

  // Execute a couple of the items and make sure it gets back to our delegate.
  // We can't use CountEnabledExecutable() here because the encoding menu's
  // delegate is internal, it doesn't use the one we pass in.
  model.ActivatedAt(0);
  EXPECT_TRUE(model.IsEnabledAt(0));
  // Make sure to use the index that is not separator in all configurations.
  model.ActivatedAt(2);
  EXPECT_TRUE(model.IsEnabledAt(2));
  EXPECT_EQ(delegate_.execute_count_, 2);
  EXPECT_EQ(delegate_.enable_count_, 2);

  delegate_.execute_count_ = 0;
  delegate_.enable_count_ = 0;

  // Choose something from the zoom submenu and make sure it makes it back to
  // the delegate as well. Use the first submenu as the zoom one.
  int zoomModelIndex = -1;
  for (int i = 0; i < itemCount; ++i) {
    if (model.GetTypeAt(i) == menus::MenuModel::TYPE_SUBMENU) {
      zoomModelIndex = i;
      break;
    }
  }
  EXPECT_GT(zoomModelIndex, -1);
  menus::MenuModel* zoomModel = model.GetSubmenuModelAt(zoomModelIndex);
  EXPECT_TRUE(zoomModel);
  EXPECT_GT(zoomModel->GetItemCount(), 1);
  zoomModel->ActivatedAt(1);
  EXPECT_TRUE(zoomModel->IsEnabledAt(1));
  EXPECT_EQ(delegate_.execute_count_, 1);
  EXPECT_EQ(delegate_.enable_count_, 1);
}
<|endoftext|>


<commit_before>#pragma once

// only included in case there's a C++11 compiler out there that doesn't support `#pragma once`
#ifndef DKM_KMEANS_H
#define DKM_KMEANS_H

#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <random>
#include <tuple>
#include <type_traits>
#include <vector>

/*
DKM - A k-means implementation that is generic across variable data dimensions.
*/
namespace dkm {

/*
These functions are all private implementation details and shouldn't be referenced outside of this
file.
*/
namespace details {

/*
Calculate the square of the distance between two points.
*/
template <typename T, size_t N>
T distance_squared(const std::array<T, N>& point_a, const std::array<T, N>& point_b) {
	T d_squared = T();
	for (typename std::array<T, N>::size_type i = 0; i < N; ++i) {
		auto delta = point_a[i] - point_b[i];
		d_squared += delta * delta;
	}
	return d_squared;
}

template <typename T, size_t N>
T distance(const std::array<T, N>& point_a, const std::array<T, N>& point_b) {
	return std::sqrt(distance_squared(point_a, point_b));
}

/*
Calculate the smallest distance between each of the data points and any of the input means.
*/
template <typename T, size_t N>
std::vector<T> closest_distance(
	const std::vector<std::array<T, N>>& means, const std::vector<std::array<T, N>>& data) {
	std::vector<T> distances;
	distances.reserve(data.size());
	for (auto& d : data) {
		T closest = distance_squared(d, means[0]);
		for (auto& m : means) {
			T distance = distance_squared(d, m);
			if (distance < closest)
				closest = distance;
		}
		distances.push_back(closest);
	}
	return distances;
}

/*
This is an alternate initialization method based on the [kmeans++](https://en.wikipedia.org/wiki/K-means%2B%2B)
initialization algorithm.
*/
template <typename T, size_t N>
std::vector<std::array<T, N>> random_plusplus(const std::vector<std::array<T, N>>& data, uint32_t k) {
	assert(k > 0);
	assert(data.size() > 0);
	using input_size_t = typename std::array<T, N>::size_type;
	std::vector<std::array<T, N>> means;
	// Using a very simple PRBS generator, parameters selected according to
	// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
	std::random_device rand_device;
	std::linear_congruential_engine<uint64_t, 6364136223846793005, 1442695040888963407, UINT64_MAX> rand_engine(
		rand_device());

	// Select first mean at random from the set
	{
		std::uniform_int_distribution<input_size_t> uniform_generator(0, data.size() - 1);
		means.push_back(data[uniform_generator(rand_engine)]);
	}

	for (uint32_t count = 1; count < k; ++count) {
		// Calculate the distance to the closest mean for each data point
		auto distances = details::closest_distance(means, data);
		// Pick a random point weighted by the distance from existing means
		// TODO: This might convert floating point weights to ints, distorting the distribution for small weights
#if !defined(_MSC_VER) || _MSC_VER >= 1900
		std::discrete_distribution<input_size_t> generator(distances.begin(), distances.end());
#else  // MSVC++ older than 14.0
		input_size_t i = 0;
		std::discrete_distribution<input_size_t> generator(distances.size(), 0.0, 0.0, [&distances, &i](double) { return distances[i++]; });
#endif
		means.push_back(data[generator(rand_engine)]);
	}
	return means;
}

/*
Calculate the index of the mean a particular data point is closest to (euclidean distance)
*/
template <typename T, size_t N>
uint32_t closest_mean(const std::array<T, N>& point, const std::vector<std::array<T, N>>& means) {
	assert(!means.empty());
	T smallest_distance = distance_squared(point, means[0]);
	typename std::array<T, N>::size_type index = 0;
	T distance;
	for (size_t i = 1; i < means.size(); ++i) {
		distance = distance_squared(point, means[i]);
		if (distance < smallest_distance) {
			smallest_distance = distance;
			index = i;
		}
	}
	return index;
}

/*
Calculate the index of the mean each data point is closest to (euclidean distance).
*/
template <typename T, size_t N>
std::vector<uint32_t> calculate_clusters(
	const std::vector<std::array<T, N>>& data, const std::vector<std::array<T, N>>& means) {
	std::vector<uint32_t> clusters;
	for (auto& point : data) {
		clusters.push_back(closest_mean(point, means));
	}
	return clusters;
}

/*
Calculate means based on data points and their cluster assignments.
*/
template <typename T, size_t N>
std::vector<std::array<T, N>> calculate_means(const std::vector<std::array<T, N>>& data,
	const std::vector<uint32_t>& clusters,
	const std::vector<std::array<T, N>>& old_means,
	uint32_t k) {
	std::vector<std::array<T, N>> means(k);
	std::vector<T> count(k, T());
	for (size_t i = 0; i < std::min(clusters.size(), data.size()); ++i) {
		auto& mean = means[clusters[i]];
		count[clusters[i]] += 1;
		for (size_t j = 0; j < std::min(data[i].size(), mean.size()); ++j) {
			mean[j] += data[i][j];
		}
	}
	for (size_t i = 0; i < k; ++i) {
		if (count[i] == 0) {
			means[i] = old_means[i];
		} else {
			for (size_t j = 0; j < means[i].size(); ++j) {
				means[i][j] /= count[i];
			}
		}
	}
	return means;
}

template <typename T, size_t N>
std::vector<T> deltas(
	const std::vector<std::array<T, N>>& old_means, const std::vector<std::array<T, N>>& means)
{
	std::vector<T> distances;
	distances.reserve(means.size());
	assert(old_means.size() == means.size());
	for (size_t i = 0; i < means.size(); ++i) {
		distances.push_back(distance(means[i], old_means[i]));
	}
	return distances;
}

template <typename T>
bool deltas_below_limit(const std::vector<T>& deltas, T min_delta) {
	for (T d : deltas) {
		if (d > min_delta) {
			return true;
		}
	}
	return false;
}

} // namespace details

/*
clustering_parameters is the configuration used for running the kmeans_lloyd algorithm.

It requires a k value for initialization, and can subsequently be configured with your choice
of optional parameters, including:
* Maximum iteration count; the algorithm will terminate if it reaches this iteration count
  before converging on a solution. The results returned are the means and cluster assignments
  calculated in the last iteration before termination.
* Minimum delta; the algorithm will terminate if the change in position of all means is
  smaller than the specified distance.
* Random seed; if present, this will be used in place of `std::random_device` for kmeans++
  initialization. This can be used to ensure reproducible/deterministic behavior.
*/
template <typename T>
class clustering_parameters {
public:
	explicit clustering_parameters(uint32_t k) :
	_k(k),
	_has_max_iter(false), _max_iter(),
	_has_min_delta(false), _min_delta(),
	_has_rand_seed(false), _rand_seed()
	{}

	void set_max_iteration(uint64_t max_iter)
	{
		_max_iter = max_iter;
		_has_max_iter = true;
	}

	void set_min_delta(T min_delta)
	{
		_min_delta = min_delta;
		_has_min_delta = true;
	}

	void set_random_seed(uint64_t rand_seed)
	{
		_rand_seed = rand_seed;
		_has_rand_seed = true;
	}

	bool has_max_iteration() { return _has_max_iter; }
	bool has_min_delta() { return _has_min_delta; }
	bool has_random_seed() { return _has_rand_seed; }

	uint32_t get_k() { return _k; };
	uint64_t get_max_iteration() { return _max_iter; }
	T get_min_delta() { return _min_delta; }
	uint64_t get_random_seed() { return _has_rand_seed; }

private:
	uint32_t _k;
	bool _has_max_iter;
	uint64_t _max_iter;
	bool _has_min_delta;
	T _min_delta;
	bool _has_rand_seed;
	uint64_t _rand_seed;
}

/*
Implementation of k-means generic across the data type and the dimension of each data item. Expects
the data to be a vector of fixed-size arrays. Generic parameters are the type of the base data (T)
and the dimensionality of each data point (N). All points must have the same dimensionality.

Optional parameters are a maximum iteration count and a minimum delta. If the maximum iteration
count is greater than 0, then the algorithm will terminate when that number of iterations is reached.
If a minimum delta greater than 0 is specified then the algorithm will terminate when none of the
means change by more than the specified amount.

e.g. points of the form (X, Y, Z) would be N = 3.

Returns a std::tuple containing:
  0: A vector holding the means for each cluster from 0 to k-1.
  1: A vector containing the cluster number (0 to k-1) for each corresponding element of the input
	 data vector.

Implementation details:
This implementation of k-means uses [Lloyd's Algorithm](https://en.wikipedia.org/wiki/Lloyd%27s_algorithm)
with the [kmeans++](https://en.wikipedia.org/wiki/K-means%2B%2B)
used for initializing the means.
*/
template <typename T, size_t N>
std::tuple<std::vector<std::array<T, N>>, std::vector<uint32_t>> kmeans_lloyd(
	const std::vector<std::array<T, N>>& data, uint32_t k,
	uint64_t max_iter = 0, T min_delta = -1.0) {
	static_assert(std::is_arithmetic<T>::value && std::is_signed<T>::value,
		"kmeans_lloyd requires the template parameter T to be a signed arithmetic type (e.g. float, double, int)");
	assert(k > 0); // k must be greater than zero
	assert(data.size() >= k); // there must be at least k data points
	std::vector<std::array<T, N>> means = details::random_plusplus(data, k);

	std::vector<std::array<T, N>> old_means;
	std::vector<std::array<T, N>> old_old_means;
	std::vector<uint32_t> clusters;
	// Calculate new means until convergence is reached or we hit the maximum iteration count
	uint64_t count = 0;
	do {
		clusters = details::calculate_clusters(data, means);
		old_old_means = old_means;
		old_means = means;
		means = details::calculate_means(data, clusters, old_means, k);
		++count;
	} while ((means != old_means && means != old_old_means)
		|| (max_iter != 0 && count == max_iter)
		|| (min_delta > 0 && !details::deltas_below_limit(details::deltas(old_means, means), min_delta)));

	return std::tuple<std::vector<std::array<T, N>>, std::vector<uint32_t>>(means, clusters);
}

} // namespace dkm

#endif /* DKM_KMEANS_H */
<commit_msg>Implemented support for clustering_parameters struct.<commit_after>#pragma once

// only included in case there's a C++11 compiler out there that doesn't support `#pragma once`
#ifndef DKM_KMEANS_H
#define DKM_KMEANS_H

#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <random>
#include <tuple>
#include <type_traits>
#include <vector>

/*
DKM - A k-means implementation that is generic across variable data dimensions.
*/
namespace dkm {

/*
These functions are all private implementation details and shouldn't be referenced outside of this
file.
*/
namespace details {

/*
Calculate the square of the distance between two points.
*/
template <typename T, size_t N>
T distance_squared(const std::array<T, N>& point_a, const std::array<T, N>& point_b) {
	T d_squared = T();
	for (typename std::array<T, N>::size_type i = 0; i < N; ++i) {
		auto delta = point_a[i] - point_b[i];
		d_squared += delta * delta;
	}
	return d_squared;
}

template <typename T, size_t N>
T distance(const std::array<T, N>& point_a, const std::array<T, N>& point_b) {
	return std::sqrt(distance_squared(point_a, point_b));
}

/*
Calculate the smallest distance between each of the data points and any of the input means.
*/
template <typename T, size_t N>
std::vector<T> closest_distance(
	const std::vector<std::array<T, N>>& means, const std::vector<std::array<T, N>>& data) {
	std::vector<T> distances;
	distances.reserve(data.size());
	for (auto& d : data) {
		T closest = distance_squared(d, means[0]);
		for (auto& m : means) {
			T distance = distance_squared(d, m);
			if (distance < closest)
				closest = distance;
		}
		distances.push_back(closest);
	}
	return distances;
}

/*
This is an alternate initialization method based on the [kmeans++](https://en.wikipedia.org/wiki/K-means%2B%2B)
initialization algorithm.
*/
template <typename T, size_t N>
std::vector<std::array<T, N>> random_plusplus(const std::vector<std::array<T, N>>& data, uint32_t k) {
	assert(k > 0);
	assert(data.size() > 0);
	using input_size_t = typename std::array<T, N>::size_type;
	std::vector<std::array<T, N>> means;
	// Using a very simple PRBS generator, parameters selected according to
	// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
	std::random_device rand_device;
	std::linear_congruential_engine<uint64_t, 6364136223846793005, 1442695040888963407, UINT64_MAX> rand_engine(
		rand_device());

	// Select first mean at random from the set
	{
		std::uniform_int_distribution<input_size_t> uniform_generator(0, data.size() - 1);
		means.push_back(data[uniform_generator(rand_engine)]);
	}

	for (uint32_t count = 1; count < k; ++count) {
		// Calculate the distance to the closest mean for each data point
		auto distances = details::closest_distance(means, data);
		// Pick a random point weighted by the distance from existing means
		// TODO: This might convert floating point weights to ints, distorting the distribution for small weights
#if !defined(_MSC_VER) || _MSC_VER >= 1900
		std::discrete_distribution<input_size_t> generator(distances.begin(), distances.end());
#else  // MSVC++ older than 14.0
		input_size_t i = 0;
		std::discrete_distribution<input_size_t> generator(distances.size(), 0.0, 0.0, [&distances, &i](double) { return distances[i++]; });
#endif
		means.push_back(data[generator(rand_engine)]);
	}
	return means;
}

/*
Calculate the index of the mean a particular data point is closest to (euclidean distance)
*/
template <typename T, size_t N>
uint32_t closest_mean(const std::array<T, N>& point, const std::vector<std::array<T, N>>& means) {
	assert(!means.empty());
	T smallest_distance = distance_squared(point, means[0]);
	typename std::array<T, N>::size_type index = 0;
	T distance;
	for (size_t i = 1; i < means.size(); ++i) {
		distance = distance_squared(point, means[i]);
		if (distance < smallest_distance) {
			smallest_distance = distance;
			index = i;
		}
	}
	return index;
}

/*
Calculate the index of the mean each data point is closest to (euclidean distance).
*/
template <typename T, size_t N>
std::vector<uint32_t> calculate_clusters(
	const std::vector<std::array<T, N>>& data, const std::vector<std::array<T, N>>& means) {
	std::vector<uint32_t> clusters;
	for (auto& point : data) {
		clusters.push_back(closest_mean(point, means));
	}
	return clusters;
}

/*
Calculate means based on data points and their cluster assignments.
*/
template <typename T, size_t N>
std::vector<std::array<T, N>> calculate_means(const std::vector<std::array<T, N>>& data,
	const std::vector<uint32_t>& clusters,
	const std::vector<std::array<T, N>>& old_means,
	uint32_t k) {
	std::vector<std::array<T, N>> means(k);
	std::vector<T> count(k, T());
	for (size_t i = 0; i < std::min(clusters.size(), data.size()); ++i) {
		auto& mean = means[clusters[i]];
		count[clusters[i]] += 1;
		for (size_t j = 0; j < std::min(data[i].size(), mean.size()); ++j) {
			mean[j] += data[i][j];
		}
	}
	for (size_t i = 0; i < k; ++i) {
		if (count[i] == 0) {
			means[i] = old_means[i];
		} else {
			for (size_t j = 0; j < means[i].size(); ++j) {
				means[i][j] /= count[i];
			}
		}
	}
	return means;
}

template <typename T, size_t N>
std::vector<T> deltas(
	const std::vector<std::array<T, N>>& old_means, const std::vector<std::array<T, N>>& means)
{
	std::vector<T> distances;
	distances.reserve(means.size());
	assert(old_means.size() == means.size());
	for (size_t i = 0; i < means.size(); ++i) {
		distances.push_back(distance(means[i], old_means[i]));
	}
	return distances;
}

template <typename T>
bool deltas_below_limit(const std::vector<T>& deltas, T min_delta) {
	for (T d : deltas) {
		if (d > min_delta) {
			return true;
		}
	}
	return false;
}

} // namespace details

/*
clustering_parameters is the configuration used for running the kmeans_lloyd algorithm.

It requires a k value for initialization, and can subsequently be configured with your choice
of optional parameters, including:
* Maximum iteration count; the algorithm will terminate if it reaches this iteration count
  before converging on a solution. The results returned are the means and cluster assignments
  calculated in the last iteration before termination.
* Minimum delta; the algorithm will terminate if the change in position of all means is
  smaller than the specified distance.
* Random seed; if present, this will be used in place of `std::random_device` for kmeans++
  initialization. This can be used to ensure reproducible/deterministic behavior.
*/
template <typename T>
class clustering_parameters {
public:
	explicit clustering_parameters(uint32_t k) :
	_k(k),
	_has_max_iter(false), _max_iter(),
	_has_min_delta(false), _min_delta(),
	_has_rand_seed(false), _rand_seed()
	{}

	void set_max_iteration(uint64_t max_iter)
	{
		_max_iter = max_iter;
		_has_max_iter = true;
	}

	void set_min_delta(T min_delta)
	{
		_min_delta = min_delta;
		_has_min_delta = true;
	}

	void set_random_seed(uint64_t rand_seed)
	{
		_rand_seed = rand_seed;
		_has_rand_seed = true;
	}

	bool has_max_iteration() const { return _has_max_iter; }
	bool has_min_delta() const { return _has_min_delta; }
	bool has_random_seed() const { return _has_rand_seed; }

	uint32_t get_k() const { return _k; };
	uint64_t get_max_iteration() const { return _max_iter; }
	T get_min_delta() const { return _min_delta; }
	uint64_t get_random_seed() const { return _has_rand_seed; }

private:
	uint32_t _k;
	bool _has_max_iter;
	uint64_t _max_iter;
	bool _has_min_delta;
	T _min_delta;
	bool _has_rand_seed;
	uint64_t _rand_seed;
};

/*
Implementation of k-means generic across the data type and the dimension of each data item. Expects
the data to be a vector of fixed-size arrays. Generic parameters are the type of the base data (T)
and the dimensionality of each data point (N). All points must have the same dimensionality.

e.g. points of the form (X, Y, Z) would be N = 3.

Takes a `clustering_parameters` struct for algorithm configuration. See the comments for the
`clustering_parameters` struct for more information about the configuration values and how they
affect the algorithm.

Returns a std::tuple containing:
  0: A vector holding the means for each cluster from 0 to k-1.
  1: A vector containing the cluster number (0 to k-1) for each corresponding element of the input
	 data vector.

Implementation details:
This implementation of k-means uses [Lloyd's Algorithm](https://en.wikipedia.org/wiki/Lloyd%27s_algorithm)
with the [kmeans++](https://en.wikipedia.org/wiki/K-means%2B%2B)
used for initializing the means.

TODO: Need to implement clustering_parameters support in parallel implementation.
*/
template <typename T, size_t N>
std::tuple<std::vector<std::array<T, N>>, std::vector<uint32_t>> kmeans_lloyd(
	const std::vector<std::array<T, N>>& data, const clustering_parameters<T>& parameters) {
	static_assert(std::is_arithmetic<T>::value && std::is_signed<T>::value,
		"kmeans_lloyd requires the template parameter T to be a signed arithmetic type (e.g. float, double, int)");
	assert(parameters.get_k() > 0); // k must be greater than zero
	assert(data.size() >= parameters.get_k()); // there must be at least k data points
	std::vector<std::array<T, N>> means = details::random_plusplus(data, parameters.get_k());

	std::vector<std::array<T, N>> old_means;
	std::vector<std::array<T, N>> old_old_means;
	std::vector<uint32_t> clusters;
	// Calculate new means until convergence is reached or we hit the maximum iteration count
	uint64_t count = 0;
	do {
		clusters = details::calculate_clusters(data, means);
		old_old_means = old_means;
		old_means = means;
		means = details::calculate_means(data, clusters, old_means, parameters.get_k());
		++count;
	} while ((means != old_means && means != old_old_means)
		|| (parameters.has_max_iteration() && count == parameters.get_max_iteration())
		|| (parameters.has_min_delta() && !details::deltas_below_limit(details::deltas(old_means, means), parameters.get_min_delta())));

	return std::tuple<std::vector<std::array<T, N>>, std::vector<uint32_t>>(means, clusters);
}

/*
This overload exists to support legacy code which uses this signature of the kmeans_lloyd function.
Any code still using this signature should move to the version of this function that uses a
`clustering_parameters` struct for configuration.
*/
template <typename T, size_t N>
std::tuple<std::vector<std::array<T, N>>, std::vector<uint32_t>> kmeans_lloyd(
	const std::vector<std::array<T, N>>& data, uint32_t k,
	uint64_t max_iter = 0, T min_delta = -1.0) {
	clustering_parameters<T> parameters(k);
	if (max_iter != 0) {
		parameters.set_max_iteration(max_iter);
	}
	if (min_delta != 0) {
		parameters.set_min_delta(min_delta);
	}
	kmeans_lloyd(data, parameters);
}

} // namespace dkm

#endif /* DKM_KMEANS_H */
<|endoftext|>


<commit_before>#include <algorithm>

#include "caffe2/core/logging.h"
#include <gtest/gtest.h>

namespace caffe2 {

TEST(LoggingTest, TestEnforceTrue) {
  // This should just work.
  CAFFE_ENFORCE(true, "Isn't it?");
}

TEST(LoggingTest, TestEnforceFalse) {
  bool kFalse = false;
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kFalse);
  try {
    CAFFE_ENFORCE(false, "This throws.");
    // This should never be triggered.
    EXPECT_FALSE(true);
  } catch (const EnforceNotMet& err) {
  }
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kFalse);
}

TEST(LoggingTest, TestEnforceEquals) {
  int x = 4;
  int y = 5;
  try {
    CAFFE_ENFORCE_THAT(Equals(++x, ++y));
    // This should never be triggered.
    EXPECT_FALSE(true);
  } catch (const EnforceNotMet& err) {
    EXPECT_NE(err.msg().find("5 vs 6"), string::npos);
  }

  // arguments are expanded only once
  CAFFE_ENFORCE_THAT(Equals(++x, y));
  EXPECT_EQ(x, 6);
  EXPECT_EQ(y, 6);
}

TEST(LoggingTest, EnforceShowcase) {
  // It's not really a test but rather a convenient thing that you can run and
  // see all messages
  int one = 1;
  int two = 2;
  int three = 3;
#define WRAP_AND_PRINT(exp)                     \
  try {                                         \
    exp;                                        \
  } catch (const EnforceNotMet& err) {          \
    /* EnforceNotMet already does LOG(ERROR) */ \
  }
  WRAP_AND_PRINT(CAFFE_ENFORCE_EQ(one, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_NE(one * 2, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_GT(one, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_GE(one, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_LT(three, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_LE(three, two));

  WRAP_AND_PRINT(CAFFE_ENFORCE_EQ(
      one * two + three, three * two, "It's a pretty complicated expression"));

  WRAP_AND_PRINT(CAFFE_ENFORCE_THAT(Equals(one * two + three, three * two)));
}

TEST(LoggingTest, Join) {
  auto s = Join(", ", vector<int>({1, 2, 3}));
  EXPECT_EQ(s, "1, 2, 3");
  s = Join(":", vector<string>());
  EXPECT_EQ(s, "");
  s = Join(", ", set<int>({3, 1, 2}));
  EXPECT_EQ(s, "1, 2, 3");
}

#if GTEST_HAS_DEATH_TEST
TEST(LoggingDeathTest, TestEnforceUsingFatal) {
  bool kTrue = true;
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kTrue);
  EXPECT_DEATH(CAFFE_ENFORCE(false, "This goes fatal."), "");
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kTrue);
}
#endif

} // namespace caffe2
<commit_msg>CodeMod: Prefer ADD_FAILURE() over EXPECT_TRUE(false), et cetera<commit_after>#include <algorithm>

#include "caffe2/core/logging.h"
#include <gtest/gtest.h>

namespace caffe2 {

TEST(LoggingTest, TestEnforceTrue) {
  // This should just work.
  CAFFE_ENFORCE(true, "Isn't it?");
}

TEST(LoggingTest, TestEnforceFalse) {
  bool kFalse = false;
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kFalse);
  try {
    CAFFE_ENFORCE(false, "This throws.");
    // This should never be triggered.
    ADD_FAILURE();
  } catch (const EnforceNotMet& err) {
  }
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kFalse);
}

TEST(LoggingTest, TestEnforceEquals) {
  int x = 4;
  int y = 5;
  try {
    CAFFE_ENFORCE_THAT(Equals(++x, ++y));
    // This should never be triggered.
    ADD_FAILURE();
  } catch (const EnforceNotMet& err) {
    EXPECT_NE(err.msg().find("5 vs 6"), string::npos);
  }

  // arguments are expanded only once
  CAFFE_ENFORCE_THAT(Equals(++x, y));
  EXPECT_EQ(x, 6);
  EXPECT_EQ(y, 6);
}

TEST(LoggingTest, EnforceShowcase) {
  // It's not really a test but rather a convenient thing that you can run and
  // see all messages
  int one = 1;
  int two = 2;
  int three = 3;
#define WRAP_AND_PRINT(exp)                     \
  try {                                         \
    exp;                                        \
  } catch (const EnforceNotMet& err) {          \
    /* EnforceNotMet already does LOG(ERROR) */ \
  }
  WRAP_AND_PRINT(CAFFE_ENFORCE_EQ(one, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_NE(one * 2, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_GT(one, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_GE(one, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_LT(three, two));
  WRAP_AND_PRINT(CAFFE_ENFORCE_LE(three, two));

  WRAP_AND_PRINT(CAFFE_ENFORCE_EQ(
      one * two + three, three * two, "It's a pretty complicated expression"));

  WRAP_AND_PRINT(CAFFE_ENFORCE_THAT(Equals(one * two + three, three * two)));
}

TEST(LoggingTest, Join) {
  auto s = Join(", ", vector<int>({1, 2, 3}));
  EXPECT_EQ(s, "1, 2, 3");
  s = Join(":", vector<string>());
  EXPECT_EQ(s, "");
  s = Join(", ", set<int>({3, 1, 2}));
  EXPECT_EQ(s, "1, 2, 3");
}

#if GTEST_HAS_DEATH_TEST
TEST(LoggingDeathTest, TestEnforceUsingFatal) {
  bool kTrue = true;
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kTrue);
  EXPECT_DEATH(CAFFE_ENFORCE(false, "This goes fatal."), "");
  std::swap(FLAGS_caffe2_use_fatal_for_enforce, kTrue);
}
#endif

} // namespace caffe2
<|endoftext|>