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
13 changes: 6 additions & 7 deletions python/src/core/functions/analytic/codac2_py_AnalyticFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,28 +154,27 @@ using namespace pybind11::literals;

inline FunctionArgsList create_FunctionArgsList(const std::vector<py::object>& l)
{
FunctionArgsList args {};
std::vector<std::shared_ptr<VarBase>> v_args;
Index i = 0;

for(const auto& li : l)
{
i++;

if(py::isinstance<ScalarVar>(li))
args.push_back(li.cast<ScalarVar>().arg_copy());
v_args.push_back(li.cast<ScalarVar>().arg_copy());

else if(py::isinstance<VectorVar>(li))
args.push_back(li.cast<VectorVar>().arg_copy());
v_args.push_back(li.cast<VectorVar>().arg_copy());

else if(py::isinstance<MatrixVar>(li))
args.push_back(li.cast<MatrixVar>().arg_copy());
v_args.push_back(li.cast<MatrixVar>().arg_copy());

else
throw std::invalid_argument("Argument " + std::to_string(i) + " is invalid. Only variables are accepted.");
}

args.compute_unique_arg_names();
return args;

return { v_args };
}

template<typename T>
Expand Down
22 changes: 16 additions & 6 deletions src/core/functions/analytic/codac2_AnalyticExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,27 @@ namespace codac2
auto& p = v[unique_id()];

if(!p)
{
p = std::make_shared<T>(x);
else
*std::dynamic_pointer_cast<T>(p) = x;
return *static_cast<T*>(p.get());
}

return x;
else
{
auto pt = std::dynamic_pointer_cast<T>(p);
assert(pt && "Type mismatch in ValuesMap for this ExprID");
*pt = x;
return *pt;
}
}

T& value(ValuesMap& v) const
{
assert(v.find(unique_id()) != v.end() && "argument cannot be found");
return *std::dynamic_pointer_cast<T>(v[unique_id()]);
auto it = v.find(unique_id());
assert(it != v.end() && "argument cannot be found");
auto p = std::dynamic_pointer_cast<T>(it->second);
assert(p && "Type mismatch in ValuesMap for this ExprID");
return *p;
}

