diff --git a/.cproject b/.cproject
index 0665eaf06..7223156ff 100644
--- a/.cproject
+++ b/.cproject
@@ -912,6 +912,14 @@
true
true
+
+ make
+ -j5
+ timeSFMExpressions.run
+ true
+ true
+ true
+
make
-j5
diff --git a/gtsam_unstable/timing/timeSFMExpressions.cpp b/gtsam_unstable/timing/timeSFMExpressions.cpp
new file mode 100644
index 000000000..fc2a8d97e
--- /dev/null
+++ b/gtsam_unstable/timing/timeSFMExpressions.cpp
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------------
+
+ * GTSAM Copyright 2010, Georgia Tech Research Corporation,
+ * Atlanta, Georgia 30332-0415
+ * All Rights Reserved
+ * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
+
+ * See LICENSE for the license information
+
+ * -------------------------------------------------------------------------- */
+
+/**
+ * @file timeSFMExpressions.cpp
+ * @brief time CalibratedCamera derivatives, realistic scenario
+ * @author Frank Dellaert
+ * @date October 3, 2014
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include // std::setprecision
+
+using namespace std;
+using namespace gtsam;
+
+//#define TERNARY
+
+int main() {
+
+ // number of cameras, and points
+ static const size_t M=100, N = 10000, n = M*N;
+
+ // Create leaves
+ Cal3_S2_ K('K', 0);
+ std::vector > x = createUnknowns(M, 'x');
+ std::vector > p = createUnknowns(N, 'p');
+
+ // Some parameters needed
+ Point2 z(-17, 30);
+ SharedNoiseModel model = noiseModel::Unit::Create(2);
+
+ // Create values
+ Values values;
+ values.insert(Symbol('K', 0), Cal3_S2());
+ for (int i = 0; i < M; i++)
+ values.insert(Symbol('x', i), Pose3());
+ for (int j = 0; j < N; j++)
+ values.insert(Symbol('p', j), Point3(0, 0, 1));
+
+ long timeLog = clock();
+ NonlinearFactorGraph graph;
+ for (int i = 0; i < M; i++) {
+ for (int j = 0; j < N; j++) {
+ NonlinearFactor::shared_ptr f = boost::make_shared<
+ ExpressionFactor >
+#ifdef TERNARY
+ (model, z, project3(x[i], p[j], K));
+#else
+ (model, z, uncalibrate(K, project(transform_to(x[i], p[j]))));
+#endif
+ graph.push_back(f);
+ }
+ }
+ long timeLog2 = clock();
+ cout << setprecision(3);
+ double seconds = (double) (timeLog2 - timeLog) / CLOCKS_PER_SEC;
+ cout << seconds << " seconds to build" << endl;
+
+ timeLog = clock();
+ GaussianFactorGraph::shared_ptr gfg = graph.linearize(values);
+ timeLog2 = clock();
+ seconds = (double) (timeLog2 - timeLog) / CLOCKS_PER_SEC;
+ cout << seconds << " seconds to linearize" << endl;
+ cout << ((double) seconds * 1000000 / n) << " musecs/call" << endl;
+
+ return 0;
+}