Skip to content

Commit 9c78656

Browse files
committed
implement unary pos FExpr
1 parent 680ba1c commit 9c78656

File tree

8 files changed

+228
-23
lines changed

8 files changed

+228
-23
lines changed

src/core/expr/fexpr.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,11 @@ oobj PyFExpr::m__getitem__(py::robj item) {
172172

173173
//----- Basic arithmetics ------------------------------------------------------
174174

175-
static oobj make_unexpr(dt::expr::Op op, const PyObject* self) {
176-
return robj(Expr_Type).call({
177-
oint(static_cast<int>(op)),
178-
otuple{oobj(self)}});
179-
}
175+
// static oobj make_unexpr(dt::expr::Op op, const PyObject* self) {
176+
// return robj(Expr_Type).call({
177+
// oint(static_cast<int>(op)),
178+
// otuple{oobj(self)}});
179+
// }
180180

181181
static oobj make_binexpr(dt::expr::Op op, robj lhs, robj rhs) {
182182
return robj(Expr_Type).call({
@@ -219,13 +219,13 @@ bool PyFExpr::nb__bool__() {
219219
// return make_unexpr(dt::expr::Op::UINVERT, this);
220220
// }
221221

222-
oobj PyFExpr::nb__neg__() {
223-
return make_unexpr(dt::expr::Op::UMINUS, this);
224-
}
222+
// oobj PyFExpr::nb__neg__() {
223+
// return make_unexpr(dt::expr::Op::UMINUS, this);
224+
// }
225225

226-
oobj PyFExpr::nb__pos__() {
227-
return make_unexpr(dt::expr::Op::UPLUS, this);
228-
}
226+
// oobj PyFExpr::nb__pos__() {
227+
// return make_unexpr(dt::expr::Op::UPLUS, this);
228+
// }
229229

230230

231231

src/core/expr/fexpr.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ class PyFExpr : public py::XObject<PyFExpr> {
164164
static py::oobj nb__mul__ (py::robj, py::robj);
165165
static py::oobj nb__floordiv__(py::robj, py::robj);
166166
static py::oobj nb__invert__ (py::robj);
167+
static py::oobj nb__neg__ (py::robj);
168+
static py::oobj nb__pos__ (py::robj);
167169
static py::oobj nb__truediv__ (py::robj, py::robj);
168170
static py::oobj nb__mod__ (py::robj, py::robj);
169171
static py::oobj nb__pow__ (py::robj, py::robj, py::robj);
@@ -174,8 +176,8 @@ class PyFExpr : public py::XObject<PyFExpr> {
174176
static py::oobj nb__rshift__ (py::robj, py::robj);
175177
bool nb__bool__();
176178
//py::oobj nb__invert__();
177-
py::oobj nb__neg__();
178-
py::oobj nb__pos__();
179+
//py::oobj nb__neg__();
180+
//py::oobj nb__pos__();
179181

180182
py::oobj len(); // [DEPRECATED]
181183
py::oobj re_match(const py::XArgs&); // [DEPRECATED]

src/core/expr/funary/umaker.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ umaker_ptr resolve_op(Op opcode, SType stype)
6262
switch (opcode) {
6363
// Basic
6464
case Op::UPLUS: return resolve_op_uplus(stype);
65-
case Op::UMINUS: return resolve_op_uminus(stype);
65+
//case Op::UMINUS: return resolve_op_uminus(stype);
6666
//case Op::UINVERT: return resolve_op_uinvert(stype);
6767

6868
// Math: trigonometric

src/core/expr/funary/umaker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ umaker_ptr resolve_op(Op, SType);
8383

8484
// Basic
8585
umaker_ptr resolve_op_uplus(SType);
86-
umaker_ptr resolve_op_uminus(SType);
86+
//umaker_ptr resolve_op_uminus(SType);
8787
//umaker_ptr resolve_op_uinvert(SType);
8888

8989
// Trigonometric

src/core/expr/funary/uinvert.cc renamed to src/core/expr/funary/unary_invert.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,8 @@
2121
//------------------------------------------------------------------------------
2222
#include "column/const.h"
2323
#include "column/func_unary.h"
24-
#include "column/isna.h"
2524
#include "expr/fexpr_column.h"
26-
#include "documentation.h"
2725
#include "expr/fexpr_func_unary.h"
28-
#include "expr/eval_context.h"
29-
#include "expr/workframe.h"
3026
#include "python/xargs.h"
3127
#include "stype.h"
3228
namespace dt {
@@ -50,7 +46,12 @@ class FExpr_UInvert : public FExpr_FuncUnary {
5046
static inline int8_t op_invert_bool(int8_t x) {
5147
return !x;
5248
}
53-
49+
/**
50+
* Unary operator `~` acts as logical NOT on a boolean column,
51+
* and as a bitwise inverse on integer columns. Integer promotions
52+
* are not applied. The operator is not applicable to floating-point
53+
* or string columns.
54+
*/
5455
Column evaluate1(Column&& col) const override{
5556
SType stype = col.stype();
5657

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//------------------------------------------------------------------------------
2+
// Copyright 2022-2023 H2O.ai
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a
5+
// copy of this software and associated documentation files (the "Software"),
6+
// to deal in the Software without restriction, including without limitation
7+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
// and/or sell copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in
12+
// all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20+
// IN THE SOFTWARE.
21+
//------------------------------------------------------------------------------
22+
#include "column/const.h"
23+
#include "column/func_unary.h"
24+
#include "expr/fexpr_column.h"
25+
#include "expr/fexpr_func_unary.h"
26+
#include "expr/eval_context.h"
27+
#include "expr/workframe.h"
28+
#include "expr/fexpr.h"
29+
#include "python/xargs.h"
30+
#include "stype.h"
31+
#include <iostream>
32+
namespace dt {
33+
namespace expr {
34+
35+
36+
class FExpr_UnaryMinus : public FExpr_FuncUnary {
37+
public:
38+
using FExpr_FuncUnary::FExpr_FuncUnary;
39+
40+
41+
std::string name() const override {
42+
return "uminus";
43+
}
44+
45+
template <typename T>
46+
static inline T op_minus(T x) {
47+
return -x;
48+
}
49+
/**
50+
* Unary operator `+` upcasts each numeric column to INT32, but
51+
* otherwise keeps unmodified. The operator cannot be applied to
52+
* string columns.
53+
*/
54+
Column evaluate1(Column&& col) const override{
55+
SType stype = col.stype();
56+
57+
switch (stype) {
58+
case SType::VOID:
59+
return Column(new ConstNa_ColumnImpl(col.nrows(), SType::VOID));
60+
case SType::BOOL:
61+
case SType::INT8:
62+
case SType::INT16:
63+
col.cast_inplace(SType::INT32);
64+
return Column(new FuncUnary1_ColumnImpl<int32_t, int32_t>(
65+
std::move(col), op_minus<int32_t>, col.nrows(), SType::INT32
66+
));
67+
case SType::INT32:
68+
return Column(new FuncUnary1_ColumnImpl<int32_t, int32_t>(
69+
std::move(col), op_minus<int32_t>, col.nrows(), SType::INT32
70+
));
71+
case SType::INT64:
72+
return Column(new FuncUnary1_ColumnImpl<int64_t, int64_t>(
73+
std::move(col), op_minus<int64_t>, col.nrows(), SType::INT64
74+
));
75+
case SType::FLOAT32:
76+
return Column(new FuncUnary1_ColumnImpl<float, float>(
77+
std::move(col), op_minus<float>, col.nrows(), SType::FLOAT32
78+
));
79+
case SType::FLOAT64:
80+
return Column(new FuncUnary1_ColumnImpl<double, double>(
81+
std::move(col), op_minus<double>, col.nrows(), SType::FLOAT64
82+
));
83+
default:
84+
throw TypeError() << "Cannot apply unary `operator -` to a column with "
85+
"stype `" << stype << "`";
86+
}
87+
}
88+
};
89+
90+
91+
// gets the count of all rows - nulls are not checked
92+
class FExpr_UnaryMinus_Node : public FExpr_Func {
93+
private:
94+
ptrExpr arg_;
95+
public:
96+
FExpr_UnaryMinus_Node(ptrExpr &&arg)
97+
: arg_(std::move(arg))
98+
{}
99+
100+
std::string repr() const override {
101+
std::string out = "uminus";
102+
out += '(';
103+
out += arg_->repr();
104+
out += ')';
105+
return out;
106+
}
107+
108+
Workframe evaluate_n(EvalContext &ctx) const override {
109+
Workframe wf(ctx);
110+
111+
return wf;
112+
}
113+
114+
};
115+
116+
py::oobj PyFExpr::nb__neg__(py::robj src) {
117+
std::cout<<src.is_by_node()<<std::endl;
118+
std::cout<<src.is_sort_node()<<std::endl;
119+
if (src.is_by_node()){
120+
return PyFExpr::make(
121+
new FExpr_UnaryMinus_Node(as_fexpr(src)));
122+
123+
}
124+
125+
return PyFExpr::make(
126+
new FExpr_UnaryMinus(as_fexpr(src)));
127+
}
128+
129+
}} // dt::expr

src/core/expr/funary/unary_plus.cc

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//------------------------------------------------------------------------------
2+
// Copyright 2022-2023 H2O.ai
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a
5+
// copy of this software and associated documentation files (the "Software"),
6+
// to deal in the Software without restriction, including without limitation
7+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
// and/or sell copies of the Software, and to permit persons to whom the
9+
// Software is furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in
12+
// all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20+
// IN THE SOFTWARE.
21+
//------------------------------------------------------------------------------
22+
#include "column/const.h"
23+
#include "expr/fexpr_column.h"
24+
#include "expr/fexpr_func_unary.h"
25+
#include "python/xargs.h"
26+
#include "stype.h"
27+
namespace dt {
28+
namespace expr {
29+
30+
31+
class FExpr_UPlus : public FExpr_FuncUnary {
32+
public:
33+
using FExpr_FuncUnary::FExpr_FuncUnary;
34+
35+
36+
std::string name() const override {
37+
return "uplus";
38+
}
39+
/**
40+
* Unary operator `+` upcasts each numeric column to INT32, but
41+
* otherwise keeps unmodified. The operator cannot be applied to
42+
* string columns.
43+
*/
44+
Column evaluate1(Column&& col) const override{
45+
SType stype = col.stype();
46+
47+
switch (stype) {
48+
case SType::VOID:
49+
return Column(new ConstNa_ColumnImpl(col.nrows(), SType::VOID));
50+
case SType::BOOL:
51+
case SType::INT8:
52+
case SType::INT16:
53+
col.cast_inplace(SType::INT32);
54+
return std::move(col);
55+
case SType::INT32:
56+
case SType::INT64:
57+
case SType::FLOAT32:
58+
case SType::FLOAT64:
59+
return std::move(col);
60+
61+
default:
62+
throw TypeError() << "Cannot apply unary `operator +` to a column with "
63+
"stype `" << stype << "`";
64+
}
65+
}
66+
};
67+
68+
py::oobj PyFExpr::nb__pos__(py::robj src) {
69+
return PyFExpr::make(
70+
new FExpr_UPlus(as_fexpr(src)));
71+
}
72+
73+
}} // dt::expr

src/core/python/xobject.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -774,12 +774,12 @@ PyObject* _safe_cmp(PyObject* x, PyObject* y, int op) noexcept {
774774
*/
775775

776776
#define METHOD__NEG__(METH) \
777-
py::_safe_unary<CLASS_OF(METH), METH, dt::CallLogger::Op::__neg__>, \
777+
py::_safe_uunary<METH, dt::CallLogger::Op::__neg__>, \
778778
py::XTypeMaker::nb_negative_tag
779779

780780

781781
#define METHOD__POS__(METH) \
782-
py::_safe_unary<CLASS_OF(METH), METH, dt::CallLogger::Op::__pos__>, \
782+
py::_safe_uunary<METH, dt::CallLogger::Op::__pos__>, \
783783
py::XTypeMaker::nb_positive_tag
784784

785785

@@ -789,7 +789,7 @@ PyObject* _safe_cmp(PyObject* x, PyObject* y, int op) noexcept {
789789

790790

791791
#define METHOD__INVERT__(METH) \
792-
py::_safe_uunary<METH, dt::CallLogger::Op::__invert__>, \
792+
py::_safe_uunary<METH, dt::CallLogger::Op::__invert__>, \
793793
py::XTypeMaker::nb_invert_tag
794794

795795

0 commit comments

Comments
 (0)