Skip to content

Commit

Permalink
Merge pull request #6 from oluwatimilehin/quadratic-formula-calculator
Browse files Browse the repository at this point in the history
Add Quadratic formula calculator
  • Loading branch information
oluwatimilehin authored Jul 16, 2022
2 parents dee9ec1 + 1253f22 commit 2134e8d
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 151 deletions.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,75 @@ d_engine.set(anchorZ, 7);
EXPECT_EQ(d_engine.get(result), 7);
EXPECT_EQ(additionCounter,1); // It shouldn't recompute anchorY because its value did not change
EXPECT_EQ(subtractionCounter, 2);
````

#### A Quadratic Formula Calculator

````cpp
auto a(Anchors::create(2));
auto b(Anchors::create(-5));
auto c(Anchors::create(-3));

int bsquareCounter = 0;
int fourACCounter = 0;

auto negativeB = Anchors::map<double>(b, [](double b) { return -b; });
auto bSquare = Anchors::map<double>(b, [&bsquareCounter](double b) {
bsquareCounter++;
return b * b;
});

auto fourAC =
Anchors::map2<double>(a, c, [&fourACCounter](double x, double y) {
fourACCounter++;
return 4 * x * y;
});

auto squareRoot = Anchors::map2<double>(
bSquare, fourAC, [](double x, double y) { return std::sqrt(x - y); });

int denominatorCounter = 0;
auto denominator = Anchors::map<double>(a, [&denominatorCounter](double a) {
denominatorCounter++;
return 2 * a;
});

using FunctionType = std::function<double(double&, double&, double&)>;
FunctionType x1Func = [](double x, double y, double z) {
return (x + y) / z;
};

FunctionType x2Func = [](double x, double y, double z) {
return (x - y) / z;
};

auto x1 = Anchors::map3<double>(negativeB, squareRoot, denominator, x1Func);
auto x2 = Anchors::map3<double>(negativeB, squareRoot, denominator, x2Func);

d_engine.observe(x1);
d_engine.observe(x2);

{
EXPECT_EQ(3, d_engine.get(x1));
EXPECT_EQ(-0.5, d_engine.get(x2));

EXPECT_EQ(1, bsquareCounter);
EXPECT_EQ(1, fourACCounter);
EXPECT_EQ(1, denominatorCounter);
}

d_engine.set(c, -7);

