First draft of vector class is ready, not done with the module test in main.cpp
This commit is contained in:
+207
-48
@@ -52,8 +52,9 @@ public:
|
||||
if (v.size() != a.size()) {
|
||||
return false;
|
||||
}
|
||||
const static T eps = static_cast<T>(1e-6); // tweak if you like
|
||||
for (uint64_t i = 0; i < v.size(); ++i) {
|
||||
if (v[i] != a[i]) {
|
||||
if (std::fabs(v[i] - a[i]) > eps) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -67,9 +68,10 @@ public:
|
||||
//##################################################
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
void inplace_add(const U a){
|
||||
const T a_hat = static_cast<T>(a);
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] += a;
|
||||
v[i] += a_hat;
|
||||
}
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
@@ -82,6 +84,10 @@ public:
|
||||
Vector<T> operator+(const U a) const {
|
||||
return add(a);
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
friend Vector<T> operator+(U a, const Vector<T>& b) {
|
||||
return b + a;
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T>& operator+=(const U a) {
|
||||
inplace_add(a);
|
||||
@@ -112,92 +118,259 @@ public:
|
||||
return *this;
|
||||
}
|
||||
//##################################################
|
||||
//# VECTOR: Scalar Subtract #
|
||||
//##################################################
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
void inplace_subtract(const U a){
|
||||
const T a_hat = static_cast<T>(a);
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] -= a_hat;
|
||||
}
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> subtract(const U a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_subtract(a);
|
||||
return result;
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> operator-(const U a) const {
|
||||
return subtract(a);
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T>& operator-=(const U a) {
|
||||
inplace_subtract(a);
|
||||
return *this;
|
||||
}
|
||||
//##################################################
|
||||
//# VECTOR: Vector Subtract #
|
||||
//##################################################
|
||||
void inplace_vec_subtract(const Vector<T>& a){
|
||||
void inplace_subtract(const Vector<T>& a){
|
||||
if (a.size() != v.size()){
|
||||
throw std::runtime_error("utill:Vector.inplace_vec_subtract -> Dimensions does not fit");
|
||||
throw std::runtime_error("utill:Vector.inplace_subtract -> Dimensions does not fit");
|
||||
}
|
||||
|
||||
uint64_t n = a.size();
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] -= a[i];
|
||||
}
|
||||
|
||||
}
|
||||
Vector<T> vec_subtract(const Vector<T>& a) const{
|
||||
Vector<T> subtract(const Vector<T>& a) const{
|
||||
Vector<T> result = *this;
|
||||
|
||||
result.inplace_vec_subtract(a);
|
||||
|
||||
result.inplace_subtract(a);
|
||||
return result;
|
||||
}
|
||||
Vector<T> operator-(const Vector<T>& a) const {
|
||||
return vec_subtract(a);
|
||||
return subtract(a);
|
||||
}
|
||||
Vector<T>& operator-=(const Vector<T>& a) {
|
||||
inplace_vec_subtract(a);
|
||||
inplace_subtract(a);
|
||||
return *this;
|
||||
}
|
||||
//##################################################
|
||||
//# VECTOR: Scalar Multiply #
|
||||
//##################################################
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
void inplace_multiply(const U a){
|
||||
const T a_hat = static_cast<T>(a);
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] *= a_hat;
|
||||
}
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> multiply(const U a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_multiply(a);
|
||||
return result;
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> operator*(const U a) const {
|
||||
return multiply(a);
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
friend Vector<T> operator*(U a, const Vector<T>& b) {
|
||||
return b * a;
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T>& operator*=(const U a) {
|
||||
inplace_multiply(a);
|
||||
return *this;
|
||||
}
|
||||
//##################################################
|
||||
//# VECTOR: Vector Multiply #
|
||||
//##################################################
|
||||
void inplace_vec_multiply(const Vector<T>& a){
|
||||
void inplace_multiply(const Vector<T>& a){
|
||||
if (a.size() != v.size()){
|
||||
throw std::runtime_error("utill:Vector.inplace_vec_multiply -> Dimensions does not fit");
|
||||
throw std::runtime_error("utill:Vector.inplace_multiply -> Dimensions does not fit");
|
||||
}
|
||||
|
||||
uint64_t n = a.size();
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] *= a[i];
|
||||
}
|
||||
|
||||
}
|
||||
Vector<T> vec_multiply(const Vector<T>& a) const{
|
||||
Vector<T> multiply(const Vector<T>& a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_vec_multiply(a);
|
||||
result.inplace_multiply(a);
|
||||
return result;
|
||||
}
|
||||
Vector<T> operator*(const Vector<T>& a) const {
|
||||
return vec_multiply(a);
|
||||
return multiply(a);
|
||||
}
|
||||
Vector<T>& operator*=(const Vector<T>& a) {
|
||||
inplace_vec_multiply(a);
|
||||
inplace_multiply(a);
|
||||
return *this;
|
||||
}
|
||||
//################################################
|
||||
//# VECTOR: Scalar Divide #
|
||||
//################################################
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
void inplace_divide(const U a){
|
||||
const T a_hat = static_cast<T>(a);
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] /= a_hat;
|
||||
}
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> divide(const U a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_divide(a);
|
||||
return result;
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> operator/(const U a) const {
|
||||
return divide(a);
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T>& operator/=(const U a) {
|
||||
inplace_divide(a);
|
||||
return *this;
|
||||
}
|
||||
//##################################################
|
||||
//# VECTOR: Vector Divide #
|
||||
//##################################################
|
||||
void inplace_vec_divide(const Vector<T>& a){
|
||||
void inplace_divide(const Vector<T>& a){
|
||||
if (a.size() != v.size()){
|
||||
throw std::runtime_error("utill:Vector.inplace_vec_divide -> Dimensions does not fit");
|
||||
throw std::runtime_error("utill:Vector.inplace_divide -> Dimensions does not fit");
|
||||
}
|
||||
|
||||
uint64_t n = a.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] /= a[i];
|
||||
}
|
||||
|
||||
}
|
||||
Vector<T> vec_divide(const Vector<T>& a) const{
|
||||
Vector<T> divide(const Vector<T>& a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_vec_divide(a);
|
||||
result.inplace_divide(a);
|
||||
return result;
|
||||
}
|
||||
Vector<T> operator/(const Vector<T>& a) const {
|
||||
return vec_divide(a);
|
||||
return divide(a);
|
||||
}
|
||||
Vector<T>& operator/=(const Vector<T>& a) {
|
||||
inplace_vec_divide(a);
|
||||
inplace_divide(a);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//###############################################
|
||||
//# VECTOR: Scalar Power #
|
||||
//###############################################
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
void inplace_power(const U a){
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] = static_cast<T>(std::pow(v[i], a));
|
||||
}
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> power(const U a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_power(a);
|
||||
return result;
|
||||
}
|
||||
//###############################################
|
||||
//# VECTOR: Vector Power #
|
||||
//###############################################
|
||||
void inplace_power(const Vector<T>& a){
|
||||
if (a.size() != v.size()){
|
||||
throw std::runtime_error("utill:Vector.inplace_power -> Dimensions does not fit");
|
||||
}
|
||||
uint64_t n = a.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] = static_cast<T>(std::pow(v[i], a[i]));
|
||||
}
|
||||
}
|
||||
Vector<T> power(const Vector<T>& a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_power(a);
|
||||
return result;
|
||||
}
|
||||
//################################################
|
||||
//# VECTOR: Scalar Square #
|
||||
//################################################
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
void inplace_square(const U a){
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] = static_cast<T>(std::sqrt(v[i], a));
|
||||
}
|
||||
}
|
||||
template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
|
||||
Vector<T> square(const U a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_square(a);
|
||||
return result;
|
||||
}
|
||||
//################################################
|
||||
//# VECTOR: Vector square #
|
||||
//################################################
|
||||
void inplace_square(const Vector<T>& a){
|
||||
if (a.size() != v.size()){
|
||||
throw std::runtime_error("utill:Vector.inplace_square -> Dimensions does not fit");
|
||||
}
|
||||
uint64_t n = a.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
v[i] = static_cast<T>(std::sqrt(v[i], a[i]));
|
||||
}
|
||||
}
|
||||
Vector<T> square(const Vector<T>& a) const{
|
||||
Vector<T> result = *this;
|
||||
result.inplace_square(a);
|
||||
return result;
|
||||
}
|
||||
//###################################################
|
||||
//# VECTOR: Dot Product #
|
||||
//###################################################
|
||||
T dot(const Vector<T>& a)const {
|
||||
if (a.size() != v.size()){
|
||||
throw std::runtime_error("utill:Vector.dot -> Dimensions does not fit");
|
||||
}
|
||||
T result;
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
result += a[i]*v[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//############################################
|
||||
//# VECTOR: Sum #
|
||||
//############################################
|
||||
T sum()const{
|
||||
T result = T{0};
|
||||
const uint64_t n = v.size();
|
||||
for (uint64_t i = 0; i < n; ++i){
|
||||
result += v[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//############################################
|
||||
//# VECTOR: Norm #
|
||||
//############################################
|
||||
T norm() const{
|
||||
return static_cast<T>(std::sqrt(this->dot(*this)));
|
||||
}
|
||||
//######################################################
|
||||
//# VECTOR: Support Functions #
|
||||
//######################################################
|
||||
|
||||
|
||||
|
||||
inline friend std::ostream& operator << (std::ostream& out, const Vector& vec){
|
||||
out << "[";
|
||||
for (uint64_t i = 0; i < vec.v.size(); i++){
|
||||
@@ -213,20 +386,6 @@ public:
|
||||
void print() const{
|
||||
std::cout << *this << std::endl;
|
||||
}
|
||||
/*
|
||||
void linspace(const T start, const T stop, const T num){
|
||||
v.clear();
|
||||
|
||||
if (num > 1){
|
||||
|
||||
double delta = (stop - start)/(num - 1);
|
||||
|
||||
for (uint64_t i = 0; i < num; i++){
|
||||
v.push_back(static_cast<T>(start + delta * i));
|
||||
}
|
||||
//v.push_back(static_cast<T>(stop));
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
typedef Vector<int> Vi;
|
||||
|
||||
Reference in New Issue
Block a user