+The easy way to install is to search for cain in the Software Center
+application, and then install it. Use the instructions below if
+you are installing from the source distribution.
+
+
+
+Select Applications→Ubuntu Software Center and install the
+following packages.
+
+The easy way to install is to search for cain in the Software Center
+application, and then install it. Use the instructions below if
+you are installing from the source distribution.
+
+
+
+Select Applications→Ubuntu Software Center and install the
+following packages.
+
-Copyright (c) 1999-2011, California Institute of Technology
+Copyright (c) 1999 to the present, California Institute of Technology
diff -Nru cain-1.9/help/License.htm cain-1.10+dfsg/help/License.htm
--- cain-1.9/help/License.htm 2011-09-27 19:44:52.000000000 +0000
+++ cain-1.10+dfsg/help/License.htm 2012-07-02 04:07:25.000000000 +0000
@@ -7,7 +7,7 @@
-Copyright (c) 1999-2011, California Institute of Technology
+Copyright (c) 1999 to the present, California Institute of Technology
diff -Nru cain-1.9/help/Links.htd cain-1.10+dfsg/help/Links.htd
--- cain-1.9/help/Links.htd 2011-09-27 19:44:52.000000000 +0000
+++ cain-1.10+dfsg/help/Links.htd 2012-07-02 04:07:25.000000000 +0000
@@ -25,7 +25,11 @@
provides software and test models at his web site.
Dizzy
is a chemical kinetics stochastic simulation software package written in
diff -Nru cain-1.9/help/Welcome.htd cain-1.10+dfsg/help/Welcome.htd
--- cain-1.9/help/Welcome.htd 2011-09-27 19:44:54.000000000 +0000
+++ cain-1.10+dfsg/help/Welcome.htd 2012-07-02 04:07:28.000000000 +0000
@@ -9,7 +9,7 @@
Welcome
-This is version 1.9 of Cain, developed by Sean Mauch,
+This is version 1.10 of Cain, developed by Sean Mauch,
, at the
Center for Advanced Computing Research, at the
California Institute of Technology.
diff -Nru cain-1.9/help/Welcome.htm cain-1.10+dfsg/help/Welcome.htm
--- cain-1.9/help/Welcome.htm 2011-09-27 19:44:54.000000000 +0000
+++ cain-1.10+dfsg/help/Welcome.htm 2012-07-02 04:07:28.000000000 +0000
@@ -10,7 +10,7 @@
Welcome
-This is version 1.9 of Cain, developed by Sean Mauch,
+This is version 1.10 of Cain, developed by Sean Mauch,
, at the
Center for Advanced Computing Research, at the
California Institute of Technology.
diff -Nru cain-1.9/Makefile cain-1.10+dfsg/Makefile
--- cain-1.9/Makefile 2011-09-27 19:44:45.000000000 +0000
+++ cain-1.10+dfsg/Makefile 2012-07-02 04:07:13.000000000 +0000
@@ -17,6 +17,8 @@
rm -rf Cain.app/Contents/Resources/simulation
rm -rf Cain.app/Contents/Resources/solvers
rm -rf Cain.app/Contents/Resources/state
+ rm -f solvers/*
+ rm -f src/solvers/*.d
test:
nosetests --with-doctest -v simulation state
diff -Nru cain-1.9/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeap.h cain-1.10+dfsg/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeap.h
--- cain-1.9/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeap.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeap.h 2012-07-02 04:07:29.000000000 +0000
@@ -12,6 +12,8 @@
#include
+#include
+
namespace ads {
//! Indexed priority queue that partitions the active and inactive elements.
diff -Nru cain-1.9/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeapPair.h cain-1.10+dfsg/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeapPair.h
--- cain-1.9/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeapPair.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/ads/indexedPriorityQueue/IndexedPriorityQueueBinaryHeapPair.h 2012-07-02 04:07:29.000000000 +0000
@@ -10,6 +10,8 @@
#include "IndexedPriorityQueueBase.h"
+#include
+
namespace ads {
//! Indexed priority queue that partitions the active and inactive elements.
diff -Nru cain-1.9/src/ads/timer/Timer.h cain-1.10+dfsg/src/ads/timer/Timer.h
--- cain-1.9/src/ads/timer/Timer.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/ads/timer/Timer.h 2012-07-02 04:07:30.000000000 +0000
@@ -35,10 +35,10 @@
\code
Timer timer;
for (std::size_t i = 0; i != 100; ++i) {
- timer.start();
- // Code to time.
- ...
- timer.stop();
+ timer.start();
+ // Code to time.
+ ...
+ timer.stop();
}
std::cout << "Elapsed time = " << timer << " seconds.\n";
@@ -64,6 +64,9 @@
uint64_t _start;
uint64_t _elapsed;
mach_timebase_info_data_t _timeBaseInfo;
+#elif defined __linux__
+ timespec _start;
+ timespec _elapsed;
#else
clock_t _start;
clock_t _elapsed;
diff -Nru cain-1.9/src/ads/timer/Timer.ipp cain-1.10+dfsg/src/ads/timer/Timer.ipp
--- cain-1.9/src/ads/timer/Timer.ipp 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/ads/timer/Timer.ipp 2012-07-02 04:07:30.000000000 +0000
@@ -52,6 +52,80 @@
return 1e-9 *(_elapsed * _timeBaseInfo.numer / _timeBaseInfo.denom);
}
+#elif defined __linux__
+// stolen from
+// http://www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/
+timespec diff(timespec start, timespec end) {
+ //printf("diff called on \nend = (%3ld, %10ld)\nstart = (%3ld, %10ld)\n",
+ //end.tv_sec, end.tv_nsec, start.tv_sec, start.tv_nsec);
+ timespec temp;
+ if ((end.tv_nsec-start.tv_nsec)<0) {
+ temp.tv_sec = end.tv_sec-start.tv_sec-1;
+ temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
+ }
+ else {
+ temp.tv_sec = end.tv_sec-start.tv_sec;
+ temp.tv_nsec = end.tv_nsec-start.tv_nsec;
+ }
+ return temp;
+}
+
+inline
+Timer::
+Timer() :
+ // Initialize with an invalid start time.
+ _start(),
+ _elapsed() {
+ _start.tv_sec = std::numeric_limits::max();
+ _start.tv_nsec = std::numeric_limits::max();
+ _elapsed.tv_sec = 0;
+ _elapsed.tv_nsec = 0;
+}
+
+inline
+void
+Timer::
+start() {
+ clock_gettime(CLOCK_REALTIME, &_start);
+}
+
+inline
+void
+Timer::
+stop() {
+#ifdef DEBUG_stlib
+ // Check that the clock was started.
+ assert(_start.tv_sec != std::numeric_limits::max() &&
+ _start.tv_nsec != std::numeric_limits::max());
+#endif
+ timespec temp;
+ clock_gettime(CLOCK_REALTIME, &temp);
+ temp = diff(_start, temp);
+ _elapsed.tv_sec += temp.tv_sec;
+ _elapsed.tv_nsec += temp.tv_nsec;
+ if (_elapsed.tv_nsec > 1000000000) {
+ _elapsed.tv_sec++;
+ _elapsed.tv_nsec -= 1000000000;
+ }
+}
+
+inline
+void
+Timer::
+reset() {
+ _start.tv_sec = std::numeric_limits::max();
+ _start.tv_nsec = std::numeric_limits::max();
+ _elapsed.tv_sec = 0;
+ _elapsed.tv_nsec = 0;
+}
+
+inline
+Timer::
+operator double() const {
+ return double(_elapsed.tv_sec + _elapsed.tv_nsec / 1e9);
+}
+
+
#else
//----------------------------------------------------------------------------
diff -Nru cain-1.9/src/ads/utility/ParseOptionsArguments.h cain-1.10+dfsg/src/ads/utility/ParseOptionsArguments.h
--- cain-1.9/src/ads/utility/ParseOptionsArguments.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/ads/utility/ParseOptionsArguments.h 2012-07-02 04:07:30.000000000 +0000
@@ -223,7 +223,7 @@
/*!
\pre The number of remaining arguments must not be zero.
- The object of type T must be able to read its' state from a stream
+ The object of type T must be able to read its state from a stream
with \c operator>>().
\return true if the argument could be read.
diff -Nru cain-1.9/src/array/all.h cain-1.10+dfsg/src/array/all.h
--- cain-1.9/src/array/all.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/array/all.h 2012-07-02 04:07:30.000000000 +0000
@@ -6,6 +6,7 @@
#include "Array.h"
#include "EquilateralArray.h"
#include "MultiArray.h"
+#include "PackedArrayOfArrays.h"
#include "SparseVector.h"
#include "StaticArrayOfArrays.h"
#include "SymmetricArray2D.h"
@@ -94,6 +95,8 @@
- array::SparseVector is a sparse 1-D vector. It stores index/value pairs.
- array::StaticArrayOfArrays is a static %array of arrays (no, really).
It is an efficient way to represent static, sparse, 2-D arrays.
+- array::PackedArrayOfArrays is like array::StaticArrayOfArrays,
+but supports building on the fly by manipulating the last array.
- array::TriangularArray is a 2-D triangular %array.
- array::SymmetricArray2D is a symmetric 2-D %array with or without the
diagonal elements.
diff -Nru cain-1.9/src/array/EquilateralArrayImp.h cain-1.10+dfsg/src/array/EquilateralArrayImp.h
--- cain-1.9/src/array/EquilateralArrayImp.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/array/EquilateralArrayImp.h 2012-07-02 04:07:30.000000000 +0000
@@ -100,7 +100,7 @@
typename Base::const_reference
operator()(const typename Base::size_type i0) const {
LOKI_STATIC_CHECK(_D == 1, BadDimension);
- return operator[](i0);
+ return Base::operator[](i0);
}
//! Return a const reference to the specified element in the 1-D array.
@@ -115,7 +115,7 @@
operator()(const typename Base::size_type i0,
const typename Base::size_type i1) const {
LOKI_STATIC_CHECK(_D == 2, BadDimension);
- return operator[](i0 + i1 * _N);
+ return Base::operator[](i0 + i1 * _N);
}
//! Return a const reference to the specified element in the 2-D array.
@@ -132,7 +132,7 @@
const typename Base::size_type i2)
const {
LOKI_STATIC_CHECK(_D == 3, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N);
}
//! Return a const reference to the specified element in the 3-D array.
@@ -149,7 +149,7 @@
const typename Base::size_type i2,
const typename Base::size_type i3) const {
LOKI_STATIC_CHECK(_D == 4, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N);
}
//! Return a const reference to the specified element in the 4-D array.
@@ -167,8 +167,8 @@
const typename Base::size_type i3,
const typename Base::size_type i4) const {
LOKI_STATIC_CHECK(_D == 5, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N);
}
//! Return a const reference to the specified element in the 5-D array.
@@ -187,8 +187,8 @@
const typename Base::size_type i4,
const typename Base::size_type i5) const {
LOKI_STATIC_CHECK(_D == 6, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N);
}
//! Return a const reference to the specified element in the 6-D array.
@@ -208,9 +208,9 @@
const typename Base::size_type i5,
const typename Base::size_type i6) const {
LOKI_STATIC_CHECK(_D == 7, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N);
}
//! Return a const reference to the specified element in the 7-D array.
@@ -231,10 +231,10 @@
const typename Base::size_type i6,
const typename Base::size_type i7) const {
LOKI_STATIC_CHECK(_D == 8, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N +
- i7 * _N * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N +
+ i7 * _N * _N * _N * _N * _N * _N * _N);
}
//! Return a const reference to the specified element in the 8-D array.
@@ -256,11 +256,11 @@
const typename Base::size_type i7,
const typename Base::size_type i8) const {
LOKI_STATIC_CHECK(_D == 9, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N +
- i7 * _N * _N * _N * _N * _N * _N * _N +
- i8 * _N * _N * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N +
+ i7 * _N * _N * _N * _N * _N * _N * _N +
+ i8 * _N * _N * _N * _N * _N * _N * _N * _N);
}
//! Return a const reference to the specified element in the 9-D array.
@@ -283,12 +283,12 @@
const typename Base::size_type i8,
const typename Base::size_type i9) const {
LOKI_STATIC_CHECK(_D == 10, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N +
- i7 * _N * _N * _N * _N * _N * _N * _N +
- i8 * _N * _N * _N * _N * _N * _N * _N * _N +
- i9 * _N * _N * _N * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N +
+ i7 * _N * _N * _N * _N * _N * _N * _N +
+ i8 * _N * _N * _N * _N * _N * _N * _N * _N +
+ i9 * _N * _N * _N * _N * _N * _N * _N * _N * _N);
}
//! Return a const reference to the specified element in the 10-D array.
@@ -323,7 +323,7 @@
typename Base::reference
operator()(const typename Base::size_type i0) {
LOKI_STATIC_CHECK(_D == 1, BadDimension);
- return operator[](i0);
+ return Base::operator[](i0);
}
//! Return a reference to the specified element in the 1-D array.
@@ -338,7 +338,7 @@
operator()(const typename Base::size_type i0,
const typename Base::size_type i1) {
LOKI_STATIC_CHECK(_D == 2, BadDimension);
- return operator[](i0 + i1 * _N);
+ return Base::operator[](i0 + i1 * _N);
}
//! Return a reference to the specified element in the 2-D array.
@@ -354,7 +354,7 @@
const typename Base::size_type i1,
const typename Base::size_type i2) {
LOKI_STATIC_CHECK(_D == 3, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N);
}
//! Return a reference to the specified element in the 3-D array.
@@ -371,7 +371,7 @@
const typename Base::size_type i2,
const typename Base::size_type i3) {
LOKI_STATIC_CHECK(_D == 4, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N);
}
//! Return a reference to the specified element in the 4-D array.
@@ -389,8 +389,8 @@
const typename Base::size_type i3,
const typename Base::size_type i4) {
LOKI_STATIC_CHECK(_D == 5, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N);
}
//! Return a reference to the specified element in the 5-D array.
@@ -409,8 +409,8 @@
const typename Base::size_type i4,
const typename Base::size_type i5) {
LOKI_STATIC_CHECK(_D == 6, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N);
}
//! Return a reference to the specified element in the 6-D array.
@@ -430,9 +430,9 @@
const typename Base::size_type i5,
const typename Base::size_type i6) {
LOKI_STATIC_CHECK(_D == 7, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N);
}
//! Return a reference to the specified element in the 7-D array.
@@ -453,10 +453,10 @@
const typename Base::size_type i6,
const typename Base::size_type i7) {
LOKI_STATIC_CHECK(_D == 8, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N +
- i7 * _N * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N +
+ i7 * _N * _N * _N * _N * _N * _N * _N);
}
//! Return a reference to the specified element in the 8-D array.
@@ -478,11 +478,11 @@
const typename Base::size_type i7,
const typename Base::size_type i8) {
LOKI_STATIC_CHECK(_D == 9, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N +
- i7 * _N * _N * _N * _N * _N * _N * _N +
- i8 * _N * _N * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N +
+ i7 * _N * _N * _N * _N * _N * _N * _N +
+ i8 * _N * _N * _N * _N * _N * _N * _N * _N);
}
//! Return a reference to the specified element in the 9-D array.
@@ -505,12 +505,12 @@
const typename Base::size_type i8,
const typename Base::size_type i9) {
LOKI_STATIC_CHECK(_D == 10, BadDimension);
- return operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
- i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
- i6 * _N * _N * _N * _N * _N * _N +
- i7 * _N * _N * _N * _N * _N * _N * _N +
- i8 * _N * _N * _N * _N * _N * _N * _N * _N +
- i9 * _N * _N * _N * _N * _N * _N * _N * _N * _N);
+ return Base::operator[](i0 + i1 * _N + i2 * _N * _N + i3 * _N * _N * _N +
+ i4 * _N * _N * _N * _N + i5 * _N * _N * _N * _N * _N +
+ i6 * _N * _N * _N * _N * _N * _N +
+ i7 * _N * _N * _N * _N * _N * _N * _N +
+ i8 * _N * _N * _N * _N * _N * _N * _N * _N +
+ i9 * _N * _N * _N * _N * _N * _N * _N * _N * _N);
}
//! Return a reference to the specified element in the 10-D array.
diff -Nru cain-1.9/src/array/EquilateralArrayRef.h cain-1.10+dfsg/src/array/EquilateralArrayRef.h
--- cain-1.9/src/array/EquilateralArrayRef.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/array/EquilateralArrayRef.h 2012-07-02 04:07:30.000000000 +0000
@@ -45,7 +45,7 @@
//! Construct from a pointer to the array data.
EquilateralArrayRef(typename Base::iterator data) :
Base() {
- setData(data);
+ Base::setData(data);
}
// @}
diff -Nru cain-1.9/src/array/PackedArrayOfArrays.h cain-1.10+dfsg/src/array/PackedArrayOfArrays.h
--- cain-1.9/src/array/PackedArrayOfArrays.h 1970-01-01 00:00:00.000000000 +0000
+++ cain-1.10+dfsg/src/array/PackedArrayOfArrays.h 2012-07-02 04:07:30.000000000 +0000
@@ -0,0 +1,465 @@
+// -*- C++ -*-
+
+/*!
+ \file PackedArrayOfArrays.h
+ \brief A class for a packed %array of arrays.
+*/
+
+#if !defined(__array_PackedArrayOfArrays_h__)
+#define __array_PackedArrayOfArrays_h__
+
+#include "../ext/vector.h"
+
+namespace array {
+
+//! A packed %array of arrays.
+/*!
+ \param _T is the value type.
+
+ This is an array of arrays that have varying sizes. One may think of it as
+ as two dimensional array where the rows have varying numbers of columns.
+ This data structure is useful where one might think of using a container
+ of containers like \c std::vector >.
+
+ This class packs all of the elements of all of the arrays into a
+ contigous storage. This gives it better cache utilization than a
+ container of containers. The downside is that it has limited ability
+ to modify the sizes of the component arrays. You can only manipulate
+ the last array. We will talk more about that later.
+ In addition to packed elements, this class stores a vector of array
+ delimiters that define the begining and end of each array.
+
+ There are a number of ways to construct this class. The default
+ constructor makes an empty data structure. There are no arrays and
+ no elements. Below we construct the class and verify this.
+ \code
+ array::PackedArrayOfArrays x;
+ assert(x.numArrays() == 0);
+ assert(x.empty());
+ \endcode
+ You can also construct it from a container of containers. You may use
+ any container that satisfies the STL interface for a sequence.
+ \code
+ std::vector > a;
+ ...
+ array::PackedArrayOfArrays x(a);
+ \endcode
+ \code
+ std::list > a;
+ ...
+ array::PackedArrayOfArrays x(a);
+ \endcode
+ If you know the sizes of the arrays but do not yet know the element values,
+ you can construct a PackedArrayOfArrays with the range of sizes.
+ \code
+ std::vector sizes;
+ ...
+ array::PackedArrayOfArrays x(sizes.begin(), sizes.end());
+ \endcode
+ You can also construct a PackedArrayOfArrays from a range of array sizes
+ and the range for the packed elements.
+ \code
+ std::vector sizes;
+ std::vector packedData;
+ ...
+ array::PackedArrayOfArrays x(sizes.begin(), sizes.end(),
+ packedData.begin(), packedData.end());
+ \endcode
+
+ This class inherits from std::vector to store the elements, and
+ it retains the accessors. Thus you can use \c operator[], \c size(),
+ \c empty(), \c begin(), \c end(), \c rbegin(), and \c rend() to work
+ with the packed array of elements. For example, below we compute the
+ sum of the elements in three different ways.
+ \code
+ array::PackedArrayOfArrays x;
+ ...
+ // Indexing.
+ double sum = 0;
+ for (std::size_t i = 0; i != x.size(); ++i) {
+ sum += x[i];
+ }
+ // Iterator.
+ sum = 0;
+ for (array::PackedArrayOfArrays::const_iterator i = x.begin();
+ i != x.end(); ++i) {
+ sum += *i;
+ }
+ // Accumulate.
+ sum = std::accumulate(x.begin(), x.end(), 0.)
+ \endcode
+
+ Of course, you can also work with the component arrays. There are
+ versions of \c size(), \c empty(), \c begin(), \c end(), \c rbegin(),
+ and \c rend() that take the component array index as an argument and
+ return information about that array.
+ \code
+ array::PackedArrayOfArrays x;
+ ...
+ // Make a vector of the array sizes.
+ std::vector sizes(x.numArrays());
+ for (std::size_t i = 0; i != x.numArrays(); ++i) {
+ sizes[i] = x.size(i);
+ }
+ // Calculate the sum of each array.
+ std::vector sums(x.numArrays());
+ for (std::size_t i = 0; i != x.numArrays(); ++i) {
+ sums[i] = std::accumulate(x.begin(i), x.end(i), 0.);
+ }
+ \endcode
+
+ \c operator() with a single argument will give you the beginning of
+ the specified array. This \c x(i) is equivalent to \c x.begin(i).
+ With two arguments it gives you the specified element of the
+ specified array. That is, \c x(m,n) is the nth element of the mth array.
+
+ Note that in inheriting from std::vector, the modifier functions
+ \c assign(), \c insert(), and \c erase() have been disabled.
+ This is because (for the sake of efficiency) PackedArrayOfArrays
+ only supports changing the size of the last array.
+ Use \c push_back() and pop_back() to append an element to the last array
+ and remove the last element from the last array, respectively.
+ \c pushArray() appends an empty array, while \c popArray()
+ erases the last array (which need not be empty).
+*/
+template
+class PackedArrayOfArrays :
+ public std::vector<_T> {
+ //
+ // Types.
+ //
+private:
+
+ typedef std::vector<_T> Base;
+
+ //
+ // Data.
+ //
+private:
+
+ //! Delimiters that determine the beginning and end of each %array.
+ std::vector _delimiters;
+
+ //
+ // Disable the following functions from the base class:
+ // assign(), insert(), and erase().
+ //
+private:
+ template
+ void
+ assign(_InputIterator first, _InputIterator last);
+
+ void
+ assign(typename Base::size_type n, typename Base::const_reference x);
+
+ typename Base::iterator
+ insert(typename Base::iterator position, typename Base::const_reference x);
+
+ void
+ insert(typename Base::iterator position, typename Base::size_type n,
+ typename Base::const_reference x);
+
+ template
+ void
+ insert(typename Base::iterator position, _InputIterator first,
+ _InputIterator last);
+
+ typename Base::iterator
+ erase(typename Base::iterator position);
+
+ typename Base::iterator
+ erase(typename Base::iterator first, typename Base::iterator last);
+
+ //
+ // Use from the base class.
+ //
+public:
+ using Base::size;
+ using Base::empty;
+ using Base::begin;
+ using Base::end;
+ using Base::rbegin;
+ using Base::rend;
+
+public:
+
+ //--------------------------------------------------------------------------
+ /*! \name Constructors etc.
+ Use the synthesized copy constructor, assignment operator, and destructor.
+ */
+ // @{
+
+ //! Default constructor. Empty data structure.
+ PackedArrayOfArrays() :
+ Base(),
+ _delimiters(1) {
+ _delimiters[0] = 0;
+ }
+
+ //! Construct from a container of containers.
+ template
+ PackedArrayOfArrays(const _Container& cOfC);
+
+ //! Construct from the %array sizes and the values.
+ template
+ PackedArrayOfArrays(SizeForwardIter sizesBeginning, SizeForwardIter sizesEnd,
+ ValueForwardIter valuesBeginning,
+ ValueForwardIter valuesEnd);
+
+ //! Rebuild from the component %array sizes.
+ template
+ void
+ rebuild(SizeForwardIter sizesBeginning, SizeForwardIter sizesEnd);
+
+ //! Rebuild from the %array sizes and the values.
+ template
+ void
+ rebuild(SizeForwardIter sizesBeginning, SizeForwardIter sizesEnd,
+ ValueForwardIter valuesBeginning, ValueForwardIter valuesEnd) {
+ rebuild(sizesBeginning, sizesEnd);
+ std::copy(valuesBeginning, valuesEnd, begin());
+ }
+
+ //! Swap with the argument.
+ void
+ swap(PackedArrayOfArrays& other) {
+ Base::swap(other);
+ _delimiters.swap(other._delimiters);
+ }
+
+ // @}
+ //--------------------------------------------------------------------------
+ //! \name Accessors for the whole set of elements.
+ // @{
+
+ //! Return the number of arrays.
+ typename Base::size_type
+ numArrays() const {
+ return _delimiters.size() - 1;
+ }
+
+ // @}
+ //--------------------------------------------------------------------------
+ //! \name Accessors for individual arrays.
+ // @{
+
+ //! Return the number of elements in the nth %array.
+ typename Base::size_type
+ size(const typename Base::size_type n) const {
+ return _delimiters[n + 1] - _delimiters[n];
+ }
+
+ //! Return true if the nth %array is empty.
+ bool
+ empty(const typename Base::size_type n) const {
+ return size(n) == 0;
+ }
+
+ //! Return a const iterator to the first value in the nth %array.
+ typename Base::const_iterator
+ begin(const typename Base::size_type n) const {
+ return Base::begin() + _delimiters[n];
+ }
+
+ //! Return a const iterator to one past the last value in the nth %array.
+ typename Base::const_iterator
+ end(const typename Base::size_type n) const {
+ return Base::begin() + _delimiters[n + 1];
+ }
+
+ //! Return a const reverse iterator to the last value in the nth %array.
+ typename Base::const_reverse_iterator
+ rbegin(const typename Base::size_type n) const {
+ return typename Base::const_reverse_iterator(end(n));
+ }
+
+ //! Return a const reverse iterator to one before the first value in the nth %array.
+ typename Base::const_reverse_iterator
+ rend(const typename Base::size_type n) const {
+ return typename Base::const_reverse_iterator(begin(n));
+ }
+
+ //! Return a const iterator to the first element of the nth %array.
+ typename Base::const_iterator
+ operator()(const typename Base::size_type n) const {
+ return begin(n);
+ }
+
+ //! Return the mth element of the nth %array.
+ typename Base::const_reference
+ operator()(const std::size_t n, const std::size_t m) const {
+#ifdef DEBUG_stlib
+ assert(m < size(n));
+#endif
+ return Base::operator[](_delimiters[n] + m);
+ }
+
+ // @}
+ //--------------------------------------------------------------------------
+ //! \name Manipulators for the whole set of elements.
+ // @{
+
+ //! Clear the %array of arrays.
+ void
+ clear() {
+ Base::clear();
+ _delimiters.resize(1);
+ _delimiters[0] = 0;
+ }
+
+ // @}
+ //--------------------------------------------------------------------------
+ //! \name Manipulators for individual arrays.
+ // @{
+
+ //! Return an iterator to the first value in the nth %array.
+ typename Base::iterator
+ begin(const typename Base::size_type n) {
+ return Base::begin() + _delimiters[n];
+ }
+
+ //! Return an iterator to one past the last value in the nth %array.
+ typename Base::iterator
+ end(const typename Base::size_type n) {
+ return Base::begin() + _delimiters[n + 1];
+ }
+
+ //! Return an iterator to the first element of the nth %array.
+ typename Base::iterator
+ operator()(const typename Base::size_type n) {
+ return begin(n);
+ }
+
+ //! Return the mth element of the nth %array.
+ typename Base::reference
+ operator()(const typename Base::size_type n, const typename Base::size_type m) {
+#ifdef DEBUG_stlib
+ assert(m < size(n));
+#endif
+ return Base::operator[](_delimiters[n] + m);
+ }
+
+ //! Append an empty array.
+ void
+ pushArray() {
+ _delimiters.push_back(_delimiters.back());
+ }
+
+ //! Append an array with elements defined by the sequence.
+ template
+ void
+ pushArray(_InputIterator begin, _InputIterator end) {
+ pushArray();
+ while (begin != end) {
+ push_back(*begin++);
+ }
+ }
+
+ //! Pop the last array.
+ void
+ popArray() {
+ Base::erase(begin(numArrays() - 1), end(numArrays() - 1));
+ _delimiters.pop_back();
+ }
+
+ //! Append an element to the last array.
+ void
+ push_back(typename Base::const_reference x) {
+ Base::push_back(x);
+ ++_delimiters.back();
+ }
+
+ //! Pop an element from the last array.
+ void
+ pop_back() {
+ Base::pop_back();
+ --_delimiters.back();
+ }
+
+ // @}
+ //--------------------------------------------------------------------------
+ //! \name Equality.
+ // @{
+
+ //! Return true if the arrays are equal.
+ bool
+ operator==(const PackedArrayOfArrays& x) const {
+ return static_cast(*this) == static_cast(x) &&
+ _delimiters == x._delimiters;
+ }
+
+ //! Return true if the arrays are not equal.
+ bool
+ operator!=(const PackedArrayOfArrays& x) const {
+ return ! operator==(x);
+ }
+
+ // @}
+ //--------------------------------------------------------------------------
+ //! \name File I/O.
+ // @{
+
+ //! Write to a file stream in ascii format.
+ void
+ put(std::ostream& out) const;
+
+ //! Read from a file stream in ascii format.
+ void
+ get(std::istream& in);
+
+ // @}
+};
+
+//
+// File I/O.
+//
+
+//! Write a PackedArrayOfArrays in ascii format.
+/*!
+ \relates PackedArrayOfArrays
+
+ Below is the file format.
+ \verbatim
+ number_of_arrays number_of_elements
+ array_0_size
+ array_0_value_0 array_0_value_1 ...
+ array_1_size
+ array_1_value_0 array_1_value_1 ...
+ ... \endverbatim
+*/
+template
+inline
+std::ostream&
+operator<<(std::ostream& out, const PackedArrayOfArrays<_T>& x) {
+ x.put(out);
+ return out;
+}
+
+//! Read a PackedArrayOfArrays in ascii format.
+/*!
+ \relates PackedArrayOfArrays
+
+ Below is the file format.
+ \verbatim
+ number_of_arrays number_of_elements
+ array_0_size
+ array_0_value_0 array_0_value_1 ...
+ array_1_size
+ array_1_value_0 array_1_value_1 ...
+ ... \endverbatim
+*/
+template
+inline
+std::istream&
+operator>>(std::istream& in, PackedArrayOfArrays<_T>& x) {
+ x.get(in);
+ return in;
+}
+
+} // namespace array
+
+#define __array_PackedArrayOfArrays_ipp__
+#include "PackedArrayOfArrays.ipp"
+#undef __array_PackedArrayOfArrays_ipp__
+
+#endif
diff -Nru cain-1.9/src/array/PackedArrayOfArrays.ipp cain-1.10+dfsg/src/array/PackedArrayOfArrays.ipp
--- cain-1.9/src/array/PackedArrayOfArrays.ipp 1970-01-01 00:00:00.000000000 +0000
+++ cain-1.10+dfsg/src/array/PackedArrayOfArrays.ipp 2012-07-02 04:07:30.000000000 +0000
@@ -0,0 +1,91 @@
+// -*- C++ -*-
+
+#if !defined(__array_PackedArrayOfArrays_ipp__)
+#error This file is an implementation detail of the class PackedArrayOfArrays.
+#endif
+
+namespace array {
+
+
+// Construct from a container of containers.
+template
+template
+inline
+PackedArrayOfArrays<_T>::
+PackedArrayOfArrays(const _Container& cOfC) :
+ Base(),
+ _delimiters(1) {
+ _delimiters[0] = 0;
+ typedef typename _Container::const_iterator ArrayIter;
+ typedef typename _Container::value_type::const_iterator ElementIter;
+ for (ArrayIter i = cOfC.begin(); i != cOfC.end(); ++i) {
+ pushArray();
+ for (ElementIter j = i->begin(); j != i->end(); ++j) {
+ push_back(*j);
+ }
+ }
+}
+
+
+template
+template
+inline
+PackedArrayOfArrays<_T>::
+PackedArrayOfArrays(SizeForwardIter sizesBeginning, SizeForwardIter sizesEnd,
+ ValueForwardIter valuesBeginning,
+ ValueForwardIter valuesEnd) :
+ Base(valuesBeginning, valuesEnd),
+ _delimiters(1) {
+ _delimiters[0] = 0;
+ std::partial_sum(sizesBeginning, sizesEnd, std::back_inserter(_delimiters));
+}
+
+
+template
+template
+inline
+void
+PackedArrayOfArrays<_T>::
+rebuild(SizeForwardIter sizesBeginning, SizeForwardIter sizesEnd) {
+ _delimiters.resize(1);
+ _delimiters[0] = 0;
+ std::partial_sum(sizesBeginning, sizesEnd, std::back_inserter(_delimiters));
+ Base::resize(_delimiters.back());
+}
+
+
+template
+inline
+void
+PackedArrayOfArrays<_T>::
+put(std::ostream& out) const {
+ out << numArrays() << " " << size() << '\n';
+ for (typename Base::size_type n = 0; n != numArrays(); ++n) {
+ out << size(n) << '\n';
+ std::copy(begin(n), end(n),
+ std::ostream_iterator(out, " "));
+ out << '\n';
+ }
+}
+
+template
+inline
+void
+PackedArrayOfArrays<_T>::
+get(std::istream& in) {
+ std::size_t numberOfArrays, numberOfElements, sz;
+ in >> numberOfArrays >> numberOfElements;
+ Base::resize(numberOfElements);
+ _delimiters.resize(numberOfArrays + 1);
+
+ _delimiters[0] = 0;
+ for (typename Base::size_type n = 0; n != numberOfArrays; ++n) {
+ in >> sz;
+ _delimiters[n + 1] = _delimiters[n] + sz;
+ for (typename Base::size_type m = 0; m != sz; ++m) {
+ in >> operator()(n, m);
+ }
+ }
+}
+
+} // namespace array
diff -Nru cain-1.9/src/array/SimpleMultiArray.ipp cain-1.10+dfsg/src/array/SimpleMultiArray.ipp
--- cain-1.9/src/array/SimpleMultiArray.ipp 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/array/SimpleMultiArray.ipp 2012-07-02 04:07:30.000000000 +0000
@@ -26,7 +26,7 @@
SimpleMultiArray(const SimpleMultiArrayConstRef<_T2, _Dimension>& other) :
Base(0, other.extents()) {
// Allocate the memory.
- setData(new typename Base::value_type[other.size()]);
+ Base::setData(new typename Base::value_type[other.size()]);
// Copy the elements.
std::copy(other.begin(), other.end(), Base::begin());
}
@@ -38,7 +38,7 @@
SimpleMultiArray(const SimpleMultiArray& other) :
Base(0, other.extents()) {
// Allocate the memory.
- setData(new typename Base::value_type[other.size()]);
+ Base::setData(new typename Base::value_type[other.size()]);
// Copy the elements.
std::copy(other.begin(), other.end(), Base::begin());
}
@@ -50,7 +50,7 @@
SimpleMultiArray(const typename Base::IndexList& extents) :
Base(0, extents) {
// Allocate the memory.
- setData(new typename Base::value_type[product(extents)]);
+ Base::setData(new typename Base::value_type[product(extents)]);
}
@@ -62,7 +62,7 @@
const typename Base::value_type& value) :
Base(0, extents) {
// Allocate the memory.
- setData(new typename Base::value_type[product(extents)]);
+ Base::setData(new typename Base::value_type[product(extents)]);
// Initialize the data.
std::fill(Base::begin(), Base::end(), value);
}
diff -Nru cain-1.9/src/array/SimpleMultiArrayRef.h cain-1.10+dfsg/src/array/SimpleMultiArrayRef.h
--- cain-1.9/src/array/SimpleMultiArrayRef.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/array/SimpleMultiArrayRef.h 2012-07-02 04:07:30.000000000 +0000
@@ -222,7 +222,7 @@
assert(indices[n] < Base::extents()[n]);
}
#endif
- return _data[arrayIndex(indices)];
+ return _data[Base::arrayIndex(indices)];
}
//! Array indexing.
@@ -232,7 +232,7 @@
#ifdef DEBUG_stlib
assert(i0 < Base::extents()[0]);
#endif
- return _data[arrayIndex(i0)];
+ return _data[Base::arrayIndex(i0)];
}
//! Array indexing.
@@ -242,7 +242,7 @@
#ifdef DEBUG_stlib
assert(i0 < Base::extents()[0] && i1 < Base::extents()[1]);
#endif
- return _data[arrayIndex(i0, i1)];
+ return _data[Base::arrayIndex(i0, i1)];
}
//! Array indexing.
@@ -254,7 +254,7 @@
assert(i0 < Base::extents()[0] && i1 < Base::extents()[1] &&
i2 < Base::extents()[2]);
#endif
- return _data[arrayIndex(i0, i1, i2)];
+ return _data[Base::arrayIndex(i0, i1, i2)];
}
//! Return a pointer to the beginning of the data.
diff -Nru cain-1.9/src/array/StaticArrayOfArrays.h cain-1.10+dfsg/src/array/StaticArrayOfArrays.h
--- cain-1.9/src/array/StaticArrayOfArrays.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/array/StaticArrayOfArrays.h 2012-07-02 04:07:30.000000000 +0000
@@ -324,7 +324,7 @@
//! Return true if the arrays are equal.
bool
- operator==(const StaticArrayOfArrays& x) const {
+ operator==(const StaticArrayOfArrays& x) const {
if (_elements != x._elements) {
return false;
}
@@ -338,7 +338,7 @@
//! Return true if the arrays are not equal.
bool
- operator!=(const StaticArrayOfArrays& x) const {
+ operator!=(const StaticArrayOfArrays& x) const {
return ! operator==(x);
}
diff -Nru cain-1.9/src/ext/array.h cain-1.10+dfsg/src/ext/array.h
--- cain-1.9/src/ext/array.h 2011-09-27 19:44:55.000000000 +0000
+++ cain-1.10+dfsg/src/ext/array.h 2012-07-02 04:07:30.000000000 +0000
@@ -3,13 +3,7 @@
#if !defined(__ext_array_h__)
#define __ext_array_h__
-#ifdef __CUDA_ARCH__
-#include "arrayCuda.h"
-#else
#include "arrayStd.h"
-#endif
-
-#include "../cuda/compatible.h"
namespace ext {
//-------------------------------------------------------------------------
@@ -43,7 +37,6 @@
//! Convert to an array with different value type.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_Target, _N>
convert_array(const std::tr1::array<_Source, _N>& x) {
std::tr1::array<_Target, _N> result;
@@ -56,7 +49,6 @@
//! Return an array filled with the specified value.
template
inline
-CUDA_COMPATIBLE
_Array
filled_array(const typename _Array::value_type& value) {
_Array x;
@@ -69,7 +61,6 @@
//! Copy from the input iterator to make an array.
template
inline
-CUDA_COMPATIBLE
_Array
copy_array(_InputIterator input) {
_Array x;
@@ -82,7 +73,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 1>
make_array(const _T& x0) {
std::tr1::array<_T, 1> x = {{x0}};
@@ -92,7 +82,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 2>
make_array(const _T& x0, const _T& x1) {
std::tr1::array<_T, 2> x = {{x0, x1}};
@@ -102,7 +91,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 3>
make_array(const _T& x0, const _T& x1, const _T& x2) {
std::tr1::array<_T, 3> x = {{x0, x1, x2}};
@@ -112,7 +100,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 4>
make_array(const _T& x0, const _T& x1, const _T& x2, const _T& x3) {
std::tr1::array<_T, 4> x = {{x0, x1, x2, x3}};
@@ -122,7 +109,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 5>
make_array(const _T& x0, const _T& x1, const _T& x2, const _T& x3,
const _T& x4) {
@@ -133,7 +119,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 6>
make_array(const _T& x0, const _T& x1, const _T& x2, const _T& x3,
const _T& x4, const _T& x5) {
@@ -144,7 +129,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 7>
make_array(const _T& x0, const _T& x1, const _T& x2, const _T& x3,
const _T& x4, const _T& x5, const _T& x6) {
@@ -155,7 +139,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 8>
make_array(const _T& x0, const _T& x1, const _T& x2, const _T& x3,
const _T& x4, const _T& x5, const _T& x6, const _T& x7) {
@@ -166,7 +149,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 9>
make_array(const _T& x0, const _T& x1, const _T& x2, const _T& x3,
const _T& x4, const _T& x5, const _T& x6, const _T& x7,
@@ -178,7 +160,6 @@
//! Return an array with the specified components.
template
inline
-CUDA_COMPATIBLE
std::tr1::array<_T, 10>
make_array(const _T& x0, const _T& x1, const _T& x2, const _T& x3,
const _T& x4, const _T& x5, const _T& x6, const _T& x7,
@@ -188,6 +169,50 @@
}
//@}
+//-------------------------------------------------------------------------
+/*! \defgroup extArraySimd SIMD Functions
+ I provide these functions because in some implementation std::tr1::array
+ is 16-byte aligned, while in others it is not. Note that these functions are
+ defined in the ext namespace so that they are not confused with the SSE
+ intrinsics.
+*/
+//@{
+
+#if 0
+//! Store for 3-D points.
+inline
+void
+_mm_store_ps(std::tr1::array* p, __m128 a) {
+ // CONTINUE: Implement specialization for 16-byte aligned structure.
+#if 0
+ // If the structure is aligned, we can use the aligned store.
+ ::_mm_store_ps(&(*p)[0], a);
+#endif
+ else {
+ // Otherwise, use the slower method. Note that we can't just use the
+ // unaligned store because it would write the fourth element.
+ (*p)[0] = reinterpret_cast(&a)[0];
+ (*p)[1] = reinterpret_cast(&a)[1];
+ (*p)[2] = reinterpret_cast(&a)[2];
+ }
+}
+
+//! Load for 3-D points.
+inline
+__m128
+_mm_load_ps(const std::tr1::array* p) {
+ if (sizeof(std::tr1::array) == 4 * sizeof(float)) {
+ // If the structure is aligned, we can use the aligned load.
+ return ::_mm_load_ps(&(*p)[0]);
+ }
+ else {
+ // Otherwise, use the slower set.
+ return _mm_set_ps(0, (*p)[2], (*p)[1], (*p)[0]);
+ }
+}
+#endif
+
+//@}
} // namespace ext
diff -Nru cain-1.9/src/ext/arrayStd.h cain-1.10+dfsg/src/ext/arrayStd.h
--- cain-1.9/src/ext/arrayStd.h 2011-09-27 19:44:56.000000000 +0000
+++ cain-1.10+dfsg/src/ext/arrayStd.h 2012-07-02 04:07:30.000000000 +0000
@@ -286,9 +286,9 @@
inline
array<_T, _N>
operator-(const array<_T, _N>& x) {
- array<_T, _N> y(x);
+ array<_T, _N> y;
for (size_t n = 0; n != _N; ++n) {
- y[n] = -y[n];
+ y[n] = -x[n];
}
return y;
}
@@ -353,8 +353,9 @@
template
struct ArithmeticResult {
//! An ordered list of numeric types.
- typedef LOKI_TYPELIST_10(double, float, unsigned long, long, unsigned, int,
- unsigned short, short, unsigned char, signed char)
+ typedef LOKI_TYPELIST_11(double, float, unsigned long, long, unsigned, int,
+ unsigned short, short, unsigned char, signed char,
+ bool)
OrderedTypes;
//! The result type.
typedef typename Loki::Select < int(Loki::TL::IndexOf::value)
@@ -1168,9 +1169,14 @@
inline
float
dot(const array& x, const array& y) {
+ // CONTINUE: Implementent specialization for 16-byte aligned structure.
+#if 0
// Note: Using load is OK because I don't access the fourth element,
// which might be NaN.
__m128 d = _mm_dp_ps(_mm_load_ps(&x[0]), _mm_load_ps(&y[0]), 0x71);
+#endif
+ __m128 d = _mm_dp_ps(_mm_set_ps(0, x[2], x[1], x[0]),
+ _mm_set_ps(0, y[2], y[1], y[0]), 0x71);
return *reinterpret_cast(&d);
}
#endif
@@ -1182,7 +1188,11 @@
inline
float
dot(const array& x, const array& y) {
+ // CONTINUE: Implementent specialization for 16-byte aligned structure.
+#if 0
__m128 d = _mm_dp_ps(_mm_load_ps(&x[0]), _mm_load_ps(&y[0]), 0xF1);
+#endif
+ __m128 d = _mm_dp_ps(_mm_loadu_ps(&x[0]), _mm_loadu_ps(&y[0]), 0xF1);
return *reinterpret_cast(&d);
}
#endif
@@ -1194,10 +1204,17 @@
inline
double
dot(const array& x, const array& y) {
+ // CONTINUE: Implementent specialization for 16-byte aligned structure.
+#if 0
__m128d a = _mm_add_sd(_mm_dp_pd(_mm_load_pd(&x[0]), _mm_load_pd(&y[0]),
0x31),
_mm_dp_pd(_mm_load_pd(&x[2]), _mm_load_pd(&y[2]),
0x31));
+#endif
+ __m128d a = _mm_add_sd(_mm_dp_pd(_mm_loadu_pd(&x[0]), _mm_loadu_pd(&y[0]),
+ 0x31),
+ _mm_dp_pd(_mm_loadu_pd(&x[2]), _mm_loadu_pd(&y[2]),
+ 0x31));
return *reinterpret_cast(&a);
}
#endif
@@ -1376,7 +1393,12 @@
float
squaredDistance(const array& x, const array& y) {
// Take the difference of the two vectors.
- __m128 d = _mm_sub_ps(_mm_load_ps(&x[0]), _mm_load_ps(&y[0]));
+ // CONTINUE: Implementent specialization for 16-byte aligned structure.
+#if 0
+ __m128 d = _mm_load_ps(&x[0]) - _mm_load_ps(&y[0]);
+#endif
+ __m128 d = _mm_set_ps(0, x[2], x[1], x[0]) -
+ _mm_set_ps(0, y[2], y[1], y[0]);
// Perform the dot product.
d = _mm_dp_ps(d, d, 0x71);
return *reinterpret_cast(&d);
@@ -1391,7 +1413,11 @@
float
squaredDistance(const array& x, const array& y) {
// Take the difference of the two vectors.
- __m128 d = _mm_sub_ps(_mm_load_ps(&x[0]), _mm_load_ps(&y[0]));
+ // CONTINUE: Implementent specialization for 16-byte aligned structure.
+#if 0
+ __m128 d = _mm_load_ps(&x[0]) - _mm_load_ps(&y[0]);
+#endif
+ __m128 d = _mm_loadu_ps(&x[0]) - _mm_loadu_ps(&y[0]);
// Perform the dot product.
d = _mm_dp_ps(d, d, 0xF1);
return *reinterpret_cast(&d);
@@ -1406,8 +1432,13 @@
double
squaredDistance(const array& x, const array& y) {
// Take the difference of the two vectors.
- __m128d a = _mm_sub_pd(_mm_load_pd(&x[0]), _mm_load_pd(&y[0]));
- __m128d b = _mm_sub_pd(_mm_load_pd(&x[2]), _mm_load_pd(&y[2]));
+ // CONTINUE: Implementent specialization for 16-byte aligned structure.
+#if 0
+ __m128d a = _mm_load_pd(&x[0]) - _mm_load_pd(&y[0]);
+ __m128d b = _mm_load_pd(&x[2]) - _mm_load_pd(&y[2]);
+#endif
+ __m128d a = _mm_loadu_pd(&x[0]) - _mm_loadu_pd(&y[0]);
+ __m128d b = _mm_loadu_pd(&x[2]) - _mm_loadu_pd(&y[2]);
// Perform the dot product.
a = _mm_add_pd(_mm_dp_pd(a, a, 0x31), _mm_dp_pd(b, b, 0x31));
return *reinterpret_cast(&a);
@@ -1446,7 +1477,11 @@
float
euclideanDistance(const array& x, const array& y) {
// Take the difference of the two vectors.
- __m128 d = _mm_sub_ps(_mm_load_ps(&x[0]), _mm_load_ps(&y[0]));
+ // CONTINUE: Implementent specialization for 16-byte aligned structure.
+#if 0
+ __m128 d = _mm_load_ps(&x[0]) - _mm_load_ps(&y[0]);
+#endif
+ __m128 d = _mm_loadu_ps(&x[0]) - _mm_loadu_ps(&y[0]);
// Perform the dot product and then take the square root.
d = _mm_sqrt_ss(_mm_dp_ps(d, d, 0xF1));
return *reinterpret_cast(&d);
diff -Nru cain-1.9/src/numerical/random/discrete/DiscreteGeneratorBinned.h cain-1.10+dfsg/src/numerical/random/discrete/DiscreteGeneratorBinned.h
--- cain-1.9/src/numerical/random/discrete/DiscreteGeneratorBinned.h 2011-09-27 19:44:56.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/discrete/DiscreteGeneratorBinned.h 2012-07-02 04:07:31.000000000 +0000
@@ -8,6 +8,8 @@
#if !defined(__numerical_DiscreteGeneratorBinned_h__)
#define __numerical_DiscreteGeneratorBinned_h__
+#include "DiscreteGeneratorBinsSplittingStacking.h"
+
#include "../uniform/Default.h"
#include "../../../ads/algorithm/sort.h"
diff -Nru cain-1.9/src/numerical/random/discrete/DiscreteGeneratorBinned.ipp cain-1.10+dfsg/src/numerical/random/discrete/DiscreteGeneratorBinned.ipp
--- cain-1.9/src/numerical/random/discrete/DiscreteGeneratorBinned.ipp 2011-09-27 19:44:56.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/discrete/DiscreteGeneratorBinned.ipp 2012-07-02 04:07:31.000000000 +0000
@@ -196,70 +196,6 @@
}
-
-
-// Count the number of required bins for the given maximum height.
-template
-inline
-std::size_t
-countBins(ForwardIterator begin, ForwardIterator end, const T height) {
- const T inverse = 1.0 / height;
- std::size_t count = 0;
- // Count the splitting bins.
- while (begin != end && *begin > height) {
- count += std::size_t(*begin * inverse) + 1;
- ++begin;
- }
- // Count the stacking bins.
- // The following loop is a little complicated because I must allow for the
- // possibility of blocks with zero height.
- T currentHeight = -1;
- while (begin != end) {
- // If we are starting a new bin.
- if (currentHeight == -1) {
- // Add the first block to the bin.
- currentHeight = *begin;
- // We are using a new bin.
- ++count;
- // Move to the next block.
- ++begin;
- }
- else {
- // Try adding a block to the current bin.
- currentHeight += *begin;
- // If we can fit it in the current bin.
- if (currentHeight <= height) {
- // Move to the next block.
- ++begin;
- }
- else {
- // Start a new bin.
- currentHeight = -1;
- }
- }
- }
- return count;
-}
-
-
-// Compute a bin height such that all the blocks will fit in the bins.
-template
-inline
-T
-computeBinHeight(ForwardIterator begin, ForwardIterator end,
- const std::size_t NumberOfBins) {
- const T content = std::accumulate(begin, end, T(0));
- T factor = 1;
- T height;
- do {
- factor += 0.1;
- height = factor * content / NumberOfBins;
- }
- while (countBins(begin, end, height) > NumberOfBins);
- return height;
-}
-
-
// Pack the block into bins.
template
inline
diff -Nru cain-1.9/src/numerical/random/discrete/DiscreteGeneratorCompositionRejectionStatic.h cain-1.10+dfsg/src/numerical/random/discrete/DiscreteGeneratorCompositionRejectionStatic.h
--- cain-1.9/src/numerical/random/discrete/DiscreteGeneratorCompositionRejectionStatic.h 2011-09-27 19:44:56.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/discrete/DiscreteGeneratorCompositionRejectionStatic.h 2012-07-02 04:07:31.000000000 +0000
@@ -216,6 +216,7 @@
DiscreteGeneratorCompositionRejectionStatic
(DiscreteUniformGenerator* generator,
ForwardIterator begin, ForwardIterator end) :
+ _discreteUniformGenerator(generator),
// Make a continuous uniform generator using the discrete uniform generator.
_continuousUniformGenerator(generator),
// Empty.
diff -Nru cain-1.9/src/numerical/random/discrete.h cain-1.10+dfsg/src/numerical/random/discrete.h
--- cain-1.9/src/numerical/random/discrete.h 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/discrete.h 2012-07-02 04:07:31.000000000 +0000
@@ -12,8 +12,6 @@
#include "discrete/DiscreteGeneratorBinned.h"
#include "discrete/DiscreteGeneratorBinsSplitting.h"
#include "discrete/DiscreteGeneratorBinsSplittingStacking.h"
-#include "discrete/DiscreteGeneratorCdfInversionUsingPartialPmfSums.h"
-#include "discrete/DiscreteGeneratorCdfInversionUsingPartialRecursiveCdf.h"
#include "discrete/DiscreteGeneratorLinearSearch.h"
#include "discrete/DiscreteGeneratorLinearSearchInteger.h"
#include "discrete/DiscreteGeneratorRejectionBinsSplitting.h"
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.h cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.h
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.h 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.h 2012-07-02 04:07:32.000000000 +0000
@@ -8,6 +8,8 @@
#if !defined(__numerical_PoissonGeneratorInversionBuildUp_h__)
#define __numerical_PoissonGeneratorInversionBuildUp_h__
+#include "PoissonGeneratorInversionMaximumMean.h"
+
#include "../uniform/ContinuousUniformGenerator.h"
#include
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.ipp cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.ipp
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.ipp 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUp.ipp 2012-07-02 04:07:32.000000000 +0000
@@ -4,10 +4,6 @@
#error This file is an implementation detail of PoissonGeneratorInversionBuildUp.
#endif
-#define __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-#include "PoissonGeneratorInversionMaximumMean.ipp"
-#undef __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-
namespace numerical {
template
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.h cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.h
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.h 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.h 2012-07-02 04:07:32.000000000 +0000
@@ -8,6 +8,8 @@
#if !defined(__numerical_PoissonGeneratorInversionBuildUpSimple_h__)
#define __numerical_PoissonGeneratorInversionBuildUpSimple_h__
+#include "PoissonGeneratorInversionMaximumMean.h"
+
#include "../uniform/ContinuousUniformGenerator.h"
#include
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.ipp cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.ipp
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.ipp 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionBuildUpSimple.ipp 2012-07-02 04:07:32.000000000 +0000
@@ -4,10 +4,6 @@
#error This file is an implementation detail of PoissonGeneratorInversionBuildUpSimple.
#endif
-#define __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-#include "PoissonGeneratorInversionMaximumMean.ipp"
-#undef __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-
namespace numerical {
template
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.h cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.h
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.h 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.h 2012-07-02 04:07:32.000000000 +0000
@@ -8,6 +8,8 @@
#if !defined(__numerical_PoissonGeneratorInversionCheckPdf_h__)
#define __numerical_PoissonGeneratorInversionCheckPdf_h__
+#include "PoissonGeneratorInversionMaximumMean.h"
+
#include "../uniform/ContinuousUniformGenerator.h"
#include
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.ipp cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.ipp
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.ipp 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionCheckPdf.ipp 2012-07-02 04:07:32.000000000 +0000
@@ -4,10 +4,6 @@
#error This file is an implementation detail of PoissonGeneratorInversionCheckPdf.
#endif
-#define __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-#include "PoissonGeneratorInversionMaximumMean.ipp"
-#undef __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-
namespace numerical {
template
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDown.h cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDown.h
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDown.h 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDown.h 2012-07-02 04:07:32.000000000 +0000
@@ -8,6 +8,8 @@
#if !defined(__numerical_PoissonGeneratorInversionChopDown_h__)
#define __numerical_PoissonGeneratorInversionChopDown_h__
+#include "PoissonGeneratorInversionMaximumMean.h"
+
#include "../uniform/ContinuousUniformGenerator.h"
#ifdef NUMERICAL_POISSON_HERMITE_APPROXIMATION
@@ -24,10 +26,6 @@
#include
#include
-#define __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-#include "PoissonGeneratorInversionMaximumMean.ipp"
-#undef __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-
namespace numerical {
//! Generator for Poisson deviates using the inversion (chop-down) method.
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.h cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.h
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.h 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.h 2012-07-02 04:07:32.000000000 +0000
@@ -8,6 +8,8 @@
#if !defined(__numerical_PoissonGeneratorInversionChopDownSimple_h__)
#define __numerical_PoissonGeneratorInversionChopDownSimple_h__
+#include "PoissonGeneratorInversionMaximumMean.h"
+
#include "../uniform/ContinuousUniformGenerator.h"
#include
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.ipp cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.ipp
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.ipp 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDownSimple.ipp 2012-07-02 04:07:32.000000000 +0000
@@ -4,10 +4,6 @@
#error This file is an implementation detail of PoissonGeneratorInversionChopDownSimple.
#endif
-#define __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-#include "PoissonGeneratorInversionMaximumMean.ipp"
-#undef __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-
namespace numerical {
template
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDownUnrolled.h cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDownUnrolled.h
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionChopDownUnrolled.h 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionChopDownUnrolled.h 2012-07-02 04:07:32.000000000 +0000
@@ -8,6 +8,8 @@
#if !defined(__numerical_PoissonGeneratorInversionChopDownUnrolled_h__)
#define __numerical_PoissonGeneratorInversionChopDownUnrolled_h__
+#include "PoissonGeneratorInversionMaximumMean.h"
+
#include "../uniform/ContinuousUniformGenerator.h"
#include "../../interpolation/hermite.h"
@@ -19,10 +21,6 @@
#include
#include
-#define __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-#include "PoissonGeneratorInversionMaximumMean.ipp"
-#undef __numerical_random_PoissonGeneratorInversionMaximumMean_ipp__
-
namespace numerical {
//! Generator for Poisson deviates using the inversion (chop-down) method.
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionMaximumMean.h cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionMaximumMean.h
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionMaximumMean.h 1970-01-01 00:00:00.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionMaximumMean.h 2012-07-02 04:07:32.000000000 +0000
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+
+/*!
+ \file numerical/random/poisson.h
+ \brief Constants for the inversion method.
+*/
+
+#if !defined(__numerical_random_poisson_PoissonGeneratorInversionMaximumMean_h__)
+#define __numerical_random_poisson_PoissonGeneratorInversionMaximumMean_h__
+
+namespace numerical {
+
+//! Maximum allowed mean for using the PoissonGeneratorInversion class.
+/*!
+ If the mean is too large, we will get underflow in computing the
+ probability density function.
+*/
+template
+class PoissonGeneratorInversionMaximumMean {
+public:
+ //! Invalid value for an unknown number type.
+ enum {Value = -1};
+};
+
+template<>
+class PoissonGeneratorInversionMaximumMean {
+public:
+ //! - std::log(std::numeric_limits::min()) == 708.396
+ enum {Value = 708};
+};
+
+template<>
+class PoissonGeneratorInversionMaximumMean {
+public:
+ //! - std::log(std::numeric_limits::min()) == 87.3365
+ /*!
+ Here I assume that the arithmetic is actually done in single precision.
+ However, floats are typically converted to double's.
+ */
+ enum {Value = 87};
+};
+
+} // namespace numerical
+
+#endif
diff -Nru cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionRatioOfUniformsWinrand.ipp cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionRatioOfUniformsWinrand.ipp
--- cain-1.9/src/numerical/random/poisson/PoissonGeneratorInversionRatioOfUniformsWinrand.ipp 2011-09-27 19:44:57.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random/poisson/PoissonGeneratorInversionRatioOfUniformsWinrand.ipp 2012-07-02 04:07:32.000000000 +0000
@@ -12,11 +12,11 @@
typename PoissonGeneratorInversionRatioOfUniformsWinrand<_Uniform, _Result>::result_type
PoissonGeneratorInversionRatioOfUniformsWinrand<_Uniform, _Result>::
operator()(const argument_type my) {
-#define C0 9.18938533204672742e-01 /* constants for */
-#define C1 8.33333333333333333e-02 /* Stirling's */
-#define C3 -2.77777777777777778e-03 /* approximation */
-#define C5 7.93650793650793651e-04 /* of ln(k!) */
-#define C7 -5.95238095238095238e-04
+ const Number C0 = 9.18938533204672742e-01; /* constants for */
+ const Number C1 = 8.33333333333333333e-02; /* Stirling's */
+ const Number C3 = -2.77777777777777778e-03; /* approximation */
+ const Number C5 = 7.93650793650793651e-04; /* of ln(k!) */
+ const Number C7 = -5.95238095238095238e-04;
static int m, b;
diff -Nru cain-1.9/src/numerical/random.h cain-1.10+dfsg/src/numerical/random.h
--- cain-1.9/src/numerical/random.h 2011-09-27 19:44:58.000000000 +0000
+++ cain-1.10+dfsg/src/numerical/random.h 2012-07-02 04:07:33.000000000 +0000
@@ -9,19 +9,19 @@
#define __numerical_random_h__
// Discrete deviates.
-#include "discrete.h"
+#include "random/discrete.h"
// Exponential
-#include "exponential.h"
+#include "random/exponential.h"
// Gamma
-#include "gamma.h"
+#include "random/gamma.h"
// Hypoexponential
-#include "hypoexponential.h"
+#include "random/hypoexponential.h"
// Normal (Gaussian) deviates.
-#include "normal.h"
+#include "random/normal.h"
// Poisson deviates.
-#include "poisson.h"
+#include "random/poisson.h"
// Uniform random deviates.
-#include "uniform.h"
+#include "random/uniform.h"
namespace numerical {
diff -Nru cain-1.9/src/solvers/env.py cain-1.10+dfsg/src/solvers/env.py
--- cain-1.9/src/solvers/env.py 2011-09-27 19:44:58.000000000 +0000
+++ cain-1.10+dfsg/src/solvers/env.py 2012-07-02 04:07:33.000000000 +0000
@@ -35,6 +35,9 @@
# uses long long.
serial.AppendUnique(CCFLAGS=['-ansi', '-Wall', '-Wextra',
'-Wstrict-aliasing=2', '-Wno-unknown-pragmas'])
+ # Use the rt library on linux, but not on darwin or windows.
+ if serial['PLATFORM'] == 'posix':
+ serial.AppendUnique(LIBS=['rt'])
# We need this to compile the implicit tau-leaping solvers for PPC
# architectures.
serial.AppendUnique(CCFLAGS=['-DEIGEN_DONT_VECTORIZE'])
Binary files /tmp/tmpowQPTK/Alr96NWhxb/cain-1.9/src/solvers/env.pyc and /tmp/tmpowQPTK/MhUGwm3H4P/cain-1.10+dfsg/src/solvers/env.pyc differ
diff -Nru cain-1.9/src/solvers/Makefile cain-1.10+dfsg/src/solvers/Makefile
--- cain-1.9/src/solvers/Makefile 2011-09-27 19:44:58.000000000 +0000
+++ cain-1.10+dfsg/src/solvers/Makefile 2012-07-02 04:07:34.000000000 +0000
@@ -21,6 +21,10 @@
# Commented out for Eigen.
#CXXFLAGS += -pedantic
+ifeq ($(shell uname),Linux)
+ LOADLIBES += -lrt
+endif
+
ifndef SOURCES
# The homogeneous sources have mass action solvers that can be pre-compiled.
SOURCES = $(wildcard Homogeneous*.cc)
diff -Nru cain-1.9/state/State.py cain-1.10+dfsg/state/State.py
--- cain-1.9/state/State.py 2011-09-27 19:44:46.000000000 +0000
+++ cain-1.10+dfsg/state/State.py 2012-07-02 04:07:16.000000000 +0000
@@ -299,7 +299,7 @@
self.seed = 2**31
self.listOfMt19937States = []
self.customSolversDirectory = tempfile.mkdtemp()
- self.version = '1.9'
+ self.version = '1.10'
def __del__(self):
if os.access(self.customSolversDirectory, os.F_OK):
@@ -844,6 +844,9 @@
' -I' + os.path.join(rp, 'src') +\
' -I' + self.customSolversDirectory + ' '
command = cxx + cxxFlags + source
+ # For linux, we need the rt library.
+ if re.match('linux', sys.platform):
+ command += ' -lrt'
process = subprocess.Popen(command, bufsize=-1,
universal_newlines=True, shell=True,
stdin=subprocess.PIPE,