Index: NetworkEditor/src/ProcessingTree.cxx
===================================================================
--- NetworkEditor/src/ProcessingTree.cxx	(revision 10025)
+++ NetworkEditor/src/ProcessingTree.cxx	(working copy)
@@ -70,6 +70,7 @@
 	"ControlTraceReader",
 	"ControlTraceWriter",
 	"ControlScaler", 
+	"ControlOperator",
 	"AutoPanner",
 	"FlagControl",
 	"Random",
Index: NetworkEditor/src/RegisterConfiguratorLaunchers.cxx
===================================================================
--- NetworkEditor/src/RegisterConfiguratorLaunchers.cxx	(revision 10025)
+++ NetworkEditor/src/RegisterConfiguratorLaunchers.cxx	(working copy)
@@ -62,6 +62,7 @@
 // Controls
 #include <CLAM/Fundamental2Control.hxx>
 #include <CLAM/ControlMapper.hxx>
+#include <CLAM/ControlOperator.hxx>
 #include <CLAM/ControlPrinter.hxx>
 #include <CLAM/ControlScaler.hxx>
 #include "ControlSurface.hxx"
@@ -129,6 +130,7 @@
 
 // Controls
 STANDARD_PROCESSING_CONFIG_REGISTER(AutoPannerConfig);