virtual bool belongs_to_args_list(const FunctionArgsList& args) const = 0;
Expand Down Expand Up @@ -132,7 +142,7 @@ namespace codac2
{
bool b = true;

std::apply([&b,args](auto &&... x)
std::apply([&b,&args](auto &&... x)
{
((b &= x->belongs_to_args_list(args)), ...);
}, this->_x);
Expand Down
4 changes: 2 additions & 2 deletions src/core/functions/analytic/codac2_AnalyticFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ namespace codac2
// If the centered form is not available for this expression...
if(x_.da.size() == 0 // .. because some parts have not yet been implemented,
|| !x_.def_domain) // .. or due to restrictions in the derivative definition domain
return eval(EvalMode::NATURAL, x...);
return x_.a; // natural evaluation

else
{
Expand Down Expand Up @@ -311,7 +311,7 @@ namespace codac2
else
{
fill_from_args(v, x...);
return this->expr()->fwd_eval(v, cart_prod(x...).size(), NATURAL_EVAL); // todo: improve size computation
return this->expr()->fwd_eval(v, this->input_size(), NATURAL_EVAL);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/functions/codac2_ExprBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
using namespace std;
using namespace codac2;

Index ExprID::_id_counter = 0;
std::atomic<Index> ExprID::_id_counter{0};

ExprID::ExprID()
: _id(ExprID::_id_counter)
: _id(ExprID::_id_counter.fetch_add(1, std::memory_order_relaxed))
{
ExprID::_id_counter ++;
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/functions/codac2_ExprBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <memory>
#include <cassert>
#include <utility>
#include <atomic>
#include "codac2_Domain.h"
#include "codac2_Index.h"

Expand Down Expand Up @@ -70,7 +71,7 @@ namespace codac2
protected:

const Index _id; //!< unique identifier, cannot be modified after initialization
static Index _id_counter; //!< static counter used to generate unique IDs for each ``ExprID`` object
static std::atomic<Index> _id_counter; //!< thread-safe counter used to generate unique IDs
};

/**
Expand Down
47 changes: 39 additions & 8 deletions src/core/functions/codac2_FunctionArgsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,36 @@ namespace codac2
* \class FunctionArgsList
* \brief A container class to manage a collection of function arguments.
*/
class FunctionArgsList : public std::vector<std::shared_ptr<VarBase>>
class FunctionArgsList : private std::vector<std::shared_ptr<VarBase>>
{
using base = std::vector<std::shared_ptr<VarBase>>;

public:

// Expose only selected const (read-only) members of the underlying
// std::vector via `using` to keep iteration/access convenient.
// Mutating operations (push_back/insert/erase/...) are intentionally
// not exposed in order to keep consistency with the _total_args_size value.

using base::size;
using base::empty;
using base::cbegin;
using base::cend;
using base::crbegin;
using base::crend;

const std::shared_ptr<VarBase>& operator[](std::size_t i) const { return base::operator[](i); }
const std::shared_ptr<VarBase>& at(std::size_t i) const { return base::at(i); }

base::const_iterator begin() const noexcept { return base::begin(); }
base::const_iterator end() const noexcept { return base::end(); }

public:

/**
* \brief Default constructor. It creates an empty list of arguments.
*/
FunctionArgsList()
{ }
FunctionArgsList() = default;

/**
* \brief Copy constructor.
Expand All @@ -43,7 +64,7 @@ namespace codac2
{
size_t i = 0;
for(const auto& arg : args)
(*this)[i++] = arg->arg_copy();
base::operator[](i++) = arg->arg_copy();
compute_unique_arg_names();
}

Expand Down Expand Up @@ -74,6 +95,12 @@ namespace codac2
compute_unique_arg_names();
}

FunctionArgsList(const std::vector<std::shared_ptr<VarBase>>& args)
: std::vector<std::shared_ptr<VarBase>>(args)
{
compute_unique_arg_names();
}

/**
* \brief Calculates the total size of the function arguments,
* as the sum of the sizes of each argument.
Expand All @@ -82,21 +109,23 @@ namespace codac2
*/
Index total_size() const
{
Index n = 0;
for(const auto& ai : *this)
n += ai->size();
return n;
return _total_args_size;
}

protected:

void compute_unique_arg_names()
{
std::list<std::string> var_names;
for(const auto& arg : *this)
var_names.push_back(arg->name());

_total_args_size = 0;

int i = 23; // default first variable is x, then y,z, then starting from a...
for(auto& arg : *this)
{
_total_args_size += arg->size();
if(arg->name() == "?")
{
std::string new_name;
Expand All @@ -107,5 +136,7 @@ namespace codac2
}
}
}

Index _total_args_size = 0;
};
}
6 changes: 3 additions & 3 deletions src/core/functions/set/codac2_SetExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace codac2
{
bool b = true;

std::apply([&b,args](auto &&... x)
std::apply([&b,&args](auto &&... x)
{
((b &= x->belongs_to_args_list(args)), ...);
}, this->_x);
Expand All @@ -71,7 +71,7 @@ namespace codac2
std::shared_ptr<CtcBase<IntervalVector>> create_ctc(const FunctionArgsList& args, const std::vector<std::shared_ptr<CtcBase<IntervalVector>>>& values) const
{
return std::apply(
[this,values,args](auto &&... x)
[this,&values,&args](auto &&... x)
{
return C::create_ctc(x->create_ctc(args,values)...);
},
Expand All @@ -81,7 +81,7 @@ namespace codac2
std::shared_ptr<SepBase> create_sep(const FunctionArgsList& args, const std::vector<std::shared_ptr<SepBase>>& values) const
{
return std::apply(
[this,values,args](auto &&... x)
[this,&values,&args](auto &&... x)
{
return C::create_sep(x->create_sep(args,values)...);
},
Expand Down