dynare/dynare++/sylv/cc/Vector.hh

255 lines
6.5 KiB
C++
Raw Normal View History

/*
* Copyright © 2004-2011 Ondra Kamenik
* Copyright © 2019 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VECTOR_H
#define VECTOR_H
/* NOTE: Vector and ConstVector have not common super class in order
to avoid running virtual method invokation mechanism. Some
members, and methods are thus duplicated */
#include <complex>
#include <utility>
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
# include <dynmex.h>
#endif
class GeneralMatrix;
class ConstVector;
2017-05-16 16:30:27 +02:00
class Vector
{
friend class ConstVector;
protected:
int len{0};
int s{1}; // stride (also called “skip” in some places)
double *data;
bool destroy{true};
public:
Vector() : data{nullptr}, destroy{false}
{
}
Vector(int l) : len{l}, data{new double[l]}
{
}
Vector(Vector &v) : len{v.len}, s{v.s}, data{v.data}, destroy{false}
2017-05-16 16:30:27 +02:00
{
}
Vector(const Vector &v);
Vector(Vector &&v) : len{std::exchange(v.len, 0)}, s{v.s},
data{std::exchange(v.data, nullptr)},
destroy{std::exchange(v.destroy, false)}
{
}
// We don't want implict conversion from ConstVector, since its expensive
explicit Vector(const ConstVector &v);
Vector(double *d, int l)
: len(l), data{d}, destroy{false}
{
}
Vector(Vector &v, int off_arg, int l);
Vector(const Vector &v, int off_arg, int l);
Vector(Vector &v, int off_arg, int skip, int l);
Vector(const Vector &v, int off_arg, int skip, int l);
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
explicit Vector(mxArray *p);
#endif
Vector &operator=(const Vector &v);
Vector &operator=(Vector &&v);
Vector &operator=(const ConstVector &v);
2017-05-16 16:30:27 +02:00
double &
operator[](int i)
{
return data[s*i];
2017-05-16 16:30:27 +02:00
}
const double &
operator[](int i) const
{
return data[s*i];
2017-05-16 16:30:27 +02:00
}
const double *
base() const
{
return data;
2017-05-16 16:30:27 +02:00
}
double *
base()
{
return data;
2017-05-16 16:30:27 +02:00
}
int
length() const
{
return len;
}
int
skip() const
{
return s;
}
// Exact equality.
2017-05-16 16:30:27 +02:00
bool operator==(const Vector &y) const;
bool operator!=(const Vector &y) const;
// Lexicographic ordering.
2017-05-16 16:30:27 +02:00
bool operator<(const Vector &y) const;
bool operator<=(const Vector &y) const;
bool operator>(const Vector &y) const;
bool operator>=(const Vector &y) const;
virtual ~Vector()
{
if (destroy)
delete[] data;
}
2017-05-16 16:30:27 +02:00
void zeros();
void nans();
void infs();
void rotatePair(double alpha, double beta1, double beta2, int i);
// Computes this = this + r·v
2017-05-16 16:30:27 +02:00
void add(double r, const Vector &v);
// Computes this = this + r·v
2017-05-16 16:30:27 +02:00
void add(double r, const ConstVector &v);
// Computes this = this + z·v (where this and v are intepreted as complex vectors)
void addComplex(const std::complex<double> &z, const Vector &v);
// Computes this = this + z·v (where this and v are intepreted as complex vectors)
void addComplex(const std::complex<double> &z, const ConstVector &v);
2017-05-16 16:30:27 +02:00
void mult(double r);
double getNorm() const;
double getMax() const;
double getNorm1() const;
double dot(const Vector &y) const;
bool isFinite() const;
void print() const;
/* Computes:
x α β b
= I·
x β α b
2017-05-16 16:30:27 +02:00
*/
static void mult2(double alpha, double beta1, double beta2,
Vector &x1, Vector &x2,
const Vector &b1, const Vector &b2);
/* Computes:
x x α β b
= + I·
x x β α b
*/
2017-05-16 16:30:27 +02:00
static void mult2a(double alpha, double beta1, double beta2,
Vector &x1, Vector &x2,
const Vector &b1, const Vector &b2);
/* Computes:
x x α β b
= I·
x x β α b
*/
2017-05-16 16:30:27 +02:00
static void
mult2s(double alpha, double beta1, double beta2,
Vector &x1, Vector &x2,
const Vector &b1, const Vector &b2)
{
mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);
}
private:
2017-05-16 16:30:27 +02:00
void copy(const double *d, int inc);
};
class ConstGeneralMatrix;
class ConstVector
2017-05-16 16:30:27 +02:00
{
friend class Vector;
protected:
2017-05-16 16:30:27 +02:00
int len;
int s{1}; // stride (also called “skip” in some places)
const double *data;
public:
// Implicit conversion from Vector is ok, since its cheap
ConstVector(const Vector &v);
ConstVector(const ConstVector &v) = default;
ConstVector(ConstVector &&v) = default;
ConstVector(const double *d, int l) : len{l}, data{d}
2017-05-16 16:30:27 +02:00
{
}
ConstVector(const ConstVector &v, int off_arg, int l);
ConstVector(const ConstVector &v, int off_arg, int skip, int l);
ConstVector(const double *d, int skip, int l);
#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
explicit ConstVector(const mxArray *p);
#endif
virtual ~ConstVector() = default;
ConstVector &operator=(const ConstVector &v) = delete;
ConstVector &operator=(ConstVector &&v) = delete;
2017-05-16 16:30:27 +02:00
const double &
operator[](int i) const
{
return data[s*i];
2017-05-16 16:30:27 +02:00
}
const double *
base() const
{
return data;
2017-05-16 16:30:27 +02:00
}
int
length() const
{
return len;
}
int
skip() const
{
return s;
}
// Exact equality
2017-05-16 16:30:27 +02:00
bool operator==(const ConstVector &y) const;
bool
operator!=(const ConstVector &y) const
{
return !operator==(y);
}
// Lexicographic ordering
2017-05-16 16:30:27 +02:00
bool operator<(const ConstVector &y) const;
bool
operator<=(const ConstVector &y) const
{
return operator<(y) || operator==(y);
}
bool
operator>(const ConstVector &y) const
{
return !operator<=(y);
}
bool
operator>=(const ConstVector &y) const
{
return !operator<(y);
}
double getNorm() const;
double getMax() const;
double getNorm1() const;
double dot(const ConstVector &y) const;
bool isFinite() const;
void print() const;
};
#endif /* VECTOR_H */