+STANDARD_PROCESSING_CONFIG_REGISTER(ControlOperatorConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(ControlPrinterConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(ControlScalerConfig);
 STANDARD_PROCESSING_CONFIG_REGISTER(ControlSourceConfig);
Index: CLAM/src/Processing/Controls/ControlOperator.cxx
===================================================================
--- CLAM/src/Processing/Controls/ControlOperator.cxx	(revision 0)
+++ CLAM/src/Processing/Controls/ControlOperator.cxx	(revision 0)
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
+ *                         UNIVERSITAT POMPEU FABRA
+ * Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "ControlOperator.hxx"
+#include "Factory.hxx"
+#include <math.h>
+
+namespace CLAM
+{
+
+Enum::tEnumValue EControlOpType::sEnumValues[] =
+	{
+		{ EControlOpType::eAdd, "Add" },
+		{ EControlOpType::eSubtract, "Subtract" },
+		{ EControlOpType::eMultiply, "Multiply" },
+		{ EControlOpType::eDivide, "Divide" },
+		{ EControlOpType::eSine, "Sine" },
+		{ EControlOpType::eCosine, "Cosine" },
+		{ EControlOpType::eTangent, "Tangent" },
+		{ EControlOpType::eArcSine, "ArcSine" },
+		{ EControlOpType::eArcCosine, "ArcCosine" },
+		{ EControlOpType::eArcTangent, "ArcTangent" },
+		{ EControlOpType::eNatLogarithm, "Natural Logarithm" },
+		{ EControlOpType::eNatExponent, "Natural Exponent" },
+		{ 0, NULL }
+	};
+
+Enum::tValue EControlOpType::sDefault = EControlOpType::eAdd;
+
+/* ================================================================== */
+
+void ControlOperatorConfig::DefaultInit()
+{
+	AddAll();
+	UpdateData();
+	SetNumberOfInputs(2);
+}
+
+ControlOperator::ControlOperator()
+	: mOperator(NULL)
+{
+	Configure( mConfig );	
+}
+
+ControlOperator::ControlOperator( const ControlOperatorConfig& cfg ) 
+	: mOperator(NULL)
+{ 
+	Configure( cfg );
+}
+
+ControlOperator::~ControlOperator()
+{
+	RemoveOldControls();
+	delete mOperator;
+}
+
+bool ControlOperator::ConcreteConfigure( const ProcessingConfig& cfg )
+{
+	RemoveOldControls();
+	CopyAsConcreteConfig( mConfig, cfg );
+
+	delete mOperator;
+	switch (mConfig.GetSelectedOperator().GetValue())
+	{
+	case EControlOpType::eAdd:
+		mOperator = new ControlOpAdd();
+		break;
+	case EControlOpType::eSubtract:
+		mOperator = new ControlOpSubtract();
+		break;
+	case EControlOpType::eMultiply:
+		mOperator = new ControlOpMultiply();
+		break;
+	case EControlOpType::eDivide:
+		mOperator = new ControlOpDivide();
+		break;
+
+	case EControlOpType::eSine:
+		mOperator = new ControlOpSine();
+		break;
+	case EControlOpType::eCosine:
+		mOperator = new ControlOpCosine();
+		break;
+	case EControlOpType::eTangent:
+		mOperator = new ControlOpTangent();
+		break;
+
+	case EControlOpType::eArcSine:
+		mOperator = new ControlOpArcSine();
+		break;
+	case EControlOpType::eArcCosine:
+		mOperator = new ControlOpArcCosine();
+		break;
+	case EControlOpType::eArcTangent:
+		mOperator = new ControlOpArcTangent();
+		break;
+
+	case EControlOpType::eNatLogarithm:
+		mOperator = new ControlOpNatLogarithm();
+		break;
+	case EControlOpType::eNatExponent:
+		mOperator = new ControlOpNatExponent();
+		break;
+
+	default:
+		AddConfigErrorMessage("Invalid operator selected in configuration");
+		return false;
+	}
+
+	int nInputs = int(mConfig.GetNumberOfInputs());
+	int minInputs = mOperator->GetMinimumInputs();
+	if (nInputs < minInputs)
+	{
+		std::stringstream str;
+		str << "The '" << mOperator->GetOpType().GetString()
+			<< "' operator requires at least " 
+			<< minInputs << " inputs";
+		AddConfigErrorMessage(str.str());
+		return false;
+	}
+	
+	mInControls.Resize(nInputs, "Input", this);
+
+	int nOutputs = mOperator->GetNumberOfOutputs(nInputs);
+	mOutControls.Resize(nOutputs, "Output", this);
+	
+	return true; 		
+}
+
+bool ControlOperator::Do()
+{
+	mOperator->Do(mInControls, mOutControls);
+	return true;
+}
+
+void ControlOperator::RemoveOldControls()
+{
+	GetInControls().Clear();
+	mInControls.Clear();
+	GetOutControls().Clear();
+	mOutControls.Clear();
+}
+
+/* ================================================================== */
+
+void ControlBinaryOp::Do(const InControlArray &in, OutControlArray &out) const
+{
+	TControlData output = in[0].GetLastValue();
+	size_t nControls = in.Size();
+	for (int i = 1; i < nControls; i++)
+		output = DoOp(output, in[i].GetLastValue());
+	out[0].SendControl(output);
+}
+
+void ControlUnaryOp::Do(const InControlArray &in, OutControlArray &out) const
+{
+	size_t nControls = in.Size();
+	for (size_t i = 0; i < nControls; i++)
+		out[i].SendControl(DoOp(in[i].GetLastValue()));
+}
+
+/* ================================================================== */
+
+TControlData ControlOpAdd::DoOp(TControlData lhs, TControlData rhs) const
+{
+	return lhs + rhs;
+}
+
+TControlData ControlOpSubtract::DoOp(TControlData lhs, TControlData rhs) const
+{
+	return lhs - rhs;
+}
+
+TControlData ControlOpMultiply::DoOp(TControlData lhs, TControlData rhs) const
+{
+	return lhs * rhs;
+}
+
+TControlData ControlOpDivide::DoOp(TControlData lhs, TControlData rhs) const
+{
+	if (0 == rhs)
+		return INFINITY;
+	return lhs / rhs;
+}
+
+/* ================================================================== */
+
+TControlData ControlOpSine::DoOp(TControlData input) const
+{
+	return sin(input);
+}
+TControlData ControlOpCosine::DoOp(TControlData input) const
+{
+	return cos(input);
+}
+TControlData ControlOpTangent::DoOp(TControlData input) const
+{
+	return tan(input);
+}
+
+TControlData ControlOpArcSine::DoOp(TControlData input) const
+{
+	return asin(input);
+}
+TControlData ControlOpArcCosine::DoOp(TControlData input) const
+{
+	return acos(input);
+}
+TControlData ControlOpArcTangent::DoOp(TControlData input) const
+{
+	return atan(input);
+}
+
+TControlData ControlOpNatLogarithm::DoOp(TControlData input) const
+{
+	return log(input);
+}
+TControlData ControlOpNatExponent::DoOp(TControlData input) const
+{
+	return exp(input);
+}
+
+/* ================================================================== */
+
+namespace detail
+{
+typedef CLAM::Factory<CLAM::Processing> ProcessingFactory;
+static ProcessingFactory::Registrator<CLAM::ControlOperator>
+			regtControlOperator( "ControlOperator" );
+}
+
+} // CLAM namespace
+
Index: CLAM/src/Processing/Controls/ControlOperator.hxx
===================================================================
--- CLAM/src/Processing/Controls/ControlOperator.hxx	(revision 0)
+++ CLAM/src/Processing/Controls/ControlOperator.hxx	(revision 0)
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
+ *                         UNIVERSITAT POMPEU FABRA
+ * Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _ControlOperator_
+#define _ControlOperator_
+
+#include "DataTypes.hxx"
+#include "Processing.hxx"
+#include "ProcessingConfig.hxx"
+#include "InControlArray.hxx"
+#include "OutControlArray.hxx"
+#include "Enum.hxx"
+
+namespace CLAM
+{
+
+class EControlOpType : public Enum
+{
+public:
+
+	static tEnumValue sEnumValues[];
+	static tValue sDefault;
+	EControlOpType() : Enum(sEnumValues, sDefault) {}
+	EControlOpType(tValue v) : Enum(sEnumValues, v) {};
+	EControlOpType(std::string s) : Enum(sEnumValues, s) {};
+
+	typedef enum {
+		eAdd,
+		eSubtract,
+		eMultiply,
+		eDivide,
+		eSine,
+		eCosine,
+		eTangent,
+		eArcSine,
+		eArcCosine,
+		eArcTangent,
+		eNatLogarithm,
+		eNatExponent,
+	}; 
+	
+	Component* Species() const { return new EControlOpType; }
+};
+
+/* ================================================================== */
+
+class ControlOperatorConfig : public ProcessingConfig
+{
+public:
+	DYNAMIC_TYPE_USING_INTERFACE(
+			ControlOperatorConfig, 2, ProcessingConfig );
+	DYN_ATTRIBUTE( 0, public, EControlOpType, SelectedOperator );
+	DYN_ATTRIBUTE( 1, public, unsigned int, NumberOfInputs );
+
+private:
+	void DefaultInit();
+};
+
+class ControlOp;
+
+class ControlOperator : public Processing
+{
+public:
+	ControlOperator();
+	ControlOperator( const ControlOperatorConfig& cfg );
+	~ControlOperator();
+
+	const char *GetClassName() const { return "ControlOperator"; }
+
+	bool ConcreteConfigure( const ProcessingConfig& cfg ); 
+
+	const ProcessingConfig& GetConfig() const { return mConfig; }
+
+	bool Do();
+
+protected:
+	void RemoveOldControls();
+
+private:
+	ControlOperatorConfig mConfig;
+	InControlArray mInControls;
+	OutControlArray mOutControls;
+
+	ControlOp *mOperator;
+};
+
+/* ================================================================== */
+
+class ControlOp {
+public:
+	virtual ~ControlOp() { }
+	virtual EControlOpType GetOpType() const = 0;
+	virtual size_t GetMinimumInputs() const = 0;
+	virtual size_t GetNumberOfOutputs(size_t nInputs) const = 0;
+
+	virtual void Do(const InControlArray &in, OutControlArray &out) const = 0;
+};
+
+/* ================================================================== */
+
+class ControlBinaryOp : public ControlOp
+{
+public:
+	size_t GetMinimumInputs() const { return 2; }
+	virtual size_t GetNumberOfOutputs(size_t nInputs) const { return 1; }
+
+	void Do(const InControlArray &in, OutControlArray &out) const;
+
+protected:
+	virtual TControlData DoOp(TControlData lhs, TControlData rhs) const = 0;
+};
+
+class ControlOpAdd : public ControlBinaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eAdd; }
+	TControlData DoOp(TControlData lhs, TControlData rhs) const;
+};
+
+class ControlOpSubtract : public ControlBinaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eSubtract; }
+	TControlData DoOp(TControlData lhs, TControlData rhs) const;
+};
+
+class ControlOpMultiply : public ControlBinaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eMultiply; }
+	TControlData DoOp(TControlData lhs, TControlData rhs) const;
+};
+
+class ControlOpDivide : public ControlBinaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eDivide; }
+	TControlData DoOp(TControlData lhs, TControlData rhs) const;
+};
+
+/* ================================================================== */
+
+class ControlUnaryOp : public ControlOp {
+public:
+	size_t GetMinimumInputs() const { return 1; }
+	virtual size_t GetNumberOfOutputs(size_t nInputs) const { return nInputs; }
+
+	void Do(const InControlArray &in, OutControlArray &out) const;
+
+protected:
+	virtual TControlData DoOp(TControlData input) const = 0;
+};
+
+class ControlOpSine : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eSine; }
+	TControlData DoOp(TControlData input) const;
+};
+class ControlOpCosine : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eCosine; }
+	TControlData DoOp(TControlData input) const;
+};
+class ControlOpTangent : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eTangent; }
+	TControlData DoOp(TControlData input) const;
+};
+
+class ControlOpArcSine : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eArcSine; }
+	TControlData DoOp(TControlData input) const;
+};
+class ControlOpArcCosine : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eArcCosine; }
+	TControlData DoOp(TControlData input) const;
+};
+class ControlOpArcTangent : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eArcTangent; }
+	TControlData DoOp(TControlData input) const;
+};
+
+class ControlOpNatLogarithm : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eNatLogarithm; }
+	TControlData DoOp(TControlData input) const;
+};
+class ControlOpNatExponent : public ControlUnaryOp
+{
+public:
+	EControlOpType GetOpType() const { return EControlOpType::eNatExponent; }
+	TControlData DoOp(TControlData input) const;
+};
+
+
+} // CLAM namespace
+
+#endif
Index: CLAM/test/UnitTests/ProcessingsTests/ControlOperatorTest.cxx
===================================================================
--- CLAM/test/UnitTests/ProcessingsTests/ControlOperatorTest.cxx	(revision 0)
+++ CLAM/test/UnitTests/ProcessingsTests/ControlOperatorTest.cxx	(revision 0)
@@ -0,0 +1,220 @@
+/*
+* Copyright (c) 2001-2002 MUSIC TECHNOLOGY GROUP (MTG)
+*                         UNIVERSITAT POMPEU FABRA
+* Copyright (c) 2007 Superlucidity Services, LLC and Zachary T Welch
+*
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*
+*/
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "ControlOperator.hxx"
+#include "OutControlSender.hxx"
+#include "ControlPrinter.hxx"
+#include "InControl.hxx"
+#include "DataTypes.hxx"
+#include <math.h>
+
+namespace CLAMTest {
+
+class ControlOperatorTest;
+CPPUNIT_TEST_SUITE_REGISTRATION( ControlOperatorTest );
+
+class ControlOperatorTest : public CppUnit::TestFixture
+{
+public:
+
+	void setUp(){}
+	void tearDown(){}
+	
+private:
+	static const CLAM::TControlData xValue = .3141, yValue = .2718;
+	static const double mDelta = 0.00001f;
+
+	CPPUNIT_TEST_SUITE( ControlOperatorTest );
+	CPPUNIT_TEST( testDo_BinaryAdd );
+	CPPUNIT_TEST( testDo_BinarySubtract );
+	CPPUNIT_TEST( testDo_BinaryMultiply );
+	CPPUNIT_TEST( testDo_BinaryDivide );
+	CPPUNIT_TEST( testDo_UnarySine );
+	CPPUNIT_TEST( testDo_UnaryCosine );
+	CPPUNIT_TEST( testDo_UnaryTangent );
+	CPPUNIT_TEST( testDo_UnaryArcSine );
+	CPPUNIT_TEST( testDo_UnaryArcCosine );
+	CPPUNIT_TEST( testDo_UnaryArcTangent );
+	CPPUNIT_TEST( testDo_UnaryNatLogarithm );
+	CPPUNIT_TEST( testDo_UnaryNatExponent );
+	CPPUNIT_TEST_SUITE_END();
+
+	void configureSender(CLAM::OutControlSender &sender, CLAM::TControlData value)
+	{
+		CLAM::OutControlSenderConfig config;
+		config.SetMin(value);
+		config.SetDefault(value);
+		config.SetMax(value);
+		sender.Configure(config);
+	}
+
+	void testBinaryOp(CLAM::EControlOpType optype,
+			CLAM::TControlData expected)
+	{
+		CLAM::OutControlSender xSender, ySender;
+		configureSender(xSender, xValue);
+		configureSender(ySender, yValue);
+
+		CLAM::ControlOperator op;
+		CLAM::ControlOperatorConfig config;
+		config.SetSelectedOperator(optype);
+		config.SetNumberOfInputs(2);
+		op.Configure(config);
+
+		CLAM::ControlPrinter out;
+		CLAM::ControlPrinterConfig pconfig;
+		out.Configure(pconfig);
+
+		xSender.GetOutControls().Get("out").AddLink(
+				op.GetInControls().Get("Input_0"));
+		ySender.GetOutControls().Get("out").AddLink(
+				op.GetInControls().Get("Input_1"));
+		op.GetOutControls().Get("Output_0").AddLink(
+				out.GetInControls().Get("In Control"));
+
+		xSender.Start();
+		ySender.Start();
+		op.Start();
+		out.Start();
+
+		xSender.Do();
+		ySender.Do();
+		op.Do();
+		out.Do();
+
+		CLAM::TControlData received =
+			out.GetInControls().Get("In Control").GetLastValue();
+		CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, received, mDelta);
+
+		xSender.Stop();
+		ySender.Stop();
+		op.Stop();
+		out.Stop();
+	}
+	void testDo_BinaryAdd()
+	{
+		testBinaryOp(CLAM::EControlOpType::eAdd, xValue + yValue);
+	}
+	void testDo_BinarySubtract()
+	{
+		testBinaryOp(CLAM::EControlOpType::eSubtract, xValue - yValue);
+	}
+	void testDo_BinaryMultiply()
+	{
+		testBinaryOp(CLAM::EControlOpType::eMultiply, xValue * yValue);
+	}
+	void testDo_BinaryDivide()
+	{
+		testBinaryOp(CLAM::EControlOpType::eDivide, xValue / yValue);
+	}
+
+	void testUnaryOp(CLAM::EControlOpType optype,
+			CLAM::TControlData expectedX,
+			CLAM::TControlData expectedY)
+	{
+		CLAM::OutControlSender xSender, ySender;
+		configureSender(xSender, xValue);
+		configureSender(ySender, yValue);
+
+		CLAM::ControlOperator op;
+		CLAM::ControlOperatorConfig config;
+		config.SetSelectedOperator(optype);
+		config.SetNumberOfInputs(2);
+		op.Configure(config);
+
+		CLAM::ControlPrinter out;
+		CLAM::ControlPrinterConfig pconfig;
+		pconfig.SetIdentifier("out");
+		pconfig.SetNumberOfInputs(2);
+		out.Configure(pconfig);
+
+		xSender.GetOutControls().Get("out").AddLink(
+				op.GetInControls().Get("Input_0"));
+		ySender.GetOutControls().Get("out").AddLink(
+				op.GetInControls().Get("Input_1"));
+		op.GetOutControls().Get("Output_0").AddLink(
+				out.GetInControls().Get("out_0"));
+		op.GetOutControls().Get("Output_1").AddLink(
+				out.GetInControls().Get("out_1"));
+
+		xSender.Start();
+		ySender.Start();
+		op.Start();
+		out.Start();
+
+		xSender.Do();
+		ySender.Do();
+		op.Do();
+		out.Do();
+
+		CLAM::TControlData receivedX =
+			out.GetInControls().Get("out_0").GetLastValue();
+		CPPUNIT_ASSERT_DOUBLES_EQUAL(expectedX, receivedX, mDelta);
+
+		CLAM::TControlData receivedY =
+			out.GetInControls().Get("out_1").GetLastValue();
+		CPPUNIT_ASSERT_DOUBLES_EQUAL(expectedY, receivedY, mDelta);
+
+		xSender.Stop();
+		ySender.Stop();
+		op.Stop();
+		out.Stop();
+	}
+	void testDo_UnarySine()
+	{
+		testUnaryOp(CLAM::EControlOpType::eSine, sin(xValue), sin(yValue));
+	}
+	void testDo_UnaryCosine()
+	{
+		testUnaryOp(CLAM::EControlOpType::eCosine, cos(xValue), cos(yValue));
+	}
+	void testDo_UnaryTangent()
+	{
+		testUnaryOp(CLAM::EControlOpType::eTangent, tan(xValue), tan(yValue));
+	}
+
+	void testDo_UnaryArcSine()
+	{
+		testUnaryOp(CLAM::EControlOpType::eArcSine, asin(xValue), asin(yValue));
+	}
+	void testDo_UnaryArcCosine()
+	{
+		testUnaryOp(CLAM::EControlOpType::eArcCosine, acos(xValue), acos(yValue));
+	}
+	void testDo_UnaryArcTangent()
+	{
+		testUnaryOp(CLAM::EControlOpType::eArcTangent, atan(xValue), atan(yValue));
+	}
+
+	void testDo_UnaryNatLogarithm()
+	{
+		testUnaryOp(CLAM::EControlOpType::eNatLogarithm, log(xValue), log(yValue));
+	}
+	void testDo_UnaryNatExponent()
+	{
+		testUnaryOp(CLAM::EControlOpType::eNatExponent, exp(xValue), exp(yValue));
+	}
+};
+
+} // CLAMTest namespace
+
