My first bigger C++ project: a vector class for personal use and statistical computation.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
template<class T>
class vect
{
std::vector<T> m;
size_t s;
public:
// default constructor
vect(): m(0), s(0){}
// overloaded constructor
vect(size_t n) :m(n), s(n) {}
vect(std::vector<T> v) :m(v), s(v.size()) {}
// copy constructor
vect(const vect<T>&v): m(v.getData()), s(v.size()){}
// destructor
~vect(){}
std::vector<T> getData() const{
return m;
}
size_t size() const {
return s;
}
void addTo(T value){
m.push_back(value);
s++;
}
void addAt(T value, size_t loc=0){
s++;
m.emplace(m.begin()+loc, value);
}
void rmFrom(){
m.pop_back();
s--;
}
void rmAt(size_t loc){
m.erase(m.begin()+loc);
s--;
}
// returns a sorted copy of the original vector.
vect<T> sorted(){
std::vector<T> temp = this->getData();
std::sort(temp.begin(), temp.end());
vect<T> v(temp);
return v;
}
double median(){
// linearly interpolated
if (s%2==0)
{
return ((this->sorted()[(s/2)-1]+this->sorted()[(s/2)])/2);
}
else
{
return (this->sorted()[(s)/2]);
}
}
double percentile(double p){
// @p - value between 0 and 1: the percentile
// rounds to the nearest index and return the corresponding
return (this->sorted()[round(s*p)]);
}
double sum(){
// computes the sum of the vectors elements
double sum = 0;
size_t l = 0;
while (l<s) {
sum+=m[l];
l++;
}
return sum;
}
double mean(){
// computes the mean of the vectors elements
return this->sum()/s;
}
double dot(){
// computes the inner product of this vector
vect<T> temp = *this;
double dot = 0;
size_t l = 0;
while(l<s){
dot+=pow(temp[l],2);
l++;
}
return dot;
}
double dot(vect<T> other){
// computes the inner product of this and another vector
vect<T> temp = *this;
double dot = 0;
size_t l = 0;
while(l<s){
dot+=temp[l]*other[l];
l++;
}
return dot;
}
double magnitude(){
return sqrt(this->dot());
}
double manhattan_norm(){
// computes the manhattan norm
double n = 0;
size_t l = 0;
while(l<s){
n+=abs(m[l]);
l++;
}
return sqrt(n);
}
double p_norm(unsigned int p){
return pow(this->dot(),1/p);
}
vect<T> normalized(){
// devides the vector by it's eucledian distance
// which results in a unity vector, meaning
// the sum the elements of a unity vector add up to one;
T n = 0;
vect<T> unity = *this;
n = unity.magnitude();
return unity/n;
}
vect<T> diff(vect<T> other){
vect<T> diff;
return (*this-other);
}
double cosine(vect<T> other){
// returns the cosine of theta of this vector and another
return this->dot(other)/(this->magnitude()*other.magnitude());
}
double angle(vect<T> other){
return acos(this->cosine(other))*(180/3.14159265);
}
bool is_perpendicular(vect<T> other){
return (this->dot(other)==0);
}
vect<T> direction_cosine(){
vect<T> direction;
double norm = this->norm();
double cosine = 0;
double theta = 0;
for(size_t i = 0; i < s; i++){
cosine = m[i]/norm;
theta = acos(cosine);
direction.addTo(theta);
}
return direction;
}
vect<T> parallel_comp(vect<T> other){
// projection of other onto *this
vect<T> temp = *this;
return (temp.dot(other)/temp.dot(temp))*temp;
}
vect<T> perpendicular_comp(vect<T> other){
return other-parallel_comp(other);
}
double parallel_magnitude(vect<T> other){
// returns the the projections size
return this->parallel_comp(other).magnitude();
}
double error_magnitude(vect<T> other){
// returns the the parallel components size relative to it's own
return this->perpendicular_comp(other).magnitude();
}
// overloaded operators
vect<T>& operator=(const vect<T>& other){
if (this!=&other)
{
m = other.getData();
s = other.size();
}
return *this;
}
T& operator[] (size_t i) {
return m[i];
}
const T& operator[] (size_t i) const {
return m[i];
}
};
template<class T>
std::ostream& operator<<(std::ostream &os, const vect<T>&v){
for(int i = 0; i < v.size(); i++){
os << v.getData()[i] << " ";
}
return os;
}
template<class T>
std::istream& operator>>(std::istream& is, vect<T>& v){
T value;
is >> value;
v.addTo(value);
return is;
}
template<class T>
vect<T>& operator+=(vect<T>& a, const vect<T>& b)
{
for(size_t i=0; i<a.size(); ++i)
a[i]+=b[i];
return a;
}
template<class T>
vect<T> operator+(const vect<T>& a, const vect<T>& b)
{
vect<T> z(a.size());
for(size_t i=0; i<a.size(); ++i)
z[i] = a[i]+b[i];
return z;
}
Plus many more overloaded arithmetic operators which are all like the last two ones.
I know it's nothing fancy but I am always looking for ways to make things better.
s
member? It looks like it's just the same asm.size()
. \$\endgroup\$