Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
- Added `ConstantSignalSource` component as first use case for `BusToSignalAdapter`.
- Added IDA option to suppress algebraic variables in local error tests.
- Removed `COO_Matrix` class.
- Added portable `Vector` class and policy-based memory utilities.

## v0.1

Expand Down
105 changes: 72 additions & 33 deletions GridKit/AutomaticDifferentiation/DependencyTracking/Variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <limits>
#include <map>
#include <string>
#include <utility>
#include <vector>

#include <GridKit/Constants.hpp>
Expand All @@ -38,8 +39,7 @@ namespace GridKit
Variable()
: value_(0.0),
variable_number_(INVALID_VAR_NUMBER),
is_fixed_(false),
dependencies_(new DependencyMap)
is_fixed_(false)
{
}

Expand All @@ -49,8 +49,7 @@ namespace GridKit
explicit Variable(double value)
: value_(value),
variable_number_(INVALID_VAR_NUMBER),
is_fixed_(false),
dependencies_(new DependencyMap)
is_fixed_(false)
{
}

Expand All @@ -62,10 +61,9 @@ namespace GridKit
Variable(double value, size_t variable_number)
: value_(value),
variable_number_(variable_number),
is_fixed_(false),
dependencies_(new DependencyMap)
is_fixed_(false)
{
(*dependencies_)[variable_number_] = 1.0;
dependencies_[variable_number_] = 1.0;
}

/**
Expand All @@ -75,18 +73,33 @@ namespace GridKit
: value_(v.value_),
variable_number_(INVALID_VAR_NUMBER),
is_fixed_(false),
dependencies_(new DependencyMap(*v.dependencies_))
dependencies_(v.dependencies_)
{
}

/**
@brief Destructor deletes the dependency map.
@brief Move constructor.

Unlike the copy constructor, this relocates @a v rather than
creating a new, detached temporary from it, so (unlike copy)
it carries over `variable_number_`/`is_fixed_` as-is instead
of resetting them. The dependency map is relocated via
`std::map`'s own move constructor (O(1)) instead of being
deep-copied.
*/
~Variable()
Variable(Variable&& v) noexcept
: value_(v.value_),
variable_number_(v.variable_number_),
is_fixed_(v.is_fixed_),
dependencies_(std::move(v.dependencies_))
{
delete dependencies_;
}

/**
@brief Destructor.
*/
~Variable() = default;

/**
@brief Assignment operator. Assigning double value to
Variable removes its dependencies. Use only if you know
Expand All @@ -96,7 +109,7 @@ namespace GridKit
{
value_ = rhs;

dependencies_->clear();
dependencies_.clear();
return *this;
}

Expand All @@ -120,8 +133,34 @@ namespace GridKit
setFixed(rhs.is_fixed());

// set dependencies from rhs
dependencies_->clear(); // clear map just in case
addDependencies(rhs); // use only dependencies from the rhs
dependencies_.clear(); // clear map just in case
addDependencies(rhs); // use only dependencies from the rhs

return *this;
}

/**
@brief Move assignment operator.

Same contract as the copy assignment operator (value and
dependencies come from rhs, variable ID of *this is left
unchanged), but relocates rhs's dependency map via
`std::map`'s own move assignment instead of deep-copying its
entries.
*/
Variable& operator=(Variable&& rhs) noexcept
{
if (this == &rhs) // self-assignment
return *this;

// set value from rhs
value_ = rhs.value_;

// if rhs is a constant so is *this
setFixed(rhs.is_fixed());

// relocate dependencies from rhs instead of copying them
dependencies_ = std::move(rhs.dependencies_);

return *this;
}
Expand Down Expand Up @@ -170,7 +209,7 @@ namespace GridKit
*/
double der(size_t i) const
{
return (*dependencies_)[i];
return dependencies_[i];
}

/**
Expand All @@ -189,9 +228,9 @@ namespace GridKit
*/
void setVariableNumber(size_t variable_number)
{
dependencies_->clear();
variable_number_ = variable_number;
(*dependencies_)[variable_number_] = 1.0;
dependencies_.clear();
variable_number_ = variable_number;
dependencies_[variable_number_] = 1.0;
}