{
EXPECT_EQ(3.5, d_engine.get(x1));
EXPECT_EQ(-1, d_engine.get(x2));

// Only the value of C changed, so only anchors
// that depend on C should be recalculated
EXPECT_EQ(1, bsquareCounter);
EXPECT_EQ(2, fourACCounter);
EXPECT_EQ(1, denominatorCounter);
}
````
### Note
Expand Down
10 changes: 10 additions & 0 deletions include/anchor.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,21 @@ class Anchor : public AnchorWrap<T> {
T d_value{};

int d_height{};
// The height of the Anchor. Its value is 0 if it has no dependencies.
// Otherwise, its value = Max(Height of Inputs) + 1

int d_necessary{};
// Indicates how many Anchors this node is a dependency of either directly
// or indirectly.

int d_numDependencies{};
// Number of dependencies this Anchor has.

int d_recomputeId{};
// The stabilization number at which this Anchor was last recomputed

int d_changeId{};
// The stabilization number at which the value of this Anchor last changed

bool d_hasNeverBeenComputed;

Expand Down
151 changes: 0 additions & 151 deletions include/anchorutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,13 @@ class Anchors {
* this type is different from the output Anchor Type T.
* @param anchor - input Anchor
* @param updater - function that maps the input Anchor to the output.
* Accepts an Lvalue reference.
* @return a shared pointer to the created Anchor
*/
template <typename T, typename InputType1 = T>
static AnchorPtr<T> map(
const AnchorPtr<InputType1> &anchor,
const typename Anchor<T, InputType1>::SingleInputUpdater &updater);

/**
* Creates an Anchor from an input Anchor.
*
* @tparam T - type of the output Anchor. `T` should overload the
* equality and output operators if not already defined.
* @tparam InputType1 - optional type of the input Anchor. Required only if
* this type is different from the output Anchor Type T.
* @param anchor - input Anchor
* @param updater - function that maps the input Anchor to the output.
* Accepts an Rvalue reference.
* @return a shared pointer to the created Anchor
*/
template <typename T, typename InputType1 = T>
static AnchorPtr<T> map(
const AnchorPtr<InputType1> &anchor,
const typename Anchor<T, InputType1>::SingleInputUpdater &&updater);

/**
* Creates an Anchor from two input Anchors.
*
Expand All @@ -80,7 +62,6 @@ class Anchors {
* @param anchor1 - first input Anchor.
* @param anchor2 - second input Anchor.
* @param updater - function that maps the input Anchors to the output.
* Accepts an Lvalue reference.
* @return a shared pointer to the created Anchor.
*/
template <typename T, typename InputType1 = T, typename InputType2 = T>
Expand All @@ -90,28 +71,6 @@ class Anchors {
const typename Anchor<T, InputType1, InputType2>::DualInputUpdater
&updater);

/**
* Creates an Anchor from two input Anchors.
*
* @tparam T - type of the output Anchor. `T` should overload the
* equality and output operators if not already defined.
* @tparam InputType1 - optional type of the first input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @tparam InputType2 - optional type of the second input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @param anchor1 - first input Anchor.
* @param anchor2 - second input Anchor.
* @param updater - function that maps the input Anchors to the output.
* Accepts an Rvalue reference.
* @return a shared pointer to the created Anchor.
*/
template <typename T, typename InputType1 = T, typename InputType2 = T>
static AnchorPtr<T> map2(
const AnchorPtr<InputType1> &anchor1,
const AnchorPtr<InputType2> &anchor2,
const typename Anchor<T, InputType1, InputType2>::DualInputUpdater
&&updater);

/**
* Creates an Anchor from three input Anchors
* @tparam T - type of the output Anchor. `T` should overload the
Expand All @@ -126,7 +85,6 @@ class Anchors {
* @param anchor2 - second input Anchor.
* @param anchor3 - third input Anchor.
* @param updater - function that maps the input Anchors to the output.
* Accepts a Lvalue reference.
* @return a shared pointer to the created Anchor
*/
template <typename T,
Expand All @@ -140,34 +98,6 @@ class Anchors {
const std::function<T(InputType1 &, InputType2 &, InputType3 &)>
&updater);

/**
* Creates an Anchor from three input Anchors
* @tparam T - type of the output Anchor. `T` should overload the
* equality and output operators if not already defined.
* @tparam InputType1 - optional type of the first input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @tparam InputType2 - optional type of the second input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @tparam InputType3 - optional type of the third input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @param anchor1 - first input Anchor.
* @param anchor2 - second input Anchor.
* @param anchor3 - third input Anchor.
* @param updater - function that maps the input Anchors to the output.
* Accepts a Rvalue reference.
* @return a shared pointer to the created Anchor
*/
template <typename T,
typename InputType1 = T,
typename InputType2 = T,
typename InputType3 = T>
static AnchorPtr<T> map3(
const AnchorPtr<InputType1> &anchor1,
const AnchorPtr<InputType2> &anchor2,
const AnchorPtr<InputType3> &anchor3,
const std::function<T(InputType1 &, InputType2 &, InputType3 &)>
&&updater);

/**
* Creates an Anchor from four input Anchors
* @tparam T - type of the output Anchor. `T` should overload the
Expand All @@ -185,7 +115,6 @@ class Anchors {
* @param anchor3 - third input Anchor.
* @param anchor4 - fourth input Anchor.
* @param updater - function that maps the input Anchors to the output.
* Accepts a Lvalue reference.
* @return a shared pointer to the created Anchor
*/
template <typename T,
Expand All @@ -201,40 +130,6 @@ class Anchors {
const std::function<
T(InputType1 &, InputType2 &, InputType3 &, InputType4 &)>
&updater);

/**
* Creates an Anchor from four input Anchors
* @tparam T - type of the output Anchor. `T` should overload the
* equality and output operators if not already defined.
* @tparam InputType1 - optional type of the first input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @tparam InputType2 - optional type of the second input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @tparam InputType3 - optional type of the third input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @tparam InputType4 - optional type of the fourth input Anchor. Required
* only if this type is different from the output Anchor Type T.
* @param anchor1 - first input Anchor.
* @param anchor2 - second input Anchor.
* @param anchor3 - third input Anchor.
* @param anchor4 - fourth input Anchor.
* @param updater - function that maps the input Anchors to the output.
* Accepts a Rvalue reference.
* @return a shared pointer to the created Anchor
*/
template <typename T,
typename InputType1 = T,
typename InputType2 = T,
typename InputType3 = T,
typename InputType4 = T>
static AnchorPtr<T> map4(
const AnchorPtr<InputType1> &anchor1,
const AnchorPtr<InputType2> &anchor2,
const AnchorPtr<InputType3> &anchor3,
const AnchorPtr<InputType4> &anchor4,
const std::function<
T(InputType1 &, InputType2 &, InputType3 &, InputType4 &)>
&&updater);
};

template <typename T>
Expand All @@ -254,13 +149,6 @@ AnchorPtr<T> Anchors::map(
return newAnchor;
}

template <typename T, typename InputType1>
AnchorPtr<T> Anchors::map(
const AnchorPtr<InputType1> &anchor,
const typename Anchor<T, InputType1>::SingleInputUpdater &&updater) {
return map<T, InputType1>(anchor, updater);
}

template <typename T, typename InputType1, typename InputType2>
AnchorPtr<T> Anchors::map2(
const AnchorPtr<InputType1> &anchor1,
Expand All @@ -273,15 +161,6 @@ AnchorPtr<T> Anchors::map2(
return newAnchor;
}

template <typename T, typename InputType1, typename InputType2>
AnchorPtr<T> Anchors::map2(
const AnchorPtr<InputType1> &anchor1,
const AnchorPtr<InputType2> &anchor2,
const typename Anchor<T, InputType1, InputType2>::DualInputUpdater
&&updater) {
return map2<T, InputType1, InputType2>(anchor1, anchor2, updater);
}

template <typename T,
typename InputType1,
typename InputType2,
Expand All @@ -305,20 +184,6 @@ AnchorPtr<T> Anchors::map3(
return map2<T, PairType, InputType3>(anchorOfPair, anchor3, newUpdater);
}

template <typename T,
typename InputType1,
typename InputType2,
typename InputType3>
AnchorPtr<T> Anchors::map3(
const AnchorPtr<InputType1> &anchor1,
const AnchorPtr<InputType2> &anchor2,
const AnchorPtr<InputType3> &anchor3,
const std::function<T(InputType1 &, InputType2 &, InputType3 &)>
&&updater) {
return map3<T, InputType1, InputType2, InputType3>(
anchor1, anchor2, anchor3, updater);
}

template <typename T,
typename InputType1,
typename InputType2,
Expand Down Expand Up @@ -356,21 +221,5 @@ AnchorPtr<T> Anchors::map4(
anchorOfPair1, anchorOfPair2, newUpdater);
}

template <typename T,
typename InputType1,
typename InputType2,
typename InputType3,
typename InputType4>
AnchorPtr<T> Anchors::map4(
const AnchorPtr<InputType1> &anchor1,
const AnchorPtr<InputType2> &anchor2,
const AnchorPtr<InputType3> &anchor3,
const AnchorPtr<InputType4> &anchor4,
const std::function<
T(InputType1 &, InputType2 &, InputType3 &, InputType4 &)> &&updater) {
return map4<T, InputType1, InputType2, InputType3, InputType4>(
anchor1, anchor2, anchor3, anchor4, updater);
}

} // namespace anchors
#endif // ANCHORS_ANCHORS_H
Loading

0 comments on commit 2134e8d

Please sign in to comment.