Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix Compose's domain and some other minor issues in week 11 source #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
77 changes: 67 additions & 10 deletions 10.source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,30 @@ struct Positives : Set
Positives* clone() const override { return new Positives(); }
};

// @TODO Define the sets of positive, nonnegative numbers and sets of intervals
// of the form (a, b)
struct NonNegatives : Set
{
bool check(float x) const override { return x >= 0; }

NonNegatives* clone() const override { return new NonNegatives(); }
};

struct Interval : Set
{
const float a, b;

Interval(const float a, const float b) : a(a), b(b) {}

bool check(float x) const override { return a < x && b > x; }

Interval* clone() const override { return new Interval(*this); }
};

struct TanDomain : Set
{
bool check(float x) const override { return ceilf(x / (M_PI / 2)) != floorf(x / (M_PI / 2)) || (int)(x / (M_PI / 2)) % 2 == 0; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Това не е ли малко дълго като за един ред 😆.
Освен това е доста криптично написано с тези условия - наложи се да го разпиша формално, за да разбера какво прави 😆
Наистина, опитай по-простичко да го изразиш - трябва просто да провериш дали x е от вида ½π + kπ, т.е. дали уравнението ½π + kπ = x има цяло решение за k.
Как да провериш дали k излиза цяло… ще се сетиш сам. Hint: използвай fmod от cmath.

И като работиш с плаваща запетая, е хубаво да допускаш някаква епсилон грешка. Иначе, формално, това е коректно :)


TanDomain* clone() const override { return new TanDomain(); }
};

class RealFunc
{
Expand Down Expand Up @@ -75,13 +97,15 @@ struct Exponent : RealFunc
{
Exponent() : RealFunc{AllReals{}, "exp"} {}

protected:
virtual float evalAt(float x) override { return std::pow(E, x); }
};

struct Log : RealFunc
{
Log() : RealFunc{Positives{}, "log"} {}

protected:
float evalAt(float x) override { return std::log(x); }
};

Expand All @@ -90,6 +114,7 @@ struct BoyanFunction : RealFunc
int n;
int* myBigArr = new int[100]; // Illustration of the need of virtual d-tors

protected:
float evalAt(float x) override
{
n++;
Expand All @@ -110,6 +135,7 @@ struct Compose : RealFunc
{
}

protected:
float evalAt(float x) override
{
return f->safeEval(g->safeEval(x));
Expand All @@ -120,19 +146,27 @@ struct Sin : RealFunc
{
Sin() : RealFunc{AllReals{}, "sin"} {}

protected:
float evalAt(float x) override { return std::sin(x); }
};

// @TODO Define `struct Tan` and carefully construct its domain Set.
struct Tan : RealFunc
{
Tan() : RealFunc{TanDomain{}, "tan"} {}

protected:
float evalAt(float x) override { return std::tan(x); }
};

// @TODO Define `struct Pow` which raises `x` to a power, specified as a
// constructor argument.
struct Pow : RealFunc
{
const float exp;

// @TODO Define `struct Sum` which represents the sum of all functions in a
// given array.
Pow(const float exp) : RealFunc{Positives{}, "pow"}, exp(exp) {}

// @TODO Define global operators `*`, `+`, and `>>` which respectively act as
// multiplication, addition and composition of functions.
protected:
float evalAt(float x) override { return std::pow(x, exp); }
};

struct Sum : public RealFunc
{
Expand All @@ -143,11 +177,29 @@ struct Sum : public RealFunc
{
}

protected:
float evalAt(float x) override { return f->safeEval(x) + g->safeEval(x); }
};

struct Product : public RealFunc
{
RealFunc *f, *g;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хубаво е да са поне const, a най-добре и private - да не вземе някой да бърника :)


Product(RealFunc* f, RealFunc* g)
: RealFunc{Intersect{f->domain, g->domain}, "Product"}, f(f), g(g)
{
}

protected:
float evalAt(float x) override { return f->safeEval(x) * g->safeEval(x); }
};

Product operator*(RealFunc& a, RealFunc& b) { return {&a, &b}; }

Sum operator+(RealFunc& a, RealFunc& b) { return {&a, &b}; }

Compose operator>>(RealFunc& a, RealFunc& b) { return {&a, &b}; }

int main()
{
Log log;
Expand All @@ -160,4 +212,9 @@ int main()

RealFunc* base = &comp;
std::cout << base->safeEval(3) << std::endl;
}

// problem with Compose's defined domain - example
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Добре де, проблем има, а идея за решение 🤔?

Compose comp2{&log, &sin};
base = &comp2;
std::cout << base->safeEval(3 * M_PI / 2) << std::endl;
}
Loading