/**
Expand Down Expand Up @@ -266,36 +305,36 @@ namespace GridKit
size_t variable_number_; ///< Independent variable ID
bool is_fixed_; ///< Constant parameter flag.

mutable DependencyMap* dependencies_;
static const size_t INVALID_VAR_NUMBER = INVALID_INDEX<size_t>;
mutable DependencyMap dependencies_;
static const size_t INVALID_VAR_NUMBER = INVALID_INDEX<size_t>;
};

//------------------------------------
// non-member operators and functions
//------------------------------------

// unary -
inline const Variable operator-(const Variable& v);
inline Variable operator-(const Variable& v);

// +
inline const Variable operator+(const Variable& lhs, const Variable& rhs);
inline const Variable operator+(const Variable& lhs, const double& rhs);
inline const Variable operator+(const double& lhs, const Variable& rhs);
inline Variable operator+(const Variable& lhs, const Variable& rhs);
inline Variable operator+(const Variable& lhs, const double& rhs);
inline Variable operator+(const double& lhs, const Variable& rhs);

// -
inline const Variable operator-(const Variable& lhs, const Variable& rhs);
inline const Variable operator-(const Variable& lhs, const double& rhs);
inline const Variable operator-(const double& lhs, const Variable& rhs);
inline Variable operator-(const Variable& lhs, const Variable& rhs);
inline Variable operator-(const Variable& lhs, const double& rhs);
inline Variable operator-(const double& lhs, const Variable& rhs);

// *
inline const Variable operator*(const Variable& lhs, const Variable& rhs);
inline const Variable operator*(const Variable& lhs, const double& rhs);
inline const Variable operator*(const double& lhs, const Variable& rhs);
inline Variable operator*(const Variable& lhs, const Variable& rhs);
inline Variable operator*(const Variable& lhs, const double& rhs);
inline Variable operator*(const double& lhs, const Variable& rhs);

// /
inline const Variable operator/(const Variable& lhs, const Variable& rhs);
inline const Variable operator/(const Variable& lhs, const double& rhs);
inline const Variable operator/(const double& lhs, const Variable& rhs);
inline Variable operator/(const Variable& lhs, const Variable& rhs);
inline Variable operator/(const Variable& lhs, const double& rhs);
inline Variable operator/(const double& lhs, const Variable& rhs);

// ==
inline bool operator==(const Variable& lhs, const Variable& rhs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ namespace GridKit
*/
const Variable::DependencyMap& Variable::getDependencies() const
{
assert(dependencies_ != 0);
return *dependencies_;
return dependencies_;
}

/**
Expand All @@ -35,17 +34,17 @@ namespace GridKit
*/
void Variable::addDependencies(const Variable& v)
{
for (auto& p : *(v.dependencies_))
(*dependencies_)[p.first] = p.second;
for (auto& p : v.dependencies_)
dependencies_[p.first] = p.second;
}

/**
@brief Multiplies each partial derivative of @a this by @a c.
*/
void Variable::scaleDependencies(double c)
{
for (auto& p : *dependencies_)
(*dependencies_)[p.first] *= c;
for (auto& p : dependencies_)
p.second *= c;
}

/**
Expand All @@ -67,10 +66,10 @@ namespace GridKit
return;
}

if (dependencies_ != NULL && !dependencies_->empty())
if (!dependencies_.empty())
{
os << " dependencies: [ ";
for (auto& p : *dependencies_)
for (auto& p : dependencies_)
os << "(" << p.first << ", " << p.second << ") ";
os << "]";
}
Expand All @@ -97,8 +96,8 @@ namespace GridKit
Variable& Variable::operator+=(const Variable& rhs)
{
// compute partial derivatives of *this
for (auto& p : *(rhs.dependencies_))
(*dependencies_)[p.first] += (p.second);
for (auto& p : rhs.dependencies_)
dependencies_[p.first] += (p.second);

// compute value of *this
value_ += rhs.value_;
Expand All @@ -124,8 +123,8 @@ namespace GridKit
Variable& Variable::operator-=(const Variable& rhs)
{
// compute partial derivatives of *this
for (auto& p : *(rhs.dependencies_))
(*dependencies_)[p.first] -= (p.second);
for (auto& p : rhs.dependencies_)
dependencies_[p.first] -= (p.second);

// compute value of *this
value_ -= rhs.value_;
Expand Down Expand Up @@ -159,8 +158,8 @@ namespace GridKit
scaleDependencies(rhs.value_);

// compute partial derivatives of rhs and add them to *this
for (auto& p : *(rhs.dependencies_))
(*dependencies_)[p.first] += (p.second * value_);
for (auto& p : rhs.dependencies_)
dependencies_[p.first] += (p.second * value_);

// compute value of this
value_ *= rhs.value_;
Expand Down Expand Up @@ -195,8 +194,8 @@ namespace GridKit

// derivation by parts of @a *this
scaleDependencies(inverseRhs);
for (auto& p : *(rhs.dependencies_))
(*dependencies_)[p.first] -= (p.second * value_ * inverseRhsSq);
for (auto& p : rhs.dependencies_)
dependencies_[p.first] -= (p.second * value_ * inverseRhsSq);

// compute value of this
value_ *= inverseRhs;
Expand Down
Loading
Loading