You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2399 lines
72 KiB
C++
2399 lines
72 KiB
C++
/*------------------------------------------------------------------------------
|
|
* Copyright (c) 2023 by Bai Bing (seread@163.com)
|
|
* See COPYING file for copying and redistribution conditions.
|
|
*
|
|
* Alians IT Studio.
|
|
*----------------------------------------------------------------------------*/
|
|
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <complex>
|
|
#include <functional>
|
|
|
|
#include "core/Error.h"
|
|
#include "core/StaticAsserts.h"
|
|
#include "core/TypeTraits.h"
|
|
#include "utils/EssentiallyEqual.h"
|
|
#include "ASMatrix.h"
|
|
|
|
namespace ais
|
|
{
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator+=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::plus<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator+=(Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](std::complex<dtype> &val1, dtype val2) -> std::complex<dtype>
|
|
{ return val1 + val2; };
|
|
|
|
std::transform(lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator+=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value += rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator+=(Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> &value) -> std::complex<dtype>
|
|
{ return value += rhs; };
|
|
|
|
std::for_each(lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator+(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), std::plus<dtype>());
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator+(const Matrix<dtype> &lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](dtype val1, const std::complex<dtype> &val2) -> std::complex<dtype>
|
|
{ return val1 + val2; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the elements of two arrays (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator+(const Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs + lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator+(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> dtype
|
|
{ return value + rhs; };
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (5)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator+(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs + lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (6)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator+(const Matrix<dtype> &lhs, const std::complex<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> std::complex<dtype>
|
|
{ return value + rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (7)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator+(const std::complex<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs + lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (8)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator+(const Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
|
|
{ return value + rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Adds the scaler to the array (9)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator+(dtype lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
return rhs + lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator-=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::minus<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator-=(Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](std::complex<dtype> &val1, dtype val2) -> std::complex<dtype>
|
|
{ return val1 - val2; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator-=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value -= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator-=(Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> &value) -> std::complex<dtype>
|
|
{ return value -= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator-(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), std::minus<dtype>());
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator-(const Matrix<dtype> &lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](dtype val1, const std::complex<dtype> &val2) -> std::complex<dtype>
|
|
{ return val1 - val2; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the elements of two arrays (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator-(const Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](const std::complex<dtype> &val1, dtype val2) -> std::complex<dtype>
|
|
{ return val1 - val2; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator-(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> dtype
|
|
{ return value - rhs; };
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (5)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator-(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [lhs](dtype value) -> dtype
|
|
{ return lhs - value; };
|
|
|
|
Matrix<dtype> returnArray(rhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (6)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator-(const Matrix<dtype> &lhs, const std::complex<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> std::complex<dtype>
|
|
{ return value - rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (7)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator-(const std::complex<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [lhs](dtype value) -> std::complex<dtype>
|
|
{ return lhs - value; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(rhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (8)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator-(const Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
|
|
{ return value - rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Subtracts the scaler from the array (9)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator-(dtype lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [lhs](std::complex<dtype> value) -> std::complex<dtype>
|
|
{ return lhs - value; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(rhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Negative Operator
|
|
///
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator-(const Matrix<dtype> &inArray)
|
|
{
|
|
const auto function = [](dtype value) -> dtype
|
|
{ return -value; };
|
|
|
|
auto returnArray = Matrix<dtype>(inArray.shape());
|
|
std::transform(std::execution::par_unseq, inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator*=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::multiplies<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator*=(Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](std::complex<dtype> &val1, dtype val2) -> std::complex<dtype>
|
|
{ return val1 * val2; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator*=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value *= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator*=(Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> &value) -> std::complex<dtype>
|
|
{ return value *= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator*(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(),
|
|
lhs.cend(),
|
|
rhs.cbegin(),
|
|
returnArray.begin(),
|
|
std::multiplies<dtype>());
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator*(const Matrix<dtype> &lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](dtype val1, const std::complex<dtype> &val2) -> std::complex<dtype>
|
|
{ return val1 * val2; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the elements of two arrays (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator*(const Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs * lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator*(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> dtype
|
|
{ return value * rhs; };
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (5)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator*(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs * lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (6)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator*(const Matrix<dtype> &lhs, const std::complex<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> std::complex<dtype>
|
|
{ return value * rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (7)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator*(const std::complex<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs * lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (8)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator*(const Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
|
|
{ return value * rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Multiplies the scaler to the array (9)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator*(dtype lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
return rhs * lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator/=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::divides<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator/=(Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](std::complex<dtype> &val1, dtype val2) -> std::complex<dtype>
|
|
{ return val1 / val2; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator/=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value /= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> &operator/=(Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> &value) -> std::complex<dtype>
|
|
{ return value /= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the elements of two arrays (1)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator/(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), std::divides<dtype>());
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the elements of two arrays (2)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator/(const Matrix<dtype> &lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
const auto function = [](dtype val1, const std::complex<dtype> &val2) -> std::complex<dtype>
|
|
{ return val1 / val2; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the elements of two arrays (3)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator/(const Matrix<std::complex<dtype>> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](const std::complex<dtype> &val1, dtype val2) -> std::complex<dtype>
|
|
{ return val1 / val2; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (4)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator/(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> dtype
|
|
{ return value / rhs; };
|
|
|
|
Matrix<dtype> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (5)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator/(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
const auto function = [lhs](dtype value) -> dtype
|
|
{ return lhs / value; };
|
|
|
|
Matrix<dtype> returnArray(rhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (6)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator/(const Matrix<dtype> &lhs, const std::complex<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](dtype value) -> std::complex<dtype>
|
|
{ return value / rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (7)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator/(const std::complex<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [lhs](dtype value) -> std::complex<dtype>
|
|
{ return lhs / value; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(rhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (8)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator/(const Matrix<std::complex<dtype>> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [rhs](std::complex<dtype> value) -> std::complex<dtype>
|
|
{ return value / rhs; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Divides the scaler from the array (9)
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<std::complex<dtype>> operator/(dtype lhs, const Matrix<std::complex<dtype>> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [lhs](std::complex<dtype> value) -> std::complex<dtype>
|
|
{ return lhs / value; };
|
|
|
|
Matrix<std::complex<dtype>> returnArray(rhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, rhs.cbegin(), rhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Modulus the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_integral<dtype>::value, int> = 0>
|
|
AIS_EXPORT Matrix<dtype> &operator%=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::modulus<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Modulus the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_floating_point<dtype>::value, int> = 0>
|
|
AIS_EXPORT Matrix<dtype> &operator%=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](const dtype value1, const dtype value2) -> dtype
|
|
{ return std::fmod(value1, value2); };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Modulus the scaler to the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_integral<dtype>::value, int> = 0>
|
|
AIS_EXPORT Matrix<dtype> &operator%=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value %= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Modulus the scaler to the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_floating_point<dtype>::value, int> = 0>
|
|
AIS_EXPORT Matrix<dtype> &operator%=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
const auto function = [rhs](dtype &value) -> void
|
|
{ value = std::fmod(value, rhs); };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the modulus of the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator%(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray %= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Modulus of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator%(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray %= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Modulus of the scaler and the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_integral<dtype>::value, int> = 0>
|
|
AIS_EXPORT Matrix<dtype> operator%(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
Matrix<dtype> returnArray(rhs.shape());
|
|
std::transform(std::execution::par_unseq, rhs.begin(),
|
|
rhs.end(),
|
|
returnArray.begin(),
|
|
[lhs](dtype value) -> dtype
|
|
{ return lhs % value; });
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Modulus of the scaler and the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype, enable_if_t<std::is_floating_point<dtype>::value, int> = 0>
|
|
AIS_EXPORT Matrix<dtype> operator%(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
Matrix<dtype> returnArray(rhs.shape());
|
|
std::transform(std::execution::par_unseq, rhs.begin(),
|
|
rhs.end(),
|
|
returnArray.begin(),
|
|
[lhs](dtype value) -> dtype
|
|
{ return std::fmod(lhs, value); });
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitwise or the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator|=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::bit_or<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitwise or the scaler to the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator|=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value |= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise or of the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator|(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray |= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise or of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator|(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray |= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise or of the sclar and the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator|(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs | lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitwise and the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator&=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::bit_and<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitwise and the scaler to the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator&=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value &= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise and of the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator&(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray &= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise and of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator&(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray &= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise and of the sclar and the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator&(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs & lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitwise xor the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator^=(Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
std::transform(std::execution::par_unseq, lhs.begin(), lhs.end(), rhs.cbegin(), lhs.begin(), std::bit_xor<dtype>());
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitwise xor the scaler to the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator^=(Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
const auto function = [rhs](dtype &value) -> dtype
|
|
{ return value ^= rhs; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise xor of the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator^(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray ^= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise xor of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator^(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
auto returnArray = Matrix<dtype>(lhs);
|
|
returnArray ^= rhs;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise xor of the sclar and the array
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator^(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs ^ lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the bitwise not of the array
|
|
///
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator~(const Matrix<dtype> &inArray)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
const auto function = [](dtype value) -> dtype
|
|
{ return ~value; };
|
|
|
|
Matrix<dtype> returnArray(inArray.shape());
|
|
|
|
std::transform(std::execution::par_unseq, inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the and of the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator&&(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](dtype value1, dtype value2) -> bool
|
|
{ return value1 && value2; };
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the and of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator&&(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [rhs](dtype value) -> bool
|
|
{ return value && rhs; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the and of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator&&(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs && lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the or of the elements of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator||(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto function = [](dtype value1, dtype value2) -> bool
|
|
{ return value1 || value2; };
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the or of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator||(const Matrix<dtype> &lhs, dtype rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [rhs](dtype value) -> bool
|
|
{ return value || rhs; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the or of the array and the scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator||(dtype lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
return rhs || lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Takes the not of the array
|
|
///
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator!(const Matrix<dtype> &inArray)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
Matrix<bool> returnArray(inArray.shape());
|
|
|
|
const auto function = [](dtype value) -> dtype
|
|
{ return !value; };
|
|
|
|
std::transform(std::execution::par_unseq, inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator==(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto equalTo = [](dtype lhs, dtype rhs) noexcept -> bool
|
|
{ return utils::essentially_equal(lhs, rhs); };
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), equalTo);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// an array and a scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param inValue
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator==(const Matrix<dtype> &lhs, dtype inValue)
|
|
{
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto equalTo = [inValue](dtype value) noexcept -> bool
|
|
{ return utils::essentially_equal(inValue, value); };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), equalTo);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// an array and a scaler
|
|
///
|
|
/// @param inValue
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator==(dtype inValue, const Matrix<dtype> &inArray)
|
|
{
|
|
return inArray == inValue;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator!=(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
const auto notEqualTo = [](dtype lhs, dtype rhs) noexcept -> bool
|
|
{ return !utils::essentially_equal(lhs, rhs); };
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), notEqualTo);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// an array and a scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param inValue
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator!=(const Matrix<dtype> &lhs, dtype inValue)
|
|
{
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto notEqualTo = [inValue](dtype value) noexcept -> bool
|
|
{ return !utils::essentially_equal(inValue, value); };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), notEqualTo);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// an array and a scaler
|
|
///
|
|
/// @param inValue
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator!=(dtype inValue, const Matrix<dtype> &inArray)
|
|
{
|
|
return inArray != inValue;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator<(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
|
|
{ return lhs < rhs; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param inValue
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator<(const Matrix<dtype> &lhs, dtype inValue)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return value < inValue; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param inValue
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator<(dtype inValue, const Matrix<dtype> &inArray)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(inArray.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return inValue < value; };
|
|
|
|
std::transform(std::execution::par_unseq, inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator>(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
|
|
{ return lhs > rhs; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param inValue
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator>(const Matrix<dtype> &lhs, dtype inValue)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return value > inValue; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param inValue
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator>(dtype inValue, const Matrix<dtype> &inArray)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(inArray.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return inValue > value; };
|
|
|
|
std::transform(std::execution::par_unseq, inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator<=(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
|
|
{ return lhs <= rhs; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param inValue
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator<=(const Matrix<dtype> &lhs, dtype inValue)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return value <= inValue; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param inValue
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator<=(dtype inValue, const Matrix<dtype> &inArray)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(inArray.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return inValue <= value; };
|
|
|
|
std::transform(std::execution::par_unseq, inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// of two arrays
|
|
///
|
|
/// @param lhs
|
|
/// @param rhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator>=(const Matrix<dtype> &lhs, const Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
if (lhs.shape() != rhs.shape())
|
|
{
|
|
THROW_INVALID_ARGUMENT("Array dimensions do not match.");
|
|
}
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [](dtype lhs, dtype rhs) noexcept -> bool
|
|
{ return lhs >= rhs; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), rhs.cbegin(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param lhs
|
|
/// @param inValue
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator>=(const Matrix<dtype> &lhs, dtype inValue)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(lhs.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return value >= inValue; };
|
|
|
|
std::transform(std::execution::par_unseq, lhs.cbegin(), lhs.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Returns an array of booleans of element wise comparison
|
|
/// the array and a scaler
|
|
///
|
|
/// @param inValue
|
|
/// @param inArray
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<bool> operator>=(dtype inValue, const Matrix<dtype> &inArray)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
Matrix<bool> returnArray(inArray.shape());
|
|
|
|
const auto function = [inValue](dtype value) noexcept -> bool
|
|
{ return inValue >= value; };
|
|
|
|
std::transform(std::execution::par_unseq, inArray.cbegin(), inArray.cend(), returnArray.begin(), function);
|
|
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitshifts left the elements of the array
|
|
///
|
|
/// @param lhs
|
|
/// @param inNumBits
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator<<=(Matrix<dtype> &lhs, uint8_t inNumBits)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
const auto function = [inNumBits](dtype &value) -> void
|
|
{ value <<= inNumBits; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitshifts left the elements of the array
|
|
///
|
|
/// @param lhs
|
|
/// @param inNumBits
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator<<(const Matrix<dtype> &lhs, uint8_t inNumBits)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
Matrix<dtype> returnArray(lhs);
|
|
returnArray <<= inNumBits;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitshifts right the elements of the array
|
|
///
|
|
/// @param lhs
|
|
/// @param inNumBits
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator>>=(Matrix<dtype> &lhs, uint8_t inNumBits)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
const auto function = [inNumBits](dtype &value) -> void
|
|
{ value >>= inNumBits; };
|
|
|
|
std::for_each(std::execution::par_unseq, lhs.begin(), lhs.end(), function);
|
|
|
|
return lhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// Bitshifts right the elements of the array
|
|
///
|
|
/// @param lhs
|
|
/// @param inNumBits
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator>>(const Matrix<dtype> &lhs, uint8_t inNumBits)
|
|
{
|
|
STATIC_ASSERT_INTEGER(dtype);
|
|
|
|
Matrix<dtype> returnArray(lhs);
|
|
returnArray >>= inNumBits;
|
|
return returnArray;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// prefix incraments the elements of an array
|
|
///
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator++(Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [](dtype &value) -> void
|
|
{ ++value; };
|
|
|
|
std::for_each(std::execution::par_unseq, rhs.begin(), rhs.end(), function);
|
|
|
|
return rhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// postfix increments the elements of an array
|
|
///
|
|
/// @param lhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator++(Matrix<dtype> &lhs, int)
|
|
{
|
|
auto copy = Matrix<dtype>(lhs);
|
|
++lhs;
|
|
return copy;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// prefix decrements the elements of an array
|
|
///
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> &operator--(Matrix<dtype> &rhs)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC(dtype);
|
|
|
|
const auto function = [](dtype &value) -> void
|
|
{ --value; };
|
|
|
|
std::for_each(std::execution::par_unseq, rhs.begin(), rhs.end(), function);
|
|
|
|
return rhs;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// postfix decrements the elements of an array
|
|
///
|
|
/// @param lhs
|
|
/// @return Matrix
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT Matrix<dtype> operator--(Matrix<dtype> &lhs, int)
|
|
{
|
|
auto copy = Matrix<dtype>(lhs);
|
|
--lhs;
|
|
return copy;
|
|
}
|
|
|
|
//============================================================================
|
|
// Method Description:
|
|
/// io operator for the Matrix class
|
|
///
|
|
/// @param inOStream
|
|
/// @param inArray
|
|
/// @return std::ostream
|
|
///
|
|
template <typename dtype>
|
|
AIS_EXPORT std::ostream &operator<<(std::ostream &inOStream, const Matrix<dtype> &inArray)
|
|
{
|
|
STATIC_ASSERT_ARITHMETIC_OR_COMPLEX(dtype);
|
|
|
|
inOStream << inArray.str();
|
|
return inOStream;
|
|
}
|
|
} // namespace ais
|