-
Notifications
You must be signed in to change notification settings - Fork 4k
ARROW-13345: [C++] Add basic implementation for log to base b #10898
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
Changes from all commits
43d807a
2946998
ca7bd10
8804fa6
756126f
a40d27d
f5713cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -229,6 +229,16 @@ class TestBinaryArithmetic : public TestBase { | |||
| AssertBinop(func, lhs, right, expected); | ||||
| } | ||||
|
|
||||
| // (Array, Scalar) => Array | ||||
| void AssertBinop(BinaryFunction func, const std::string& lhs, | ||||
| const std::shared_ptr<Scalar>& right, | ||||
| const std::shared_ptr<Array>& expected) { | ||||
| auto left = ArrayFromJSON(type_singleton(), lhs); | ||||
|
|
||||
| ASSERT_OK_AND_ASSIGN(auto actual, func(left, right, options_, nullptr)); | ||||
| ValidateAndAssertApproxEqual(actual.make_array(), expected); | ||||
| } | ||||
|
|
||||
| // (Array, Scalar) | ||||
| void AssertBinop(BinaryFunction func, const std::string& lhs, | ||||
| const std::shared_ptr<Scalar>& right, const std::string& expected) { | ||||
|
|
@@ -248,6 +258,15 @@ class TestBinaryArithmetic : public TestBase { | |||
| AssertBinop(func, left, right, expected); | ||||
| } | ||||
|
|
||||
| // (Array, Array) => Array | ||||
| void AssertBinop(BinaryFunction func, const std::string& lhs, const std::string& rhs, | ||||
| const std::shared_ptr<Array>& expected) { | ||||
| auto left = ArrayFromJSON(type_singleton(), lhs); | ||||
| auto right = ArrayFromJSON(type_singleton(), rhs); | ||||
|
|
||||
| AssertBinop(func, left, right, expected); | ||||
| } | ||||
|
|
||||
| // (Array, Array) | ||||
| void AssertBinop(BinaryFunction func, const std::shared_ptr<Array>& left, | ||||
| const std::shared_ptr<Array>& right, | ||||
|
|
@@ -2001,6 +2020,72 @@ TYPED_TEST(TestUnaryArithmeticIntegral, Log) { | |||
| } | ||||
| } | ||||
|
|
||||
| TYPED_TEST(TestBinaryArithmeticIntegral, Log) { | ||||
| // Integer arguments promoted to double, sanity check here | ||||
| this->AssertBinop(Logb, "[1, 10, null]", "[10, 10, null]", | ||||
| ArrayFromJSON(float64(), "[0, 1, null]")); | ||||
| this->AssertBinop(Logb, "[1, 2, null]", "[2, 2, null]", | ||||
| ArrayFromJSON(float64(), "[0, 1, null]")); | ||||
| this->AssertBinop(Logb, "[10, 100, null]", this->MakeScalar(10), | ||||
| ArrayFromJSON(float64(), "[1, 2, null]")); | ||||
| } | ||||
|
|
||||
| TYPED_TEST(TestBinaryArithmeticFloating, Log) { | ||||
| using CType = typename TestFixture::CType; | ||||
| this->SetNansEqual(true); | ||||
| auto min_val = std::numeric_limits<CType>::min(); | ||||
| auto max_val = std::numeric_limits<CType>::max(); | ||||
| for (auto check_overflow : {false, true}) { | ||||
| this->SetOverflowCheck(check_overflow); | ||||
| // N.B. min() for float types is smallest normal number > 0 | ||||
| this->AssertBinop(Logb, "[1, 10, null, NaN, Inf]", "[100, 10, null, 2, 10]", | ||||
| "[0, 1, null, NaN, Inf]"); | ||||
| this->AssertBinop(Logb, min_val, 10, | ||||
| static_cast<CType>(std::log(min_val) / std::log(10))); | ||||
| this->AssertBinop(Logb, max_val, 10, | ||||
| static_cast<CType>(std::log(max_val) / std::log(10))); | ||||
| } | ||||
| this->AssertBinop(Logb, "[1.0, 10.0, null]", "[10.0, 10.0, null]", "[0.0, 1.0, null]"); | ||||
| this->AssertBinop(Logb, "[1.0, 2.0, null]", "[2.0, 2.0, null]", "[0.0, 1.0, null]"); | ||||
| this->AssertBinop(Logb, "[10.0, 100.0, 1000.0, null]", this->MakeScalar(10), | ||||
| "[1.0, 2.0, 3.0, null]"); | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also test what happens on Log of NaN, Inf, and -Inf. We should also check the error cases below here, with both check_overflow = true and check_overflow = false. Or really, it should look similar to the tests for the unary log functions here:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. More unit tests were added. |
||||
| this->SetOverflowCheck(false); | ||||
| this->AssertBinop(Logb, "[-Inf, -1, 0, Inf]", this->MakeScalar(10), | ||||
| "[NaN, NaN, -Inf, Inf]"); | ||||
| this->AssertBinop(Logb, "[-Inf, -1, 0, Inf]", this->MakeScalar(2), | ||||
| "[NaN, NaN, -Inf, Inf]"); | ||||
| this->AssertBinop(Logb, "[-Inf, -1, 0, Inf]", "[2, 10, 0, 0]", "[NaN, NaN, NaN, NaN]"); | ||||
| this->AssertBinop(Logb, "[-Inf, -1, 0, Inf]", this->MakeScalar(0), | ||||
| "[NaN, NaN, NaN, NaN]"); | ||||
| this->AssertBinop(Logb, "[-Inf, -2, -1, Inf]", this->MakeScalar(2), | ||||
| "[NaN, NaN, NaN, Inf]"); | ||||
| this->SetOverflowCheck(true); | ||||
| this->AssertBinopRaises(Logb, "[0]", "[2]", "logarithm of zero"); | ||||
| this->AssertBinopRaises(Logb, "[-1]", "[2]", "logarithm of negative number"); | ||||
| this->AssertBinopRaises(Logb, "[-Inf]", "[2]", "logarithm of negative number"); | ||||
| } | ||||
|
|
||||
| TYPED_TEST(TestBinaryArithmeticSigned, Log) { | ||||
| // Integer arguments promoted to double, sanity check here | ||||
| this->SetNansEqual(true); | ||||
| this->SetOverflowCheck(false); | ||||
| this->AssertBinop(Logb, "[-1, 0]", this->MakeScalar(10), | ||||
| ArrayFromJSON(float64(), "[NaN, -Inf]")); | ||||
| this->AssertBinop(Logb, "[-1, 0]", this->MakeScalar(2), | ||||
| ArrayFromJSON(float64(), "[NaN, -Inf]")); | ||||
| this->AssertBinop(Logb, "[10, 100]", this->MakeScalar(-1), | ||||
| ArrayFromJSON(float64(), "[NaN, NaN]")); | ||||
| this->AssertBinop(Logb, "[-1, 0, null]", this->MakeScalar(-1), | ||||
| ArrayFromJSON(float64(), "[NaN, NaN, null]")); | ||||
| this->AssertBinop(Logb, "[10, 100]", this->MakeScalar(0), | ||||
| ArrayFromJSON(float64(), "[0, 0]")); | ||||
| this->SetOverflowCheck(true); | ||||
| this->AssertBinopRaises(Logb, "[0]", "[10]", "logarithm of zero"); | ||||
| this->AssertBinopRaises(Logb, "[-1]", "[10]", "logarithm of negative number"); | ||||
| this->AssertBinopRaises(Logb, "[10]", "[0]", "logarithm of zero"); | ||||
| this->AssertBinopRaises(Logb, "[100]", "[-1]", "logarithm of negative number"); | ||||
| } | ||||
|
|
||||
| TYPED_TEST(TestUnaryArithmeticSigned, Log) { | ||||
| // Integer arguments promoted to double, sanity check here | ||||
| this->SetNansEqual(true); | ||||
|
|
||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this line is redundant now (ty is never integer). I had filed ARROW-13361 to clean this up.