/** Returns the highest frequency that can be probed by the data. This is 
 * defined as 1/2dt, where dt > 0 is the @b smallest time interval between 
 * any two observations.
 * 
 * @param[in] times	Times at which data were taken
 *
 * @return The highest meaningful frequency, in the inverse of whatever units 
 *	@p times is in.
 *
 * @pre @p times.size() ≥ 2
 * @pre @p times contains at least two unique values
 * @pre @p times is sorted in ascending order
 * 
 * @perform O(N) time, where N = @p times.size()
 * 
 * @exception std::invalid_argument Thrown if @p times has at most one element.
 * @exception kpftimes::except::BadLightCurve Thrown if @p times has 
 *	at most one distinct value.
 * @exception kpfutils::except::NotSorted Thrown if @p times is not in 
 *	ascending order.
 * 
 * @exceptsafe The function arguments are unchanged in the event 
 *	of an exception.
 * 
 * @test Regular grid, length 1. Expected behavior: throws invalid_argument
 * @test Regular grid, length 2. Expected behavior: returns PNF = 1/(2*step)
 * @test Regular grid, length 100. Expected behavior: returns PNF = 1/(2*step)
 * @todo How to test this for irregular grids?
 */
double maxFreq(const DoubleVec &times) {
	if (times.size() < 2) {
		throw std::invalid_argument("Parameter 'times' in maxFreq() contains fewer than 2 observations");
	}

	// Test for sort in O(N)
	// Faster than sorting, O(N log N), or unsorted test, O(N^2)
	if(!kpfutils::isSorted(times.begin(), times.end())) {
		throw kpfutils::except::NotSorted("Parameter 'times' in maxFreq() is unsorted");
	}

	// Look for the smallest interval
	DoubleVec::const_iterator t1 = times.begin();
	DoubleVec::const_iterator t2 = t1 + 1;
	double minDeltaT = 0.0;
	
	while(t2 != times.end()) {
		if (*t2 > *t1 && (*t2 - *t1 < minDeltaT || minDeltaT == 0.0)) {
			minDeltaT = *t2 - *t1;
		}
		t1++;
		t2++;
	}
	
	// Report the results
	if (minDeltaT == 0.0) {
		throw except::BadLightCurve("Parameter 'times' in maxFreq() contains only one unique value");
	} else {
		return 0.5 / minDeltaT;
	}
}
/** Returns the time interval covered by the data.
 * 
 * @param[in] times	Times at which data were taken
 *
 * @return The length of time between the earliest observation in times and 
 *	the latest observation in times, in whatever units @p times is in.
 *
 * @pre @p times.size() &ge; 2
 * @pre @p times contains at least two unique values
 * 
 * @perform O(N) time, where N = @p times.size()
 * 
 * @exception std::invalid_argument Thrown if @p times has at most one element.
 * @exception kpftimes::except::BadLightCurve Thrown if @p times has 
 *	at most one distinct value.
 * 
 * @exceptsafe The function arguments are unchanged in the event 
 *	of an exception.
 * 
 * @test Regular grid, length 1. Expected behavior: throws invalid_argument
 * @test Regular grid, length 2. Expected behavior: returns step
 * @test Regular grid, length 100. Expected behavior: returns 99*step
 * @test Irregular grid, 2 values randomly chosen from [0, 1). Expected behavior: returns max_element()-min_element()
 * @test Irregular grid, 100 values randomly chosen from [0, 1). Expected behavior: returns max_element()-min_element()
 */
double deltaT(const DoubleVec &times) {
	if (times.size() < 2) {
		throw std::invalid_argument("Parameter 'times' in deltaT() contains fewer than 2 observations");
	}
	
	// In C++11, this entire body can be replaced with a call to std::minmax_element()

	// Scanning the array to verify that it's sorted would take just as 
	//	long as scanning it for min and max
	double tMin = times.front();
	double tMax = tMin;
	
	for (DoubleVec::const_iterator i = times.begin(); i != times.end(); i++) {
		if (*i < tMin) {
			tMin = *i;
		}
		if (*i > tMax) {
			tMax = *i;
		}
	}
	
	if (tMax <= tMin) {
		throw except::BadLightCurve("Parameter 'times' in deltaT() contains only one unique value");
	}
	else {
		return (tMax - tMin);
	}
}
Exemple #3
0
double Stdev(const DoubleVec &val)
{
	double mean=0; 
	double sq=0;
	for(DoubleVec::const_iterator it=val.begin(); it< val.end(); it++)
	{
		mean+=*it;
		sq+=*it*(*it);
	}
	double std= sqrt((val.size()*sq-mean*mean)/((val.size()-1)*val.size()));
	mean/=val.size();
	sq/=val.size();
	return(std);
}
Exemple #4
0
void test_intersect()
{
	DoubleVec dv;
	IntVec iv;

	const struct {
		unsigned int pos;
		double val;
	} dTbl[] = {
		{ 5, 3.14 }, { 10, 2 }, { 12, 1.4 }, { 100, 2.3 }, { 1000, 4 },
	};

	const struct {
		unsigned int pos;
		int val;
	} iTbl[] = {
		{ 2, 4 }, { 5, 2 }, { 100, 4 }, { 101, 3}, { 999, 4 }, { 1000, 1 }, { 2000, 3 },
	};

	const struct {
		unsigned int pos;
		double d;
		int i;
	} interTbl[] = {
		 { 5, 3.14, 2 }, { 100, 2.3, 4 }, { 1000, 4, 1 }
	};

	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(dTbl); i++) {
		dv.push_back(dTbl[i].pos, dTbl[i].val);
	}
	for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(iTbl); i++) {
		iv.push_back(iTbl[i].pos, iTbl[i].val);
	}

	int j = 0;
	for (typename DoubleVec::const_iterator i = dv.begin(), ie = dv.end(); i != ie; ++i) {
		CYBOZU_TEST_EQUAL(i->pos(), dTbl[j].pos);
		CYBOZU_TEST_EQUAL(i->val(), dTbl[j].val);
		j++;
	}

	j = 0;
	for (typename IntVec::const_iterator i = iv.begin(), ie = iv.end(); i != ie; ++i) {
		CYBOZU_TEST_EQUAL(i->pos(), iTbl[j].pos);
		CYBOZU_TEST_EQUAL(i->val(), iTbl[j].val);
		j++;
	}

	int sum = 0;
	for (typename IntVec::const_iterator i = iv.begin(), ie = iv.end(); i != ie; ++i) {
		sum += i->val() * i->val();
	}
	CYBOZU_TEST_EQUAL(sum, 71);

	typedef cybozu::nlp::Intersection<DoubleVec, IntVec> InterSection;
	InterSection inter(dv, iv);

	j = 0;
	for (typename InterSection::const_iterator i = inter.begin(), ie = inter.end(); i != ie; ++i) {
		CYBOZU_TEST_EQUAL(i->pos(), interTbl[j].pos);
		CYBOZU_TEST_EQUAL(i->val1(), interTbl[j].d);
		CYBOZU_TEST_EQUAL(i->val2(), interTbl[j].i);
		j++;
	}
}