code format
This commit is contained in:
@@ -5,22 +5,22 @@
|
||||
* \~russian Вычисление CRC контрольной суммы
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
CRC checksum calculator
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
CRC checksum calculator
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PICRC_H
|
||||
@@ -28,138 +28,295 @@
|
||||
|
||||
#include "pistring.h"
|
||||
|
||||
template <int L>
|
||||
template<int L>
|
||||
class PIP_EXPORT uint_cl {
|
||||
public:
|
||||
uint_cl() {for (int i = 0; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(const uint_cl<L> & v) {for (int i = 0; i < L / 8; ++i) data_[i] = v.data_[i];}
|
||||
uint_cl(uchar v) {for (int i = 0; i < L / 8; ++i) data_[i] = (i == 0 ? v : 0);}
|
||||
uint_cl(char v) {for (int i = 0; i < L / 8; ++i) data_[i] = (i == 0 ? v : 0);}
|
||||
uint_cl(ushort v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(short v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(uint v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(int v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(ulong v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(long v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(ullong v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl(llong v) {int l = piMin<uint>(L / 8, sizeof(v)); memcpy(data_, &v, l); for (int i = l; i < L / 8; ++i) data_[i] = 0;}
|
||||
uint_cl() {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(const uint_cl<L> & v) {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
data_[i] = v.data_[i];
|
||||
}
|
||||
uint_cl(uchar v) {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
data_[i] = (i == 0 ? v : 0);
|
||||
}
|
||||
uint_cl(char v) {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
data_[i] = (i == 0 ? v : 0);
|
||||
}
|
||||
uint_cl(ushort v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(short v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(uint v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(int v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(ulong v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(long v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(ullong v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
uint_cl(llong v) {
|
||||
int l = piMin<uint>(L / 8, sizeof(v));
|
||||
memcpy(data_, &v, l);
|
||||
for (int i = l; i < L / 8; ++i)
|
||||
data_[i] = 0;
|
||||
}
|
||||
|
||||
operator bool() {for (int i = 0; i < L / 8; ++i) if (data_[i] > 0) return true; return false;}
|
||||
operator char() {return (char)data_[0];}
|
||||
operator short() {short t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator int() {int t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator long() {long t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator llong() {llong t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator uchar() {return data_[0];}
|
||||
operator ushort() {ushort t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator uint() {uint t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator ulong() {ulong t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator ullong() {ullong t(0); int l = piMin<uint>(L / 8, sizeof(t)); memcpy(&t, data_, l); return t;}
|
||||
operator bool() {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
if (data_[i] > 0) return true;
|
||||
return false;
|
||||
}
|
||||
operator char() { return (char)data_[0]; }
|
||||
operator short() {
|
||||
short t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
operator int() {
|
||||
int t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
operator long() {
|
||||
long t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
operator llong() {
|
||||
llong t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
operator uchar() { return data_[0]; }
|
||||
operator ushort() {
|
||||
ushort t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
operator uint() {
|
||||
uint t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
operator ulong() {
|
||||
ulong t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
operator ullong() {
|
||||
ullong t(0);
|
||||
int l = piMin<uint>(L / 8, sizeof(t));
|
||||
memcpy(&t, data_, l);
|
||||
return t;
|
||||
}
|
||||
|
||||
uint_cl<L> operator +(const uint_cl<L> & v) {
|
||||
uint_cl<L> operator+(const uint_cl<L> & v) {
|
||||
uint_cl<L> t;
|
||||
uint cv;
|
||||
bool ov = false;
|
||||
for (int i = 0; i < L / 8; ++i) {
|
||||
cv = v.data_[i] + data_[i];
|
||||
if (ov) ++cv;
|
||||
ov = cv > 255;
|
||||
ov = cv > 255;
|
||||
t.data_[i] = ov ? cv - 256 : cv;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
uint_cl<L> operator &(const uint_cl<L> & v) const {uint_cl<L> t; for (int i = 0; i < L / 8; ++i) t.data_[i] = v.data_[i] & data_[i]; return t;}
|
||||
uint_cl<L> operator &(const uchar & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const ushort & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const uint & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const ulong & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const ullong & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const char & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const short & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const int & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const long & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator &(const llong & v) const {return *this & uint_cl<L>(v);}
|
||||
uint_cl<L> operator&(const uint_cl<L> & v) const {
|
||||
uint_cl<L> t;
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
t.data_[i] = v.data_[i] & data_[i];
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> operator&(const uchar & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const ushort & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const uint & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const ulong & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const ullong & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const char & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const short & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const int & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const long & v) const { return *this & uint_cl<L>(v); }
|
||||
uint_cl<L> operator&(const llong & v) const { return *this & uint_cl<L>(v); }
|
||||
|
||||
uint_cl<L> operator |(const uint_cl<L> & v) const {uint_cl<L> t; for (int i = 0; i < L / 8; ++i) t.data_[i] = v.data_[i] | data_[i]; return t;}
|
||||
uint_cl<L> operator |(const uchar & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const ushort & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const uint & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const ulong & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const ullong & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const char & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const short & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const int & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const long & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator |(const llong & v) const {return *this | uint_cl<L>(v);}
|
||||
uint_cl<L> operator|(const uint_cl<L> & v) const {
|
||||
uint_cl<L> t;
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
t.data_[i] = v.data_[i] | data_[i];
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> operator|(const uchar & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const ushort & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const uint & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const ulong & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const ullong & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const char & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const short & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const int & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const long & v) const { return *this | uint_cl<L>(v); }
|
||||
uint_cl<L> operator|(const llong & v) const { return *this | uint_cl<L>(v); }
|
||||
|
||||
uint_cl<L> operator ^(const uint_cl<L> & v) const {uint_cl<L> t; for (int i = 0; i < L / 8; ++i) t.data_[i] = v.data_[i] ^ data_[i]; return t;}
|
||||
uint_cl<L> operator ^(const uchar & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const ushort & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const uint & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const ulong & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const ullong & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const char & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const short & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const int & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const long & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator ^(const llong & v) const {return *this ^ uint_cl<L>(v);}
|
||||
uint_cl<L> operator^(const uint_cl<L> & v) const {
|
||||
uint_cl<L> t;
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
t.data_[i] = v.data_[i] ^ data_[i];
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> operator^(const uchar & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const ushort & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const uint & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const ulong & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const ullong & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const char & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const short & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const int & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const long & v) const { return *this ^ uint_cl<L>(v); }
|
||||
uint_cl<L> operator^(const llong & v) const { return *this ^ uint_cl<L>(v); }
|
||||
|
||||
bool operator <(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] > data_[i]) return true; if (v.data_[i] < data_[i]) return false;} return false;}
|
||||
bool operator <=(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] > data_[i]) return true; if (v.data_[i] < data_[i]) return false;} return true;}
|
||||
bool operator >(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] < data_[i]) return true; if (v.data_[i] > data_[i]) return false;} return false;}
|
||||
bool operator >=(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) {if (v.data_[i] < data_[i]) return true; if (v.data_[i] > data_[i]) return false;} return true;}
|
||||
bool operator ==(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) if (v.data_[i] != data_[i]) return false; return true;}
|
||||
bool operator !=(const uint_cl<L> & v) const {for (int i = 0; i < L / 8; ++i) if (v.data_[i] != data_[i]) return true; return false;}
|
||||
bool operator <=(const uint_cl<8> & v1) {return (*(uchar*)data()) <= (*(uchar*)v1.data());}
|
||||
bool operator<(const uint_cl<L> & v) const {
|
||||
for (int i = 0; i < L / 8; ++i) {
|
||||
if (v.data_[i] > data_[i]) return true;
|
||||
if (v.data_[i] < data_[i]) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool operator<=(const uint_cl<L> & v) const {
|
||||
for (int i = 0; i < L / 8; ++i) {
|
||||
if (v.data_[i] > data_[i]) return true;
|
||||
if (v.data_[i] < data_[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool operator>(const uint_cl<L> & v) const {
|
||||
for (int i = 0; i < L / 8; ++i) {
|
||||
if (v.data_[i] < data_[i]) return true;
|
||||
if (v.data_[i] > data_[i]) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool operator>=(const uint_cl<L> & v) const {
|
||||
for (int i = 0; i < L / 8; ++i) {
|
||||
if (v.data_[i] < data_[i]) return true;
|
||||
if (v.data_[i] > data_[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool operator==(const uint_cl<L> & v) const {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
if (v.data_[i] != data_[i]) return false;
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const uint_cl<L> & v) const {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
if (v.data_[i] != data_[i]) return true;
|
||||
return false;
|
||||
}
|
||||
bool operator<=(const uint_cl<8> & v1) { return (*(uchar *)data()) <= (*(uchar *)v1.data()); }
|
||||
|
||||
uint_cl<L> operator >>(const int & c) const {
|
||||
uint_cl<L> operator>>(const int & c) const {
|
||||
uint_cl<L> t;
|
||||
int l = L - c;
|
||||
bool bit;
|
||||
if (l <= 0) return t;
|
||||
for (int i = 0; i < l; ++i) {
|
||||
bit = 1 & (data_[(i + c) / 8] >> ((i + c) % 8));
|
||||
if (bit) t.data_[i / 8] |= (1 << (i % 8));
|
||||
else t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
if (bit)
|
||||
t.data_[i / 8] |= (1 << (i % 8));
|
||||
else
|
||||
t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> operator >>(const uint & c) const {return (*this << (int)c);}
|
||||
uint_cl<L> operator <<(const int & c) const {
|
||||
uint_cl<L> operator>>(const uint & c) const { return (*this << (int)c); }
|
||||
uint_cl<L> operator<<(const int & c) const {
|
||||
uint_cl<L> t;
|
||||
int l = L - c;
|
||||
bool bit;
|
||||
if (l <= 0) return t;
|
||||
for (int i = c; i < L; ++i) {
|
||||
bit = 1 & (data_[(i - c) / 8] >> ((i - c) % 8));
|
||||
if (bit) t.data_[i / 8] |= (1 << (i % 8));
|
||||
else t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
if (bit)
|
||||
t.data_[i / 8] |= (1 << (i % 8));
|
||||
else
|
||||
t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> operator <<(const uint & c) const {return (*this >> (int)c);}
|
||||
uint_cl<L> operator<<(const uint & c) const { return (*this >> (int)c); }
|
||||
|
||||
uint_cl<L> & inverse() const {for (int i = 0; i < L / 8; ++i) data_[i] = ~data_[i]; return *this;}
|
||||
uint_cl<L> inversed() const {uint_cl<L> t(*this); for (int i = 0; i < L / 8; ++i) t.data_[i] = ~t.data_[i]; return t;}
|
||||
uint_cl<L> & inverse() const {
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
data_[i] = ~data_[i];
|
||||
return *this;
|
||||
}
|
||||
uint_cl<L> inversed() const {
|
||||
uint_cl<L> t(*this);
|
||||
for (int i = 0; i < L / 8; ++i)
|
||||
t.data_[i] = ~t.data_[i];
|
||||
return t;
|
||||
}
|
||||
uint_cl<L> reversed() const {
|
||||
uint_cl<L> t;
|
||||
bool bit;
|
||||
for (int i = 0; i < L; ++i) {
|
||||
bit = 1 & (data_[(L - i - 1) / 8] >> ((L - i - 1) % 8));
|
||||
if (bit) t.data_[i / 8] |= (1 << (i % 8));
|
||||
else t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
if (bit)
|
||||
t.data_[i / 8] |= (1 << (i % 8));
|
||||
else
|
||||
t.data_[i / 8] &= ~(1 << (i % 8));
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
const uchar * data() const {return data_;}
|
||||
uchar * data() {return data_;}
|
||||
uint length() const {return L / 8;}
|
||||
const uchar * data() const { return data_; }
|
||||
uchar * data() { return data_; }
|
||||
uint length() const { return L / 8; }
|
||||
|
||||
private:
|
||||
uchar data_[L / 8];
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -173,74 +330,117 @@ inline uchar reverseByte(uchar b) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <uint L, typename N = uint_cl<L> >
|
||||
template<uint L, typename N = uint_cl<L>>
|
||||
class PIP_EXPORT PICRC {
|
||||
public:
|
||||
PICRC(const N & poly = N()) {poly_ = poly; reverse_poly = true; init_ = inversed(N(0)); out_ = inversed(N(0)); reverse_before_xor = reverse_data = false; initTable();}
|
||||
PICRC(const N & poly, bool reverse_poly_, const N & initial, const N & out_xor) {poly_ = poly; reverse_poly = reverse_poly_; init_ = initial; out_ = out_xor; reverse_before_xor = reverse_data = false; initTable();}
|
||||
PICRC(const N & poly = N()) {
|
||||
poly_ = poly;
|
||||
reverse_poly = true;
|
||||
init_ = inversed(N(0));
|
||||
out_ = inversed(N(0));
|
||||
reverse_before_xor = reverse_data = false;
|
||||
initTable();
|
||||
}
|
||||
PICRC(const N & poly, bool reverse_poly_, const N & initial, const N & out_xor) {
|
||||
poly_ = poly;
|
||||
reverse_poly = reverse_poly_;
|
||||
init_ = initial;
|
||||
out_ = out_xor;
|
||||
reverse_before_xor = reverse_data = false;
|
||||
initTable();
|
||||
}
|
||||
|
||||
void setInitial(const N & v) {init_ = v;}
|
||||
void setOutXor(const N & v) {out_ = v;}
|
||||
void setReversePolynome(bool yes) {reverse_poly = yes; initTable();}
|
||||
void setReverseOutBeforeXOR(bool yes) {reverse_before_xor = yes;}
|
||||
void setReverseDataBytes(bool yes) {reverse_data = yes;}
|
||||
void setInitial(const N & v) { init_ = v; }
|
||||
void setOutXor(const N & v) { out_ = v; }
|
||||
void setReversePolynome(bool yes) {
|
||||
reverse_poly = yes;
|
||||
initTable();
|
||||
}
|
||||
void setReverseOutBeforeXOR(bool yes) { reverse_before_xor = yes; }
|
||||
void setReverseDataBytes(bool yes) { reverse_data = yes; }
|
||||
|
||||
void initTable() {
|
||||
N tmp, pol = reverse_poly ? reversed(poly_) : poly_;
|
||||
//cout << std::hex << "poly " << (uint)N(poly_) << " -> " << (uint)N(pol) << endl;
|
||||
// cout << std::hex << "poly " << (uint)N(poly_) << " -> " << (uint)N(pol) << endl;
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
tmp = uchar(i);
|
||||
for (int j = 0; j < 8; ++j)
|
||||
tmp = ((tmp & 1) ? ((tmp >> 1) ^ pol) : (tmp >> 1));
|
||||
table[i] = tmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
N calculate(const void * data, int size) {
|
||||
N crc = init_;
|
||||
uchar * data_ = (uchar * )data, cb;
|
||||
//cout << "process " << size << endl;
|
||||
N crc = init_;
|
||||
uchar *data_ = (uchar *)data, cb;
|
||||
// cout << "process " << size << endl;
|
||||
uchar nTemp;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cb = data_[i];
|
||||
if (reverse_data) cb = reverseByte(cb);
|
||||
nTemp = cb ^ uchar(crc);
|
||||
crc = crc >> 8;
|
||||
crc = crc ^ table[nTemp];
|
||||
crc = crc >> 8;
|
||||
crc = crc ^ table[nTemp];
|
||||
}
|
||||
if (reverse_before_xor) crc = reversed(crc);
|
||||
return crc ^ out_;
|
||||
|
||||
}
|
||||
N calculate(const PIByteArray & d) {return calculate(d.data(), d.size());}
|
||||
N calculate(const char * str) {PIByteArray s(PIString(str).toByteArray()); return calculate(s.data(), s.size_s());}
|
||||
N calculate(const PIByteArray & d) { return calculate(d.data(), d.size()); }
|
||||
N calculate(const char * str) {
|
||||
PIByteArray s(PIString(str).toByteArray());
|
||||
return calculate(s.data(), s.size_s());
|
||||
}
|
||||
|
||||
private:
|
||||
inline N reversed(const N & v) {return v.reversed();}
|
||||
inline N inversed(const N & v) {return v.inversed();}
|
||||
|
||||
inline N reversed(const N & v) { return v.reversed(); }
|
||||
inline N inversed(const N & v) { return v.inversed(); }
|
||||
|
||||
N table[256];
|
||||
N poly_, init_, out_;
|
||||
bool reverse_poly, reverse_before_xor, reverse_data;
|
||||
|
||||
};
|
||||
|
||||
template <> inline uchar PICRC<8, uchar>::reversed(const uchar & v) {return reverseByte(v);}
|
||||
template <> inline ushort PICRC<16, ushort>::reversed(const ushort & v) {return uint_cl<16>(v).reversed();}
|
||||
template <> inline uint PICRC<32, uint>::reversed(const uint & v) {return uint_cl<32>(v).reversed();}
|
||||
template <> inline uchar PICRC<8, uchar>::inversed(const uchar & v) {return ~v;}
|
||||
template <> inline ushort PICRC<16, ushort>::inversed(const ushort & v) {return ~v;}
|
||||
template <> inline uint PICRC<32, uint>::inversed(const uint & v) {return ~v;}
|
||||
template<>
|
||||
inline uchar PICRC<8, uchar>::reversed(const uchar & v) {
|
||||
return reverseByte(v);
|
||||
}
|
||||
template<>
|
||||
inline ushort PICRC<16, ushort>::reversed(const ushort & v) {
|
||||
return uint_cl<16>(v).reversed();
|
||||
}
|
||||
template<>
|
||||
inline uint PICRC<32, uint>::reversed(const uint & v) {
|
||||
return uint_cl<32>(v).reversed();
|
||||
}
|
||||
template<>
|
||||
inline uchar PICRC<8, uchar>::inversed(const uchar & v) {
|
||||
return ~v;
|
||||
}
|
||||
template<>
|
||||
inline ushort PICRC<16, ushort>::inversed(const ushort & v) {
|
||||
return ~v;
|
||||
}
|
||||
template<>
|
||||
inline uint PICRC<32, uint>::inversed(const uint & v) {
|
||||
return ~v;
|
||||
}
|
||||
|
||||
typedef PICRC<32, uint> CRC_32;
|
||||
typedef PICRC<24> CRC_24;
|
||||
typedef PICRC<32, uint> CRC_32;
|
||||
typedef PICRC<24> CRC_24;
|
||||
typedef PICRC<16, ushort> CRC_16;
|
||||
typedef PICRC<8, uchar> CRC_8;
|
||||
typedef PICRC<8, uchar> CRC_8;
|
||||
|
||||
inline CRC_32 standardCRC_32() {return CRC_32(0x04C11DB7, true, 0xFFFFFFFF, 0xFFFFFFFF);}
|
||||
inline CRC_16 standardCRC_16() {return CRC_16(0x8005, true, 0x0, 0x0);}
|
||||
inline CRC_16 standardCRC_16_Modbus() {return CRC_16(0x8005, 0xFFFF, 0xFFFF, false);}
|
||||
inline CRC_8 standardCRC_8() {return CRC_8(0xD5, true, 0x0, 0x0);}
|
||||
inline CRC_32 standardCRC_32() {
|
||||
return CRC_32(0x04C11DB7, true, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
}
|
||||
inline CRC_16 standardCRC_16() {
|
||||
return CRC_16(0x8005, true, 0x0, 0x0);
|
||||
}
|
||||
inline CRC_16 standardCRC_16_Modbus() {
|
||||
return CRC_16(0x8005, 0xFFFF, 0xFFFF, false);
|
||||
}
|
||||
inline CRC_8 standardCRC_8() {
|
||||
return CRC_8(0xD5, true, 0x0, 0x0);
|
||||
}
|
||||
|
||||
#endif // CRC_H
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream computing
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream computing
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pievaluator.h"
|
||||
@@ -122,49 +122,49 @@ using namespace PIEvaluatorTypes;
|
||||
|
||||
|
||||
PIEvaluatorContent::PIEvaluatorContent() {
|
||||
addFunction(PIStringAscii("arcsin" ), 1);
|
||||
addFunction(PIStringAscii("arccos" ), 1);
|
||||
addFunction(PIStringAscii("arctg" ), 1);
|
||||
addFunction(PIStringAscii("arcctg" ), 1);
|
||||
addFunction(PIStringAscii("random" ), 2);
|
||||
addFunction(PIStringAscii("arcsin"), 1);
|
||||
addFunction(PIStringAscii("arccos"), 1);
|
||||
addFunction(PIStringAscii("arctg"), 1);
|
||||
addFunction(PIStringAscii("arcctg"), 1);
|
||||
addFunction(PIStringAscii("random"), 2);
|
||||
addFunction(PIStringAscii("randomn"), 2);
|
||||
addFunction(PIStringAscii("sin" ), 1);
|
||||
addFunction(PIStringAscii("cos" ), 1);
|
||||
addFunction(PIStringAscii("ctg" ), 1);
|
||||
addFunction(PIStringAscii("tg" ), 1);
|
||||
addFunction(PIStringAscii("exp" ), 1);
|
||||
addFunction(PIStringAscii("cth" ), 1);
|
||||
addFunction(PIStringAscii("sh" ), 1);
|
||||
addFunction(PIStringAscii("ch" ), 1);
|
||||
addFunction(PIStringAscii("th" ), 1);
|
||||
addFunction(PIStringAscii("sqrt" ), 1);
|
||||
addFunction(PIStringAscii("sqr" ), 1);
|
||||
addFunction(PIStringAscii("pow" ), 2);
|
||||
addFunction(PIStringAscii("abs" ), 1);
|
||||
addFunction(PIStringAscii("ln" ), 1);
|
||||
addFunction(PIStringAscii("lg" ), 1);
|
||||
addFunction(PIStringAscii("log" ), 2);
|
||||
addFunction(PIStringAscii("im" ), 1);
|
||||
addFunction(PIStringAscii("re" ), 1);
|
||||
addFunction(PIStringAscii("arg" ), 1);
|
||||
addFunction(PIStringAscii("len" ), 1);
|
||||
addFunction(PIStringAscii("conj" ), 1);
|
||||
addFunction(PIStringAscii("sign" ), 1);
|
||||
addFunction(PIStringAscii("rad" ), 1);
|
||||
addFunction(PIStringAscii("deg" ), 1);
|
||||
addFunction(PIStringAscii("j0" ), 1);
|
||||
addFunction(PIStringAscii("j1" ), 1);
|
||||
addFunction(PIStringAscii("jn" ), 2);
|
||||
addFunction(PIStringAscii("y0" ), 1);
|
||||
addFunction(PIStringAscii("y1" ), 1);
|
||||
addFunction(PIStringAscii("yn" ), 2);
|
||||
addFunction(PIStringAscii("min" ), -2); // (x0,x1,...)
|
||||
addFunction(PIStringAscii("max" ), -2); // (x0,x1,...)
|
||||
addFunction(PIStringAscii("clamp" ), 3); // (x,a,b) = x < a ? a : (x > b ? b : x)
|
||||
addFunction(PIStringAscii("step" ), 2); // (x,s) = x >= s ? 1. : 0. (1 if 'x' >= 's', else 0)
|
||||
addFunction(PIStringAscii("mix" ), 3); // (x,a,b) = a*(1.-x) + b*x (interpolate between 'a' and 'b' linear for 'x')
|
||||
addFunction(PIStringAscii("sin"), 1);
|
||||
addFunction(PIStringAscii("cos"), 1);
|
||||
addFunction(PIStringAscii("ctg"), 1);
|
||||
addFunction(PIStringAscii("tg"), 1);
|
||||
addFunction(PIStringAscii("exp"), 1);
|
||||
addFunction(PIStringAscii("cth"), 1);
|
||||
addFunction(PIStringAscii("sh"), 1);
|
||||
addFunction(PIStringAscii("ch"), 1);
|
||||
addFunction(PIStringAscii("th"), 1);
|
||||
addFunction(PIStringAscii("sqrt"), 1);
|
||||
addFunction(PIStringAscii("sqr"), 1);
|
||||
addFunction(PIStringAscii("pow"), 2);
|
||||
addFunction(PIStringAscii("abs"), 1);
|
||||
addFunction(PIStringAscii("ln"), 1);
|
||||
addFunction(PIStringAscii("lg"), 1);
|
||||
addFunction(PIStringAscii("log"), 2);
|
||||
addFunction(PIStringAscii("im"), 1);
|
||||
addFunction(PIStringAscii("re"), 1);
|
||||
addFunction(PIStringAscii("arg"), 1);
|
||||
addFunction(PIStringAscii("len"), 1);
|
||||
addFunction(PIStringAscii("conj"), 1);
|
||||
addFunction(PIStringAscii("sign"), 1);
|
||||
addFunction(PIStringAscii("rad"), 1);
|
||||
addFunction(PIStringAscii("deg"), 1);
|
||||
addFunction(PIStringAscii("j0"), 1);
|
||||
addFunction(PIStringAscii("j1"), 1);
|
||||
addFunction(PIStringAscii("jn"), 2);
|
||||
addFunction(PIStringAscii("y0"), 1);
|
||||
addFunction(PIStringAscii("y1"), 1);
|
||||
addFunction(PIStringAscii("yn"), 2);
|
||||
addFunction(PIStringAscii("min"), -2); // (x0,x1,...)
|
||||
addFunction(PIStringAscii("max"), -2); // (x0,x1,...)
|
||||
addFunction(PIStringAscii("clamp"), 3); // (x,a,b) = x < a ? a : (x > b ? b : x)
|
||||
addFunction(PIStringAscii("step"), 2); // (x,s) = x >= s ? 1. : 0. (1 if 'x' >= 's', else 0)
|
||||
addFunction(PIStringAscii("mix"), 3); // (x,a,b) = a*(1.-x) + b*x (interpolate between 'a' and 'b' linear for 'x')
|
||||
addFunction(PIStringAscii("defined"), 1);
|
||||
addFunction(PIStringAscii("round" ), 1);
|
||||
addFunction(PIStringAscii("round"), 1);
|
||||
clearCustomVariables();
|
||||
}
|
||||
|
||||
@@ -206,94 +206,89 @@ int PIEvaluatorContent::customVariablesCount() const {
|
||||
|
||||
int PIEvaluatorContent::findFunction(const PIString & name) const {
|
||||
for (uint i = 0; i < functions.size(); i++)
|
||||
if (functions[i].identifier == name)
|
||||
return i;
|
||||
if (functions[i].identifier == name) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int PIEvaluatorContent::findVariable(const PIString & var_name) const {
|
||||
for (uint i = 0; i < variables.size(); i++)
|
||||
if (variables[i].name == var_name)
|
||||
return i;
|
||||
if (variables[i].name == var_name) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
PIEvaluatorTypes::Function PIEvaluatorContent::function(int index) {
|
||||
if (index < 0 || index >= functions.size_s())
|
||||
return PIEvaluatorTypes::Function();
|
||||
if (index < 0 || index >= functions.size_s()) return PIEvaluatorTypes::Function();
|
||||
return functions[index];
|
||||
}
|
||||
|
||||
|
||||
PIEvaluatorTypes::Variable PIEvaluatorContent::variable(int index) {
|
||||
if (index < 0 || index >= variables.size_s())
|
||||
return PIEvaluatorTypes::Variable();
|
||||
if (index < 0 || index >= variables.size_s()) return PIEvaluatorTypes::Variable();
|
||||
return variables[index];
|
||||
}
|
||||
|
||||
|
||||
PIEvaluatorTypes::Variable PIEvaluatorContent::customVariable(int index) {
|
||||
if (index < 0 || index >= variables.size_s() - cv_count)
|
||||
return PIEvaluatorTypes::Variable();
|
||||
if (index < 0 || index >= variables.size_s() - cv_count) return PIEvaluatorTypes::Variable();
|
||||
return variables[index + cv_count];
|
||||
}
|
||||
|
||||
|
||||
void PIEvaluatorContent::clearCustomVariables() {
|
||||
variables.clear();
|
||||
addVariable(PIStringAscii("i" ), complexd_i);
|
||||
addVariable(PIStringAscii("i"), complexd_i);
|
||||
addVariable(PIStringAscii("pi"), 3.141592653589793238462643383280);
|
||||
addVariable(PIStringAscii("e" ), exp(1.));
|
||||
addVariable(PIStringAscii("e"), exp(1.));
|
||||
cv_count = variables.size_s();
|
||||
}
|
||||
|
||||
|
||||
BaseFunctions PIEvaluatorContent::getBaseFunction(const PIString & name) {
|
||||
if (name == PIStringAscii("sin" )) return bfSin;
|
||||
if (name == PIStringAscii("cos" )) return bfCos;
|
||||
if (name == PIStringAscii("tg" )) return bfTg;
|
||||
if (name == PIStringAscii("ctg" )) return bfCtg;
|
||||
if (name == PIStringAscii("arcsin" )) return bfArcsin;
|
||||
if (name == PIStringAscii("arccos" )) return bfArccos;
|
||||
if (name == PIStringAscii("arctg" )) return bfArctg;
|
||||
if (name == PIStringAscii("arcctg" )) return bfArcctg;
|
||||
if (name == PIStringAscii("exp" )) return bfExp;
|
||||
if (name == PIStringAscii("random" )) return bfRandom;
|
||||
if (name == PIStringAscii("sin")) return bfSin;
|
||||
if (name == PIStringAscii("cos")) return bfCos;
|
||||
if (name == PIStringAscii("tg")) return bfTg;
|
||||
if (name == PIStringAscii("ctg")) return bfCtg;
|
||||
if (name == PIStringAscii("arcsin")) return bfArcsin;
|
||||
if (name == PIStringAscii("arccos")) return bfArccos;
|
||||
if (name == PIStringAscii("arctg")) return bfArctg;
|
||||
if (name == PIStringAscii("arcctg")) return bfArcctg;
|
||||
if (name == PIStringAscii("exp")) return bfExp;
|
||||
if (name == PIStringAscii("random")) return bfRandom;
|
||||
if (name == PIStringAscii("randomn")) return bfRandomn;
|
||||
if (name == PIStringAscii("sh" )) return bfSh;
|
||||
if (name == PIStringAscii("ch" )) return bfCh;
|
||||
if (name == PIStringAscii("th" )) return bfTh;
|
||||
if (name == PIStringAscii("cth" )) return bfCth;
|
||||
if (name == PIStringAscii("sqrt" )) return bfSqrt;
|
||||
if (name == PIStringAscii("sqr" )) return bfSqr;
|
||||
if (name == PIStringAscii("pow" )) return bfPow;
|
||||
if (name == PIStringAscii("abs" )) return bfAbs;
|
||||
if (name == PIStringAscii("ln" )) return bfLn;
|
||||
if (name == PIStringAscii("lg" )) return bfLg;
|
||||
if (name == PIStringAscii("log" )) return bfLog;
|
||||
if (name == PIStringAscii("im" )) return bfIm;
|
||||
if (name == PIStringAscii("re" )) return bfRe;
|
||||
if (name == PIStringAscii("arg" )) return bfArg;
|
||||
if (name == PIStringAscii("len" )) return bfLen;
|
||||
if (name == PIStringAscii("conj" )) return bfConj;
|
||||
if (name == PIStringAscii("sign" )) return bfSign;
|
||||
if (name == PIStringAscii("rad" )) return bfRad;
|
||||
if (name == PIStringAscii("deg" )) return bfDeg;
|
||||
if (name == PIStringAscii("j0" )) return bfJ0;
|
||||
if (name == PIStringAscii("j1" )) return bfJ1;
|
||||
if (name == PIStringAscii("jn" )) return bfJN;
|
||||
if (name == PIStringAscii("y0" )) return bfY0;
|
||||
if (name == PIStringAscii("y1" )) return bfY1;
|
||||
if (name == PIStringAscii("yn" )) return bfYN;
|
||||
if (name == PIStringAscii("min" )) return bfMin;
|
||||
if (name == PIStringAscii("max" )) return bfMax;
|
||||
if (name == PIStringAscii("clamp" )) return bfClamp;
|
||||
if (name == PIStringAscii("step" )) return bfStep;
|
||||
if (name == PIStringAscii("mix" )) return bfMix;
|
||||
if (name == PIStringAscii("sh")) return bfSh;
|
||||
if (name == PIStringAscii("ch")) return bfCh;
|
||||
if (name == PIStringAscii("th")) return bfTh;
|
||||
if (name == PIStringAscii("cth")) return bfCth;
|
||||
if (name == PIStringAscii("sqrt")) return bfSqrt;
|
||||
if (name == PIStringAscii("sqr")) return bfSqr;
|
||||
if (name == PIStringAscii("pow")) return bfPow;
|
||||
if (name == PIStringAscii("abs")) return bfAbs;
|
||||
if (name == PIStringAscii("ln")) return bfLn;
|
||||
if (name == PIStringAscii("lg")) return bfLg;
|
||||
if (name == PIStringAscii("log")) return bfLog;
|
||||
if (name == PIStringAscii("im")) return bfIm;
|
||||
if (name == PIStringAscii("re")) return bfRe;
|
||||
if (name == PIStringAscii("arg")) return bfArg;
|
||||
if (name == PIStringAscii("len")) return bfLen;
|
||||
if (name == PIStringAscii("conj")) return bfConj;
|
||||
if (name == PIStringAscii("sign")) return bfSign;
|
||||
if (name == PIStringAscii("rad")) return bfRad;
|
||||
if (name == PIStringAscii("deg")) return bfDeg;
|
||||
if (name == PIStringAscii("j0")) return bfJ0;
|
||||
if (name == PIStringAscii("j1")) return bfJ1;
|
||||
if (name == PIStringAscii("jn")) return bfJN;
|
||||
if (name == PIStringAscii("y0")) return bfY0;
|
||||
if (name == PIStringAscii("y1")) return bfY1;
|
||||
if (name == PIStringAscii("yn")) return bfYN;
|
||||
if (name == PIStringAscii("min")) return bfMin;
|
||||
if (name == PIStringAscii("max")) return bfMax;
|
||||
if (name == PIStringAscii("clamp")) return bfClamp;
|
||||
if (name == PIStringAscii("step")) return bfStep;
|
||||
if (name == PIStringAscii("mix")) return bfMix;
|
||||
if (name == PIStringAscii("defined")) return bfDefined;
|
||||
if (name == PIStringAscii("round" )) return bfRound;
|
||||
if (name == PIStringAscii("round")) return bfRound;
|
||||
return bfUnknown;
|
||||
}
|
||||
|
||||
@@ -312,8 +307,10 @@ const PIString & PIEvaluator::prepare(const PIString & string) {
|
||||
replaceOperators();
|
||||
removeSpaces();
|
||||
checkBrackets();
|
||||
while (fillElements()) checkBrackets();
|
||||
while (setSignes()) fillElements();
|
||||
while (fillElements())
|
||||
checkBrackets();
|
||||
while (setSignes())
|
||||
fillElements();
|
||||
removeJunk();
|
||||
findUnknownVariables();
|
||||
return currentString;
|
||||
@@ -352,7 +349,8 @@ void PIEvaluator::removeJunk() {
|
||||
elements.pop_back();
|
||||
junk = true;
|
||||
break;
|
||||
} else break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,8 +386,10 @@ void PIEvaluator::findUnknownVariables() {
|
||||
unknownVars.clear();
|
||||
usedVars.clear();
|
||||
for (int i = 0; i < currentString.length(); i++) {
|
||||
if (elements[i].var_num >= 0) usedVars << content.variable(elements[i].var_num).name;
|
||||
else if (elements[i].var_num == -666) cvar += currentString[i];
|
||||
if (elements[i].var_num >= 0)
|
||||
usedVars << content.variable(elements[i].var_num).name;
|
||||
else if (elements[i].var_num == -666)
|
||||
cvar += currentString[i];
|
||||
else {
|
||||
if (cvar.length() == 0) continue;
|
||||
unknownVars << cvar;
|
||||
@@ -412,7 +412,6 @@ bool PIEvaluator::isSign(const PIChar & ch) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PIEvaluator::checkBrackets() {
|
||||
PIString tmps = currentString;
|
||||
PIChar fc, sc;
|
||||
@@ -427,7 +426,8 @@ void PIEvaluator::checkBrackets() {
|
||||
if (bcnt == 0) {
|
||||
currentString.insert(bpos + inserted, '(');
|
||||
inserted++;
|
||||
} else bcnt--;
|
||||
} else
|
||||
bcnt--;
|
||||
}
|
||||
}
|
||||
if (bcnt > 0) currentString += PIString(bcnt, ')');
|
||||
@@ -435,9 +435,8 @@ void PIEvaluator::checkBrackets() {
|
||||
for (int i = 0; i < tmps.length() - 1; i++) {
|
||||
fc = tmps[i].toLower();
|
||||
sc = tmps[i + 1].toLower();
|
||||
if ((fc == ')' && sc == '(') ||
|
||||
(fc == ')' && sc >= '0' && sc <= '9') ||
|
||||
(fc == ')' && sc >= 'a' && sc <= 'z') ) tmps.insert(++i, '*');
|
||||
if ((fc == ')' && sc == '(') || (fc == ')' && sc >= '0' && sc <= '9') || (fc == ')' && sc >= 'a' && sc <= 'z'))
|
||||
tmps.insert(++i, '*');
|
||||
}
|
||||
currentString = tmps;
|
||||
}
|
||||
@@ -445,20 +444,20 @@ void PIEvaluator::checkBrackets() {
|
||||
|
||||
bool PIEvaluator::fillElements() {
|
||||
int fstart, flen, cnum = 0, cpart = 0, cfunc;
|
||||
PIChar cc, nc, pc, fc = '!';
|
||||
PIChar cc, nc, pc, fc = '!';
|
||||
bool numFound = false;
|
||||
PIString curfind, tmps = currentString;
|
||||
elements.resize(tmps.length());
|
||||
for (uint i = 0; i < elements.size(); i++) {
|
||||
elements[i].type = etVariable;
|
||||
elements[i].type = etVariable;
|
||||
elements[i].var_num = -666;
|
||||
}
|
||||
currentVariables.clear();
|
||||
for (int i = 0; i < content.functionsCount(); i++) {
|
||||
curfind = content.function(i).identifier;
|
||||
cfunc = i;
|
||||
flen = curfind.length();
|
||||
fstart = 0;
|
||||
cfunc = i;
|
||||
flen = curfind.length();
|
||||
fstart = 0;
|
||||
while (fstart >= 0) {
|
||||
fstart = tmps.find(curfind, fstart);
|
||||
if (fstart < 0) break;
|
||||
@@ -479,12 +478,12 @@ bool PIEvaluator::fillElements() {
|
||||
for (int i = 0; i < content.variables.size_s(); ++i) {
|
||||
var_index << PairII(i, content.variables[i].name.length());
|
||||
}
|
||||
var_index.sort([](const PairII & v1, const PairII & v2){return v1.second > v2.second;});
|
||||
var_index.sort([](const PairII & v1, const PairII & v2) { return v1.second > v2.second; });
|
||||
for (int i = 0; i < var_index.size_s(); i++) {
|
||||
int vind = var_index[i].first;
|
||||
curfind = content.variables[vind].name;
|
||||
flen = curfind.length();
|
||||
fstart = 0;
|
||||
curfind = content.variables[vind].name;
|
||||
flen = curfind.length();
|
||||
fstart = 0;
|
||||
while (fstart >= 0) {
|
||||
fstart = tmps.find(curfind, fstart);
|
||||
if (fstart < 0) break;
|
||||
@@ -570,7 +569,7 @@ bool PIEvaluator::fillElements() {
|
||||
}
|
||||
curfind.clear();
|
||||
cnum++;
|
||||
cpart = 0;
|
||||
cpart = 0;
|
||||
numFound = false;
|
||||
}
|
||||
}
|
||||
@@ -584,24 +583,28 @@ bool PIEvaluator::fillElements() {
|
||||
cc = nc = fc;
|
||||
for (int i = 0; i < tmps.length(); i++) {
|
||||
cc = tmps[i];
|
||||
if (i > 0) pc = tmps[i - 1];
|
||||
else pc = fc;
|
||||
if (i < tmps.length() - 1) nc = tmps[i + 1];
|
||||
else nc = fc;
|
||||
if (i > 0)
|
||||
pc = tmps[i - 1];
|
||||
else
|
||||
pc = fc;
|
||||
if (i < tmps.length() - 1)
|
||||
nc = tmps[i + 1];
|
||||
else
|
||||
nc = fc;
|
||||
if (cc == '(' || cc == ')' || cc == ',') {
|
||||
elements[i].set(etOperator, -1);
|
||||
continue;
|
||||
}
|
||||
if (cc == '-' || cc == '+') {
|
||||
elements[i].set(etOperator, -1);
|
||||
if (i < tmps.length() - 1) if (elements[i + 1].type == etVariable ||
|
||||
elements[i + 1].type == etFunction) continue;
|
||||
if (i < tmps.length() - 1)
|
||||
if (elements[i + 1].type == etVariable || elements[i + 1].type == etFunction) continue;
|
||||
if ((pc == '(' || isSign(pc) || i == 0) && i < tmps.length() - 1) {
|
||||
if (elements[i + 1].type != etOperator) {
|
||||
cnum = elements[i + 1].num;
|
||||
elements[i].set(etNumber, cnum);
|
||||
tmps.replace(i, 1, fc);
|
||||
///cout << "found sign " << cc << " :" << cnum - 1 << endl;
|
||||
/// cout << "found sign " << cc << " :" << cnum - 1 << endl;
|
||||
if (cc == '-' && currentVariables.size_s() >= cnum)
|
||||
currentVariables[cnum - 1].value = -currentVariables[cnum - 1].value;
|
||||
continue;
|
||||
@@ -615,12 +618,12 @@ bool PIEvaluator::fillElements() {
|
||||
}
|
||||
/*cout << " ";
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
switch (elements[i].type) {
|
||||
case etFunction: cout << "f"; break;
|
||||
case etNumber: cout << "n"; break;
|
||||
case etOperator: cout << "o"; break;
|
||||
case etVariable: cout << "v"; break;
|
||||
}
|
||||
switch (elements[i].type) {
|
||||
case etFunction: cout << "f"; break;
|
||||
case etNumber: cout << "n"; break;
|
||||
case etOperator: cout << "o"; break;
|
||||
case etVariable: cout << "v"; break;
|
||||
}
|
||||
}
|
||||
cout << endl; */
|
||||
return false;
|
||||
@@ -633,22 +636,26 @@ bool PIEvaluator::setSignes() {
|
||||
PIString tmps = currentString;
|
||||
for (int i = 0; i < tmps.length() - 1; i++) {
|
||||
needInsert = 0;
|
||||
ni = i + 1;
|
||||
ni = i + 1;
|
||||
if (i > 0) pi = i - 1;
|
||||
fc = tmps[i].toLower();
|
||||
sc = tmps[ni].toLower();
|
||||
pc = tmps[pi].toLower();
|
||||
if (fc == ',' || sc == ',') continue;
|
||||
if (elements[i].type == etOperator && elements[ni].type == etOperator) continue;
|
||||
if (fc == ')' && (elements[ni].type == etNumber || elements[ni].type == etVariable || elements[ni].type == etFunction)) needInsert = 1;
|
||||
if (fc == ')' && (elements[ni].type == etNumber || elements[ni].type == etVariable || elements[ni].type == etFunction))
|
||||
needInsert = 1;
|
||||
if (sc == '(' && (elements[i].type == etNumber || elements[i].type == etVariable)) needInsert = 1;
|
||||
if (elements[i].type == etNumber && elements[ni].type == etNumber && elements[i].num != elements[ni].num) needInsert = 1;
|
||||
if (elements[i].type == etVariable && elements[ni].type == etVariable && elements[i].num != elements[ni].num) needInsert = 1;
|
||||
if ((elements[i].type == etNumber && elements[ni].type == etVariable) || (elements[i].type == etVariable && elements[ni].type == etNumber)) needInsert = 1;
|
||||
if ((elements[i].type == etNumber && elements[ni].type == etVariable) ||
|
||||
(elements[i].type == etVariable && elements[ni].type == etNumber))
|
||||
needInsert = 1;
|
||||
if ((elements[i].type == etNumber || elements[i].type == etVariable) && elements[ni].type == etFunction) needInsert = 1;
|
||||
if (elements[i].type == etFunction && elements[ni].type == etFunction && elements[i].num != elements[ni].num) needInsert = 2;
|
||||
if (elements[i].type == etFunction && elements[ni].type != etFunction && sc != '(') needInsert = 2;
|
||||
if (elements[pi].type == etOperator && (elements[ni].type == etFunction || elements[ni].type == etVariable) && fc == '-') needInsert = 3;
|
||||
if (elements[pi].type == etOperator && (elements[ni].type == etFunction || elements[ni].type == etVariable) && fc == '-')
|
||||
needInsert = 3;
|
||||
switch (needInsert) {
|
||||
case 1:
|
||||
currentString.insert(ni + inserted, '*');
|
||||
@@ -677,7 +684,8 @@ void PIEvaluator::convert() {
|
||||
j++;
|
||||
}
|
||||
currentString.replace(i, j - i, ' ');
|
||||
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||
for (int k = i + 1; k < j; k++)
|
||||
elements.remove(i);
|
||||
}
|
||||
for (int i = 0; i < currentString.length(); i++) {
|
||||
pe = elements[i];
|
||||
@@ -689,7 +697,8 @@ void PIEvaluator::convert() {
|
||||
j++;
|
||||
}
|
||||
currentString.replace(i, j - i, ' ');
|
||||
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||
for (int k = i + 1; k < j; k++)
|
||||
elements.remove(i);
|
||||
}
|
||||
for (int i = 0; i < currentString.length(); i++) {
|
||||
pe = elements[i];
|
||||
@@ -701,22 +710,22 @@ void PIEvaluator::convert() {
|
||||
j++;
|
||||
}
|
||||
currentString.replace(i, j - i, ' ');
|
||||
for (int k = i + 1; k < j; k++) elements.remove(i);
|
||||
for (int k = i + 1; k < j; k++)
|
||||
elements.remove(i);
|
||||
}
|
||||
/*cout << " ";
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
switch (elements[i].type) {
|
||||
case etFunction: cout << "f"; break;
|
||||
case etNumber: cout << "n"; break;
|
||||
case etOperator: cout << "o"; break;
|
||||
case etVariable: cout << "v"; break;
|
||||
}
|
||||
switch (elements[i].type) {
|
||||
case etFunction: cout << "f"; break;
|
||||
case etNumber: cout << "n"; break;
|
||||
case etOperator: cout << "o"; break;
|
||||
case etVariable: cout << "v"; break;
|
||||
}
|
||||
}
|
||||
cout << endl; */
|
||||
}
|
||||
|
||||
|
||||
|
||||
PIString PIEvaluator::preprocess(const PIString & string) {
|
||||
PIString ret;
|
||||
int lind;
|
||||
@@ -724,24 +733,24 @@ PIString PIEvaluator::preprocess(const PIString & string) {
|
||||
convert();
|
||||
instructions.clear();
|
||||
variables = currentVariables;
|
||||
lind = parse(currentString);
|
||||
lind = parse(currentString);
|
||||
if (instructions.size() == 0) {
|
||||
variables.push_back(Variable());
|
||||
instructions.push_back(Instruction(oNone, PIVector<short>(1, lind), -variables.size_s()));
|
||||
}
|
||||
/*cout << endl << "variables:" << endl;
|
||||
for (int i = 0; i < variables.size(); i++)
|
||||
cout << i << " value = " << variables[i].value << endl;
|
||||
cout << i << " value = " << variables[i].value << endl;
|
||||
|
||||
cout << endl << "instructions:" << endl;
|
||||
for (int i = 0; i < instructions.size(); i++) {
|
||||
cout << i << endl;
|
||||
cout << " operation " << instructions[i].operation << endl;
|
||||
cout << " operators: ";
|
||||
for (int j = 0; j < instructions[i].operators.size(); j++)
|
||||
cout << instructions[i].operators[j] << "; ";
|
||||
cout << endl << " function " << instructions[i].function << endl;
|
||||
cout << " out " << instructions[i].out << endl;
|
||||
cout << i << endl;
|
||||
cout << " operation " << instructions[i].operation << endl;
|
||||
cout << " operators: ";
|
||||
for (int j = 0; j < instructions[i].operators.size(); j++)
|
||||
cout << instructions[i].operators[j] << "; ";
|
||||
cout << endl << " function " << instructions[i].function << endl;
|
||||
cout << " out " << instructions[i].out << endl;
|
||||
} */
|
||||
makeOutput(ret);
|
||||
return ret;
|
||||
@@ -757,17 +766,13 @@ int PIEvaluator::parse(const PIString & string, int offset) {
|
||||
PIVector<short> args, atmp;
|
||||
PIVector<Operation> opers;
|
||||
|
||||
//cout << " "; for (int i = 0; i < slen; i++) cout << preproc->elements[i + offset].type; cout << endl;
|
||||
// cout << " "; for (int i = 0; i < slen; i++) cout << preproc->elements[i + offset].type; cout << endl;
|
||||
for (int i = 0; i < slen; i++) {
|
||||
ce = elements[i + offset];
|
||||
cc = string[i];
|
||||
switch (ce.type) {
|
||||
case etNumber:
|
||||
args.push_back(ce.var_num);
|
||||
continue;
|
||||
case etVariable:
|
||||
args.push_back(ce.var_num);
|
||||
continue;
|
||||
case etNumber: args.push_back(ce.var_num); continue;
|
||||
case etVariable: args.push_back(ce.var_num); continue;
|
||||
case etFunction:
|
||||
i++;
|
||||
cfunc = content.function(ce.var_num);
|
||||
@@ -782,21 +787,23 @@ int PIEvaluator::parse(const PIString & string, int offset) {
|
||||
case ')':
|
||||
bcnt--;
|
||||
if (bcnt == 0) {
|
||||
///qDebug() << "arument: " << carg;
|
||||
/// qDebug() << "arument: " << carg;
|
||||
atmp.push_back(parse(carg, k + offset - carg.length()));
|
||||
k++;
|
||||
carg.clear();
|
||||
if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||
if (atmp.size_s() > 0)
|
||||
if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
if (bcnt == 1) {
|
||||
///qDebug() << "arument: " << carg;
|
||||
/// qDebug() << "arument: " << carg;
|
||||
atmp.push_back(parse(carg, k + offset - carg.length()));
|
||||
k++;
|
||||
carg.clear();
|
||||
if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||
if (atmp.size_s() > 0)
|
||||
if (atmp.back() < 0 && farg > 0) farg = atmp.back();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -811,7 +818,7 @@ int PIEvaluator::parse(const PIString & string, int offset) {
|
||||
}
|
||||
instructions.push_back(Instruction(oFunction, atmp, farg, ce.var_num));
|
||||
args.push_back(farg);
|
||||
//for (int i = 0; i < args.size_s(); i++) cout << preproc->currentVariables[-args[i]].value << endl;
|
||||
// for (int i = 0; i < args.size_s(); i++) cout << preproc->currentVariables[-args[i]].value << endl;
|
||||
continue;
|
||||
case etOperator:
|
||||
if (cc == '(') {
|
||||
@@ -820,20 +827,62 @@ int PIEvaluator::parse(const PIString & string, int offset) {
|
||||
i += sbrackets.length() + 1;
|
||||
continue;
|
||||
}
|
||||
if (cc == '+') {opers.push_back(oAdd); continue;}
|
||||
if (cc == '-') {opers.push_back(oSubtract); continue;}
|
||||
if (cc == '*') {opers.push_back(oMultiply); continue;}
|
||||
if (cc == '/') {opers.push_back(oDivide); continue;}
|
||||
if (cc == '%') {opers.push_back(oResidue); continue;}
|
||||
if (cc == '^') {opers.push_back(oPower); continue;}
|
||||
if (cc == '=') {opers.push_back(oEqual); continue;}
|
||||
if (cc == ':') {opers.push_back(oNotEqual); continue;}
|
||||
if (cc == '}') {opers.push_back(oGreaterEqual); continue;}
|
||||
if (cc == '{') {opers.push_back(oSmallerEqual); continue;}
|
||||
if (cc == '>') {opers.push_back(oGreater); continue;}
|
||||
if (cc == '<') {opers.push_back(oSmaller); continue;}
|
||||
if (cc == '&') {opers.push_back(oAnd); continue;}
|
||||
if (cc == '|') {opers.push_back(oOr); continue;}
|
||||
if (cc == '+') {
|
||||
opers.push_back(oAdd);
|
||||
continue;
|
||||
}
|
||||
if (cc == '-') {
|
||||
opers.push_back(oSubtract);
|
||||
continue;
|
||||
}
|
||||
if (cc == '*') {
|
||||
opers.push_back(oMultiply);
|
||||
continue;
|
||||
}
|
||||
if (cc == '/') {
|
||||
opers.push_back(oDivide);
|
||||
continue;
|
||||
}
|
||||
if (cc == '%') {
|
||||
opers.push_back(oResidue);
|
||||
continue;
|
||||
}
|
||||
if (cc == '^') {
|
||||
opers.push_back(oPower);
|
||||
continue;
|
||||
}
|
||||
if (cc == '=') {
|
||||
opers.push_back(oEqual);
|
||||
continue;
|
||||
}
|
||||
if (cc == ':') {
|
||||
opers.push_back(oNotEqual);
|
||||
continue;
|
||||
}
|
||||
if (cc == '}') {
|
||||
opers.push_back(oGreaterEqual);
|
||||
continue;
|
||||
}
|
||||
if (cc == '{') {
|
||||
opers.push_back(oSmallerEqual);
|
||||
continue;
|
||||
}
|
||||
if (cc == '>') {
|
||||
opers.push_back(oGreater);
|
||||
continue;
|
||||
}
|
||||
if (cc == '<') {
|
||||
opers.push_back(oSmaller);
|
||||
continue;
|
||||
}
|
||||
if (cc == '&') {
|
||||
opers.push_back(oAnd);
|
||||
continue;
|
||||
}
|
||||
if (cc == '|') {
|
||||
opers.push_back(oOr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*cout << "stack: " << endl << "args: ";
|
||||
@@ -841,26 +890,34 @@ int PIEvaluator::parse(const PIString & string, int offset) {
|
||||
cout << endl << "opers: ";
|
||||
for (int i = 0; i < opers.size_s(); i++) cout << opers[i] << ", "; */
|
||||
if (opers.size_s() == 0) {
|
||||
if (args.size_s() > 0) return args.back();
|
||||
else return -666;
|
||||
if (args.size_s() > 0)
|
||||
return args.back();
|
||||
else
|
||||
return -666;
|
||||
}
|
||||
|
||||
int oprior = -1;
|
||||
PIVector<Operation> opv;
|
||||
while(1) {
|
||||
while (1) {
|
||||
operationsByPriority(++oprior, opv);
|
||||
if (opv.isEmpty()) break;
|
||||
for (int j = 0; j < opers.size_s(); j++) {
|
||||
if (!opv.contains(opers[j])) continue;
|
||||
atmp.clear();
|
||||
if (j < args.size_s() && j >= 0) atmp.push_back(args[j]);
|
||||
else atmp.push_back(-666);
|
||||
if (j + 1 < args.size_s() && j >= -1) atmp.push_back(args[j + 1]);
|
||||
else atmp.push_back(-666);
|
||||
if (j < args.size_s() && j >= 0)
|
||||
atmp.push_back(args[j]);
|
||||
else
|
||||
atmp.push_back(-666);
|
||||
if (j + 1 < args.size_s() && j >= -1)
|
||||
atmp.push_back(args[j + 1]);
|
||||
else
|
||||
atmp.push_back(-666);
|
||||
farg = 1;
|
||||
if (atmp[0] < 0) farg = atmp[0];
|
||||
if (atmp[0] < 0)
|
||||
farg = atmp[0];
|
||||
else {
|
||||
if (atmp[1] < 0) farg = atmp[1];
|
||||
if (atmp[1] < 0)
|
||||
farg = atmp[1];
|
||||
else {
|
||||
variables.push_back(Variable());
|
||||
farg = -variables.size_s();
|
||||
@@ -876,7 +933,7 @@ int PIEvaluator::parse(const PIString & string, int offset) {
|
||||
}
|
||||
}
|
||||
return instructions.back().out;
|
||||
//cout << endl;
|
||||
// cout << endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -889,13 +946,13 @@ bool PIEvaluator::check() {
|
||||
}
|
||||
for (int i = 0; i < instructions.size_s(); i++) {
|
||||
error = false;
|
||||
ci = instructions[i];
|
||||
ci = instructions[i];
|
||||
Function cf;
|
||||
int fac, gac;
|
||||
switch (ci.operation) {
|
||||
case oNone: break;
|
||||
case oFunction:
|
||||
cf = content.function(ci.function);
|
||||
cf = content.function(ci.function);
|
||||
fac = cf.arguments;
|
||||
gac = ci.operators.size_s();
|
||||
for (int j = 0; j < ci.operators.size_s(); j++) {
|
||||
@@ -906,9 +963,8 @@ bool PIEvaluator::check() {
|
||||
}
|
||||
if (fac > 0) {
|
||||
if (gac != fac) {
|
||||
lastError = PIStringAscii("Invalid arguments count for function \"") + cf.identifier +
|
||||
PIStringAscii("\", expected ") + PIString::fromNumber(fac) + PIStringAscii(" but ") +
|
||||
PIString::fromNumber(gac) + PIStringAscii(" given");
|
||||
lastError = PIStringAscii("Invalid arguments count for function \"") + cf.identifier + PIStringAscii("\", expected ") +
|
||||
PIString::fromNumber(fac) + PIStringAscii(" but ") + PIString::fromNumber(gac) + PIStringAscii(" given");
|
||||
return false;
|
||||
}
|
||||
if (error) {
|
||||
@@ -919,8 +975,8 @@ bool PIEvaluator::check() {
|
||||
if (fac < 0) {
|
||||
if (gac < -fac) {
|
||||
lastError = PIStringAscii("Invalid arguments count for function \"") + cf.identifier +
|
||||
PIStringAscii("\", expected at least ") + PIString::fromNumber(-fac) + PIStringAscii(" but ") +
|
||||
PIString::fromNumber(gac) + PIStringAscii(" given");
|
||||
PIStringAscii("\", expected at least ") + PIString::fromNumber(-fac) + PIStringAscii(" but ") +
|
||||
PIString::fromNumber(gac) + PIStringAscii(" given");
|
||||
return false;
|
||||
}
|
||||
if (error) {
|
||||
@@ -969,20 +1025,20 @@ PIString PIEvaluator::inBrackets(const PIString & string) {
|
||||
|
||||
PIString PIEvaluator::operationChar(const Operation & operation) {
|
||||
switch (operation) {
|
||||
case oAdd : return PIStringAscii("+");
|
||||
case oSubtract : return PIStringAscii("-");
|
||||
case oMultiply : return PIStringAscii("*");
|
||||
case oDivide : return PIStringAscii("/");
|
||||
case oPower : return PIStringAscii("^");
|
||||
case oResidue : return PIStringAscii("%");
|
||||
case oEqual : return PIStringAscii("=");
|
||||
case oNotEqual : return PIString::fromUTF8("≠");
|
||||
case oAdd: return PIStringAscii("+");
|
||||
case oSubtract: return PIStringAscii("-");
|
||||
case oMultiply: return PIStringAscii("*");
|
||||
case oDivide: return PIStringAscii("/");
|
||||
case oPower: return PIStringAscii("^");
|
||||
case oResidue: return PIStringAscii("%");
|
||||
case oEqual: return PIStringAscii("=");
|
||||
case oNotEqual: return PIString::fromUTF8("≠");
|
||||
case oGreaterEqual: return PIString::fromUTF8("≥");
|
||||
case oSmallerEqual: return PIString::fromUTF8("≤");
|
||||
case oGreater : return PIStringAscii(">");
|
||||
case oSmaller : return PIStringAscii("<");
|
||||
case oAnd : return PIString::fromUTF8("⋀");
|
||||
case oOr : return PIString::fromUTF8("⋁");
|
||||
case oGreater: return PIStringAscii(">");
|
||||
case oSmaller: return PIStringAscii("<");
|
||||
case oAnd: return PIString::fromUTF8("⋀");
|
||||
case oOr: return PIString::fromUTF8("⋁");
|
||||
default: break;
|
||||
}
|
||||
return PIStringAscii("???");
|
||||
@@ -1016,119 +1072,63 @@ inline void PIEvaluator::execFunction(const Instruction & ci) {
|
||||
int oi = -ci.out - 1;
|
||||
complexd tmp, stmp, ttmp;
|
||||
switch (cfunc.type) {
|
||||
case bfSin:
|
||||
tmpvars[oi].value = sin(value(ci.operators[0]));
|
||||
break;
|
||||
case bfCos:
|
||||
tmpvars[oi].value = cos(value(ci.operators[0]));
|
||||
break;
|
||||
case bfTg:
|
||||
tmpvars[oi].value = tan(value(ci.operators[0]));
|
||||
break;
|
||||
case bfSin: tmpvars[oi].value = sin(value(ci.operators[0])); break;
|
||||
case bfCos: tmpvars[oi].value = cos(value(ci.operators[0])); break;
|
||||
case bfTg: tmpvars[oi].value = tan(value(ci.operators[0])); break;
|
||||
case bfCtg:
|
||||
tmp = tan(value(ci.operators[0]));
|
||||
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = complexd_1 / tmp;
|
||||
break;
|
||||
case bfArcsin:
|
||||
tmpvars[oi].value = asinc(value(ci.operators[0]));
|
||||
break;
|
||||
case bfArccos:
|
||||
tmpvars[oi].value = acosc(value(ci.operators[0]));
|
||||
break;
|
||||
case bfArctg:
|
||||
tmpvars[oi].value = atanc(value(ci.operators[0]));
|
||||
break;
|
||||
case bfArcctg:
|
||||
tmpvars[oi].value = atanc(-value(ci.operators[0])) + M_PI_2;
|
||||
break;
|
||||
case bfSh:
|
||||
tmpvars[oi].value = sinh(value(ci.operators[0]));
|
||||
break;
|
||||
case bfCh:
|
||||
tmpvars[oi].value = cosh(value(ci.operators[0]));
|
||||
break;
|
||||
case bfTh:
|
||||
tmpvars[oi].value = tanh(value(ci.operators[0]));
|
||||
if (tmp == complexd_0)
|
||||
tmpvars[oi].value = 0.;
|
||||
else
|
||||
tmpvars[oi].value = complexd_1 / tmp;
|
||||
break;
|
||||
case bfArcsin: tmpvars[oi].value = asinc(value(ci.operators[0])); break;
|
||||
case bfArccos: tmpvars[oi].value = acosc(value(ci.operators[0])); break;
|
||||
case bfArctg: tmpvars[oi].value = atanc(value(ci.operators[0])); break;
|
||||
case bfArcctg: tmpvars[oi].value = atanc(-value(ci.operators[0])) + M_PI_2; break;
|
||||
case bfSh: tmpvars[oi].value = sinh(value(ci.operators[0])); break;
|
||||
case bfCh: tmpvars[oi].value = cosh(value(ci.operators[0])); break;
|
||||
case bfTh: tmpvars[oi].value = tanh(value(ci.operators[0])); break;
|
||||
case bfCth:
|
||||
tmp = tanh(value(ci.operators[0]));
|
||||
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = complexd_1 / tmp;
|
||||
break;
|
||||
case bfAbs:
|
||||
tmpvars[oi].value = abs(value(ci.operators[0]));
|
||||
break;
|
||||
case bfSqrt:
|
||||
tmpvars[oi].value = sqrt(value(ci.operators[0]));
|
||||
break;
|
||||
case bfSqr:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[0]);
|
||||
break;
|
||||
case bfExp:
|
||||
tmpvars[oi].value = exp(value(ci.operators[0]));
|
||||
break;
|
||||
case bfPow:
|
||||
tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1]));
|
||||
break;
|
||||
case bfLn:
|
||||
tmpvars[oi].value = log(value(ci.operators[0]));
|
||||
break;
|
||||
case bfLg:
|
||||
tmpvars[oi].value = log10(value(ci.operators[0]));
|
||||
if (tmp == complexd_0)
|
||||
tmpvars[oi].value = 0.;
|
||||
else
|
||||
tmpvars[oi].value = complexd_1 / tmp;
|
||||
break;
|
||||
case bfAbs: tmpvars[oi].value = abs(value(ci.operators[0])); break;
|
||||
case bfSqrt: tmpvars[oi].value = sqrt(value(ci.operators[0])); break;
|
||||
case bfSqr: tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[0]); break;
|
||||
case bfExp: tmpvars[oi].value = exp(value(ci.operators[0])); break;
|
||||
case bfPow: tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1])); break;
|
||||
case bfLn: tmpvars[oi].value = log(value(ci.operators[0])); break;
|
||||
case bfLg: tmpvars[oi].value = log10(value(ci.operators[0])); break;
|
||||
case bfLog:
|
||||
tmp = log(value(ci.operators[1]));
|
||||
if (tmp == complexd_0) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = log(value(ci.operators[0])) / tmp;
|
||||
break;
|
||||
case bfRe:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real();
|
||||
break;
|
||||
case bfIm:
|
||||
tmpvars[oi].value = value(ci.operators[0]).imag();
|
||||
break;
|
||||
case bfArg:
|
||||
tmpvars[oi].value = arg(value(ci.operators[0]));
|
||||
break;
|
||||
case bfLen:
|
||||
tmpvars[oi].value = abs(value(ci.operators[0]));
|
||||
break;
|
||||
case bfConj:
|
||||
tmpvars[oi].value = conj(value(ci.operators[0]));
|
||||
break;
|
||||
case bfSign:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() >= 0. ? complexd_1 : -complexd_1;
|
||||
break;
|
||||
case bfRad:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * complexd(deg2rad, 0.);
|
||||
break;
|
||||
case bfDeg:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * complexd(rad2deg, 0.);
|
||||
break;
|
||||
case bfJ0:
|
||||
tmpvars[oi].value = piJ0(value(ci.operators[0]).real());
|
||||
break;
|
||||
case bfJ1:
|
||||
tmpvars[oi].value = piJ1(value(ci.operators[0]).real());
|
||||
break;
|
||||
case bfJN:
|
||||
tmpvars[oi].value = piJn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real());
|
||||
break;
|
||||
case bfY0:
|
||||
tmpvars[oi].value = piY0(value(ci.operators[0]).real());
|
||||
break;
|
||||
case bfY1:
|
||||
tmpvars[oi].value = piY1(value(ci.operators[0]).real());
|
||||
break;
|
||||
case bfYN:
|
||||
tmpvars[oi].value = piYn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real());
|
||||
if (tmp == complexd_0)
|
||||
tmpvars[oi].value = 0.;
|
||||
else
|
||||
tmpvars[oi].value = log(value(ci.operators[0])) / tmp;
|
||||
break;
|
||||
case bfRe: tmpvars[oi].value = value(ci.operators[0]).real(); break;
|
||||
case bfIm: tmpvars[oi].value = value(ci.operators[0]).imag(); break;
|
||||
case bfArg: tmpvars[oi].value = arg(value(ci.operators[0])); break;
|
||||
case bfLen: tmpvars[oi].value = abs(value(ci.operators[0])); break;
|
||||
case bfConj: tmpvars[oi].value = conj(value(ci.operators[0])); break;
|
||||
case bfSign: tmpvars[oi].value = value(ci.operators[0]).real() >= 0. ? complexd_1 : -complexd_1; break;
|
||||
case bfRad: tmpvars[oi].value = value(ci.operators[0]) * complexd(deg2rad, 0.); break;
|
||||
case bfDeg: tmpvars[oi].value = value(ci.operators[0]) * complexd(rad2deg, 0.); break;
|
||||
case bfJ0: tmpvars[oi].value = piJ0(value(ci.operators[0]).real()); break;
|
||||
case bfJ1: tmpvars[oi].value = piJ1(value(ci.operators[0]).real()); break;
|
||||
case bfJN: tmpvars[oi].value = piJn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real()); break;
|
||||
case bfY0: tmpvars[oi].value = piY0(value(ci.operators[0]).real()); break;
|
||||
case bfY1: tmpvars[oi].value = piY1(value(ci.operators[0]).real()); break;
|
||||
case bfYN: tmpvars[oi].value = piYn(piRoundd(value(ci.operators[1]).real()), value(ci.operators[0]).real()); break;
|
||||
case bfMin:
|
||||
tmp = value(ci.operators[0]);
|
||||
for (int i = 1; i < ci.operators.size_s(); ++i) {
|
||||
stmp = value(ci.operators[i]);
|
||||
tmp = complexd(piMind(tmp.real(), stmp.real()), piMind(tmp.imag(), stmp.imag()));
|
||||
tmp = complexd(piMind(tmp.real(), stmp.real()), piMind(tmp.imag(), stmp.imag()));
|
||||
}
|
||||
tmpvars[oi].value = tmp;
|
||||
break;
|
||||
@@ -1136,37 +1136,29 @@ inline void PIEvaluator::execFunction(const Instruction & ci) {
|
||||
tmp = value(ci.operators[0]);
|
||||
for (int i = 1; i < ci.operators.size_s(); ++i) {
|
||||
stmp = value(ci.operators[i]);
|
||||
tmp = complexd(piMaxd(tmp.real(), stmp.real()), piMaxd(tmp.imag(), stmp.imag()));
|
||||
tmp = complexd(piMaxd(tmp.real(), stmp.real()), piMaxd(tmp.imag(), stmp.imag()));
|
||||
}
|
||||
tmpvars[oi].value = tmp;
|
||||
break;
|
||||
case bfClamp:
|
||||
tmp = value(ci.operators[0]);
|
||||
stmp = value(ci.operators[1]);
|
||||
ttmp = value(ci.operators[2]);
|
||||
tmp = value(ci.operators[0]);
|
||||
stmp = value(ci.operators[1]);
|
||||
ttmp = value(ci.operators[2]);
|
||||
tmpvars[oi].value = complexd(piClampd(tmp.real(), stmp.real(), ttmp.real()), piClampd(tmp.imag(), stmp.imag(), ttmp.imag()));
|
||||
break;
|
||||
case bfStep:
|
||||
tmpvars[oi].value = complexd(value(ci.operators[0]).real() >= value(ci.operators[1]).real() ? complexld_1 : complexld_0);
|
||||
break;
|
||||
case bfMix:
|
||||
tmp = value(ci.operators[0]);
|
||||
stmp = value(ci.operators[1]);
|
||||
ttmp = value(ci.operators[2]);
|
||||
tmp = value(ci.operators[0]);
|
||||
stmp = value(ci.operators[1]);
|
||||
ttmp = value(ci.operators[2]);
|
||||
tmpvars[oi].value = stmp.real() * (1. - tmp.real()) + ttmp.real() * tmp.real();
|
||||
break;
|
||||
case bfDefined:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > 0. ? complexd_1 : complexd_0;
|
||||
break;
|
||||
case bfRandom:
|
||||
tmpvars[oi].value = value(ci.operators[0]) + randomd() * value(ci.operators[1]);
|
||||
break;
|
||||
case bfRandomn:
|
||||
tmpvars[oi].value = randomn(value(ci.operators[0]).real(), value(ci.operators[1]).real());
|
||||
break;
|
||||
case bfRound:
|
||||
tmpvars[oi].value = piRoundd(value(ci.operators[0]).real());
|
||||
break;
|
||||
case bfDefined: tmpvars[oi].value = value(ci.operators[0]).real() > 0. ? complexd_1 : complexd_0; break;
|
||||
case bfRandom: tmpvars[oi].value = value(ci.operators[0]) + randomd() * value(ci.operators[1]); break;
|
||||
case bfRandomn: tmpvars[oi].value = randomn(value(ci.operators[0]).real(), value(ci.operators[1]).real()); break;
|
||||
case bfRound: tmpvars[oi].value = piRoundd(value(ci.operators[0]).real()); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -1175,74 +1167,45 @@ inline void PIEvaluator::execFunction(const Instruction & ci) {
|
||||
inline bool PIEvaluator::execInstructions() {
|
||||
int oi;
|
||||
tmpvars = variables;
|
||||
//cout << "var count " << tmpvars.size_s() << endl;
|
||||
// cout << "var count " << tmpvars.size_s() << endl;
|
||||
for (int i = 0; i < instructions.size_s(); i++) {
|
||||
const Instruction & ci(instructions[i]);
|
||||
oi = -ci.out - 1;
|
||||
//cout << value(ci.operators[0]) << operationChar(ci.operation) << value(ci.operators[1]) << ", " << oi << endl;
|
||||
// cout << value(ci.operators[0]) << operationChar(ci.operation) << value(ci.operators[1]) << ", " << oi << endl;
|
||||
switch (ci.operation) {
|
||||
case oAdd:
|
||||
tmpvars[oi].value = value(ci.operators[0]) + value(ci.operators[1]);
|
||||
break;
|
||||
case oSubtract:
|
||||
tmpvars[oi].value = value(ci.operators[0]) - value(ci.operators[1]);
|
||||
break;
|
||||
case oMultiply:
|
||||
tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]);
|
||||
break;
|
||||
case oAdd: tmpvars[oi].value = value(ci.operators[0]) + value(ci.operators[1]); break;
|
||||
case oSubtract: tmpvars[oi].value = value(ci.operators[0]) - value(ci.operators[1]); break;
|
||||
case oMultiply: tmpvars[oi].value = value(ci.operators[0]) * value(ci.operators[1]); break;
|
||||
case oDivide: {
|
||||
complexd tmp = value(ci.operators[1]);
|
||||
if (tmp == complexd(0., 0.)) tmpvars[oi].value = 0.;
|
||||
else tmpvars[oi].value = value(ci.operators[0]) / tmp;
|
||||
} break;
|
||||
case oResidue:
|
||||
tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1]));
|
||||
break;
|
||||
case oPower:
|
||||
tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1]));
|
||||
break;
|
||||
case oEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]) == value(ci.operators[1]);
|
||||
break;
|
||||
case oNotEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]) != value(ci.operators[1]);
|
||||
break;
|
||||
case oGreaterEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() >= value(ci.operators[1]).real();
|
||||
break;
|
||||
case oSmallerEqual:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() <= value(ci.operators[1]).real();
|
||||
break;
|
||||
case oGreater:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > value(ci.operators[1]).real();
|
||||
break;
|
||||
case oSmaller:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() < value(ci.operators[1]).real();
|
||||
break;
|
||||
case oAnd:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > 0. && value(ci.operators[1]).real() > 0.;
|
||||
break;
|
||||
case oOr:
|
||||
tmpvars[oi].value = value(ci.operators[0]).real() > 0. || value(ci.operators[1]).real() > 0.;
|
||||
break;
|
||||
case oFunction:
|
||||
execFunction(ci);
|
||||
break;
|
||||
case oNone:
|
||||
tmpvars[oi].value = value(ci.operators[0]);
|
||||
break;
|
||||
if (tmp == complexd(0., 0.))
|
||||
tmpvars[oi].value = 0.;
|
||||
else
|
||||
tmpvars[oi].value = value(ci.operators[0]) / tmp;
|
||||
} break;
|
||||
case oResidue: tmpvars[oi].value = residue(value(ci.operators[0]), value(ci.operators[1])); break;
|
||||
case oPower: tmpvars[oi].value = pow(value(ci.operators[0]), value(ci.operators[1])); break;
|
||||
case oEqual: tmpvars[oi].value = value(ci.operators[0]) == value(ci.operators[1]); break;
|
||||
case oNotEqual: tmpvars[oi].value = value(ci.operators[0]) != value(ci.operators[1]); break;
|
||||
case oGreaterEqual: tmpvars[oi].value = value(ci.operators[0]).real() >= value(ci.operators[1]).real(); break;
|
||||
case oSmallerEqual: tmpvars[oi].value = value(ci.operators[0]).real() <= value(ci.operators[1]).real(); break;
|
||||
case oGreater: tmpvars[oi].value = value(ci.operators[0]).real() > value(ci.operators[1]).real(); break;
|
||||
case oSmaller: tmpvars[oi].value = value(ci.operators[0]).real() < value(ci.operators[1]).real(); break;
|
||||
case oAnd: tmpvars[oi].value = value(ci.operators[0]).real() > 0. && value(ci.operators[1]).real() > 0.; break;
|
||||
case oOr: tmpvars[oi].value = value(ci.operators[0]).real() > 0. || value(ci.operators[1]).real() > 0.; break;
|
||||
case oFunction: execFunction(ci); break;
|
||||
case oNone: tmpvars[oi].value = value(ci.operators[0]); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (!instructions.isEmpty())
|
||||
out = value(instructions.back().out);
|
||||
if (!instructions.isEmpty()) out = value(instructions.back().out);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PIEvaluator::check(const PIString & string) {
|
||||
currentString = preprocess(string);
|
||||
correct = check();
|
||||
correct = check();
|
||||
if (!correct) {
|
||||
instructions.clear();
|
||||
return false;
|
||||
|
||||
@@ -5,120 +5,208 @@
|
||||
* \~russian Вычислитель математических выражений
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream calculations
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream calculations
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIEVALUATOR_H
|
||||
#define PIEVALUATOR_H
|
||||
|
||||
#include "pistringlist.h"
|
||||
#include "pimathcomplex.h"
|
||||
#include "pistringlist.h"
|
||||
|
||||
|
||||
namespace PIEvaluatorTypes {
|
||||
|
||||
typedef std::function<complexd(void * , int, complexd * )> FuncHanlder;
|
||||
typedef std::function<complexd(void *, int, complexd *)> FuncHanlder;
|
||||
|
||||
enum eType {etNumber, etOperator, etVariable, etFunction};
|
||||
enum Operation {oNone, oAdd, oSubtract, oMultiply, oDivide, oResidue, oPower,
|
||||
oEqual, oNotEqual, oGreater, oSmaller, oGreaterEqual, oSmallerEqual,
|
||||
oAnd, oOr, oFunction
|
||||
};
|
||||
enum BaseFunctions {bfUnknown, bfSin, bfCos, bfTg, bfCtg,
|
||||
bfArcsin, bfArccos, bfArctg, bfArcctg,
|
||||
bfExp, bfRandom, bfRandomn,
|
||||
bfSh, bfCh, bfTh, bfCth,
|
||||
bfSqrt, bfSqr, bfPow, bfAbs,
|
||||
bfLn, bfLg, bfLog, bfSign,
|
||||
bfIm, bfRe, bfArg, bfLen, bfConj,
|
||||
bfRad, bfDeg, bfJ0, bfJ1, bfJN,
|
||||
bfY0, bfY1, bfYN, bfMin, bfMax,
|
||||
bfClamp, bfStep, bfMix, bfDefined,
|
||||
bfRound,
|
||||
bfCustom = 0xFFFF
|
||||
};
|
||||
enum eType {
|
||||
etNumber,
|
||||
etOperator,
|
||||
etVariable,
|
||||
etFunction
|
||||
};
|
||||
enum Operation {
|
||||
oNone,
|
||||
oAdd,
|
||||
oSubtract,
|
||||
oMultiply,
|
||||
oDivide,
|
||||
oResidue,
|
||||
oPower,
|
||||
oEqual,
|
||||
oNotEqual,
|
||||
oGreater,
|
||||
oSmaller,
|
||||
oGreaterEqual,
|
||||
oSmallerEqual,
|
||||
oAnd,
|
||||
oOr,
|
||||
oFunction
|
||||
};
|
||||
enum BaseFunctions {
|
||||
bfUnknown,
|
||||
bfSin,
|
||||
bfCos,
|
||||
bfTg,
|
||||
bfCtg,
|
||||
bfArcsin,
|
||||
bfArccos,
|
||||
bfArctg,
|
||||
bfArcctg,
|
||||
bfExp,
|
||||
bfRandom,
|
||||
bfRandomn,
|
||||
bfSh,
|
||||
bfCh,
|
||||
bfTh,
|
||||
bfCth,
|
||||
bfSqrt,
|
||||
bfSqr,
|
||||
bfPow,
|
||||
bfAbs,
|
||||
bfLn,
|
||||
bfLg,
|
||||
bfLog,
|
||||
bfSign,
|
||||
bfIm,
|
||||
bfRe,
|
||||
bfArg,
|
||||
bfLen,
|
||||
bfConj,
|
||||
bfRad,
|
||||
bfDeg,
|
||||
bfJ0,
|
||||
bfJ1,
|
||||
bfJN,
|
||||
bfY0,
|
||||
bfY1,
|
||||
bfYN,
|
||||
bfMin,
|
||||
bfMax,
|
||||
bfClamp,
|
||||
bfStep,
|
||||
bfMix,
|
||||
bfDefined,
|
||||
bfRound,
|
||||
bfCustom = 0xFFFF
|
||||
};
|
||||
|
||||
struct PIP_EXPORT Instruction {
|
||||
Instruction() {out = -1; function = -1; operation = oNone;}
|
||||
Instruction(Operation oper, PIVector<short> opers, short out_ind, short func = -1) {
|
||||
operation = oper; operators = opers; out = out_ind; function = func;}
|
||||
Operation operation;
|
||||
short out;
|
||||
short function;
|
||||
PIVector<short> operators;
|
||||
};
|
||||
struct PIP_EXPORT Element {
|
||||
Element() {num = 0; var_num = -1; type = etNumber;}
|
||||
Element(eType new_type, short new_num, short new_var_num = -1) {set(new_type, new_num, new_var_num);}
|
||||
void set(eType new_type, short new_num, short new_var_num = -1) {type = new_type; num = new_num; var_num = new_var_num;}
|
||||
eType type;
|
||||
short num;
|
||||
short var_num;
|
||||
};
|
||||
struct PIP_EXPORT Function {
|
||||
Function() {arguments = 0; type = bfUnknown; handler = nullptr;}
|
||||
Function(const PIString & name, short args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype; handler = nullptr;}
|
||||
Function(const PIString & name, short args, FuncHanlder h) {identifier = name; arguments = args; type = bfCustom; handler = h;}
|
||||
PIString identifier;
|
||||
BaseFunctions type;
|
||||
FuncHanlder handler;
|
||||
short arguments;
|
||||
};
|
||||
struct PIP_EXPORT Variable {
|
||||
Variable() {value = 0.;}
|
||||
Variable(const PIString & var_name, complexd val) {name = var_name; value = val;}
|
||||
PIString name;
|
||||
complexd value;
|
||||
};
|
||||
}
|
||||
struct PIP_EXPORT Instruction {
|
||||
Instruction() {
|
||||
out = -1;
|
||||
function = -1;
|
||||
operation = oNone;
|
||||
}
|
||||
Instruction(Operation oper, PIVector<short> opers, short out_ind, short func = -1) {
|
||||
operation = oper;
|
||||
operators = opers;
|
||||
out = out_ind;
|
||||
function = func;
|
||||
}
|
||||
Operation operation;
|
||||
short out;
|
||||
short function;
|
||||
PIVector<short> operators;
|
||||
};
|
||||
struct PIP_EXPORT Element {
|
||||
Element() {
|
||||
num = 0;
|
||||
var_num = -1;
|
||||
type = etNumber;
|
||||
}
|
||||
Element(eType new_type, short new_num, short new_var_num = -1) { set(new_type, new_num, new_var_num); }
|
||||
void set(eType new_type, short new_num, short new_var_num = -1) {
|
||||
type = new_type;
|
||||
num = new_num;
|
||||
var_num = new_var_num;
|
||||
}
|
||||
eType type;
|
||||
short num;
|
||||
short var_num;
|
||||
};
|
||||
struct PIP_EXPORT Function {
|
||||
Function() {
|
||||
arguments = 0;
|
||||
type = bfUnknown;
|
||||
handler = nullptr;
|
||||
}
|
||||
Function(const PIString & name, short args, BaseFunctions ftype) {
|
||||
identifier = name;
|
||||
arguments = args;
|
||||
type = ftype;
|
||||
handler = nullptr;
|
||||
}
|
||||
Function(const PIString & name, short args, FuncHanlder h) {
|
||||
identifier = name;
|
||||
arguments = args;
|
||||
type = bfCustom;
|
||||
handler = h;
|
||||
}
|
||||
PIString identifier;
|
||||
BaseFunctions type;
|
||||
FuncHanlder handler;
|
||||
short arguments;
|
||||
};
|
||||
struct PIP_EXPORT Variable {
|
||||
Variable() { value = 0.; }
|
||||
Variable(const PIString & var_name, complexd val) {
|
||||
name = var_name;
|
||||
value = val;
|
||||
}
|
||||
PIString name;
|
||||
complexd value;
|
||||
};
|
||||
} // namespace PIEvaluatorTypes
|
||||
/*
|
||||
≠ :
|
||||
≥ }
|
||||
≤ {
|
||||
⋀ &
|
||||
⋁ |
|
||||
≠ :
|
||||
≥ }
|
||||
≤ {
|
||||
⋀ &
|
||||
⋁ |
|
||||
*/
|
||||
|
||||
class PIP_EXPORT PIEvaluatorContent
|
||||
{
|
||||
class PIP_EXPORT PIEvaluatorContent {
|
||||
friend class PIEvaluator;
|
||||
BINARY_STREAM_FRIEND(PIEvaluatorContent);
|
||||
|
||||
public:
|
||||
PIEvaluatorContent();
|
||||
~PIEvaluatorContent() {;}
|
||||
~PIEvaluatorContent() { ; }
|
||||
|
||||
void addFunction(const PIString & name, int args = 1);
|
||||
int addVariable(const PIString & name, const complexd & val = 0.);
|
||||
int addVariable(const PIString & name, const complexd & val = 0.);
|
||||
void addCustomFunction(const PIString & name, int args_count, PIEvaluatorTypes::FuncHanlder func);
|
||||
int functionsCount() const {return functions.size();}
|
||||
int variablesCount() const {return variables.size();}
|
||||
int functionsCount() const { return functions.size(); }
|
||||
int variablesCount() const { return variables.size(); }
|
||||
int customVariablesCount() const;
|
||||
int findFunction(const PIString & name) const;
|
||||
int findVariable(const PIString & var_name) const;
|
||||
PIEvaluatorTypes::Function function(int index);
|
||||
PIEvaluatorTypes::Variable variable(int index);
|
||||
PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));}
|
||||
PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));}
|
||||
PIEvaluatorTypes::Function function(const PIString & name) { return function(findFunction(name)); }
|
||||
PIEvaluatorTypes::Variable variable(const PIString & name) { return variable(findVariable(name)); }
|
||||
PIEvaluatorTypes::Variable customVariable(int index);
|
||||
bool setVariableValue(int index, complexd new_value);
|
||||
bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);}
|
||||
bool setVariableValue(const PIString & var_name, const complexd & new_value) {
|
||||
return setVariableValue(findVariable(var_name), new_value);
|
||||
}
|
||||
bool setVariableName(int index, const PIString & new_name);
|
||||
bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);}
|
||||
bool setVariableName(const PIString & var_name, const PIString & new_name) { return setVariableName(findVariable(var_name), new_name); }
|
||||
void clearCustomVariables();
|
||||
PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name);
|
||||
|
||||
@@ -128,32 +216,32 @@ private:
|
||||
PIVector<PIEvaluatorTypes::Function> functions;
|
||||
PIVector<PIEvaluatorTypes::Variable> variables;
|
||||
int cv_count;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PIP_EXPORT PIEvaluator
|
||||
{
|
||||
class PIP_EXPORT PIEvaluator {
|
||||
public:
|
||||
|
||||
//! Constructs an empty evaluator
|
||||
PIEvaluator() {correct = false; data_ = 0;}
|
||||
PIEvaluator() {
|
||||
correct = false;
|
||||
data_ = 0;
|
||||
}
|
||||
|
||||
~PIEvaluator() {;}
|
||||
~PIEvaluator() { ; }
|
||||
|
||||
|
||||
//! Returns custom data
|
||||
void * data() {return data_;}
|
||||
void * data() { return data_; }
|
||||
|
||||
//! Set custom data to "_data"
|
||||
void setData(void * _data) {data_ = _data;}
|
||||
void setData(void * _data) { data_ = _data; }
|
||||
|
||||
|
||||
//! Check mathematical expression and parse it to list of instructions
|
||||
bool check(const PIString & string);
|
||||
|
||||
//! Returns true if expression was checked succesfully
|
||||
bool isCorrect() const {return correct;}
|
||||
bool isCorrect() const { return correct; }
|
||||
|
||||
//! Set variable value with name "name" to value "value". Add variable if it doesn`t exists
|
||||
int setVariable(const PIString & name, complexd value = complexd(0.));
|
||||
@@ -165,25 +253,25 @@ public:
|
||||
complexd evaluate();
|
||||
|
||||
//! Remove all manually added variables
|
||||
void clearCustomVariables() {content.clearCustomVariables();}
|
||||
void clearCustomVariables() { content.clearCustomVariables(); }
|
||||
|
||||
//! Returns index of variable with name "name"
|
||||
int variableIndex(const PIString & name) const {return content.findVariable(name);}
|
||||
int variableIndex(const PIString & name) const { return content.findVariable(name); }
|
||||
|
||||
//! Returns all unknown variables founded in last expression passed to \a check() function
|
||||
const PIStringList & unknownVariables() const {return unknownVars;}
|
||||
const PIStringList & unknownVariables() const { return unknownVars; }
|
||||
|
||||
//! Returns all used variables founded in last expression passed to \a check() function
|
||||
const PIStringList & usedVariables() const {return usedVars;}
|
||||
const PIStringList & usedVariables() const { return usedVars; }
|
||||
|
||||
//! Returns processed last expression passed to \a check() function
|
||||
const PIString & expression() const {return currentString;}
|
||||
const PIString & expression() const { return currentString; }
|
||||
|
||||
//! Returns last error description occured in \a check() function
|
||||
const PIString & error() const {return lastError;}
|
||||
const PIString & error() const { return lastError; }
|
||||
|
||||
//! Returns last result of \a evaluate()
|
||||
const complexd & lastResult() const {return out;}
|
||||
const complexd & lastResult() const { return out; }
|
||||
|
||||
//! Save to %PIByteArray evaluator state (expression, variables, errors, compiled instructions)
|
||||
PIByteArray save() const;
|
||||
@@ -205,13 +293,24 @@ private:
|
||||
bool fillElements();
|
||||
bool setSignes();
|
||||
bool isSign(const PIChar & ch);
|
||||
PIString inverse(const PIString & string) {int len = string.length(); PIString s; for (int i = 0; i < len; i++) s += string[len - i - 1]; return s;}
|
||||
PIString inverse(const PIString & string) {
|
||||
int len = string.length();
|
||||
PIString s;
|
||||
for (int i = 0; i < len; i++)
|
||||
s += string[len - i - 1];
|
||||
return s;
|
||||
}
|
||||
bool check();
|
||||
bool execInstructions();
|
||||
PIString inBrackets(const PIString & string);
|
||||
PIString operationChar(const PIEvaluatorTypes::Operation & operation);
|
||||
void operationsByPriority(int p, PIVector<PIEvaluatorTypes::Operation> & ret);
|
||||
complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return content.variables[index].value;}
|
||||
complexd value(const int & index) {
|
||||
if (index < 0)
|
||||
return tmpvars[-index - 1].value;
|
||||
else
|
||||
return content.variables[index].value;
|
||||
}
|
||||
inline complexd residue(const complexd & f, const complexd & s);
|
||||
inline void execFunction(const PIEvaluatorTypes::Instruction & ci);
|
||||
|
||||
@@ -226,19 +325,47 @@ private:
|
||||
void * data_;
|
||||
};
|
||||
|
||||
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}
|
||||
inline bool operator !=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type != e2.type || e1.num != e2.num);}
|
||||
inline bool operator==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {
|
||||
return (e1.type == e2.type && e1.num == e2.num);
|
||||
}
|
||||
inline bool operator!=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {
|
||||
return (e1.type != e2.type || e1.num != e2.num);
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Instruction) {s << PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) << v.operators; return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorTypes::Instruction) {s >> PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) >> v.operators; return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Instruction) {
|
||||
s << PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) << v.operators;
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorTypes::Instruction) {
|
||||
s >> PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) >> v.operators;
|
||||
return s;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Element) {s << createMemoryBlock(&v); return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorTypes::Element) {s >> createMemoryBlock(&v); return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Element) {
|
||||
s << createMemoryBlock(&v);
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorTypes::Element) {
|
||||
s >> createMemoryBlock(&v);
|
||||
return s;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Variable) {s << v.name << v.value; return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorTypes::Variable) {s >> v.name >> v.value; return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Variable) {
|
||||
s << v.name << v.value;
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorTypes::Variable) {
|
||||
s >> v.name >> v.value;
|
||||
return s;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorContent) {s << v.variables << v.cv_count; return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorContent) {s >> v.variables >> v.cv_count; return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorContent) {
|
||||
s << v.variables << v.cv_count;
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorContent) {
|
||||
s >> v.variables >> v.cv_count;
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // PIEVALUATOR_H
|
||||
|
||||
@@ -1,28 +1,27 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Class for FFT, IFFT and Hilbert transformations
|
||||
Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Class for FFT, IFFT and Hilbert transformations
|
||||
Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pifft.h"
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
|
||||
PIFFT_double::PIFFT_double() {
|
||||
}
|
||||
PIFFT_double::PIFFT_double() {}
|
||||
|
||||
|
||||
PIVector<complexd> * PIFFT_double::calcFFT(const PIVector<complexd> & val) {
|
||||
@@ -45,8 +44,10 @@ PIVector<complexd> * PIFFT_double::calcHilbert(const PIVector<double> & val) {
|
||||
result.clear();
|
||||
if (val.size_s() < 4) return &result;
|
||||
fftc1r(val, val.size());
|
||||
for (uint i = 0; i < result.size() / 2; i++) result[i] = result[i] * 2.;
|
||||
for (uint i = result.size() / 2; i < result.size(); i++) result[i] = 0;
|
||||
for (uint i = 0; i < result.size() / 2; i++)
|
||||
result[i] = result[i] * 2.;
|
||||
for (uint i = result.size() / 2; i < result.size(); i++)
|
||||
result[i] = 0;
|
||||
fftc1dinv(result, result.size());
|
||||
return &result;
|
||||
}
|
||||
@@ -65,7 +66,7 @@ PIVector<double> PIFFT_double::getAmplitude() const {
|
||||
ret.resize(result.size());
|
||||
double tmp;
|
||||
for (uint i = 0; i < result.size(); i++) {
|
||||
tmp = sqrt(result[i].real() * result[i].real() + result[i].imag() * result[i].imag());
|
||||
tmp = sqrt(result[i].real() * result[i].real() + result[i].imag() * result[i].imag());
|
||||
ret[i] = tmp;
|
||||
}
|
||||
return ret;
|
||||
@@ -111,18 +112,18 @@ void PIFFT_double::fftc1r(const PIVector<double> & a, uint n) {
|
||||
if (n % 2 == 0) {
|
||||
PIVector<double> buf;
|
||||
uint n2 = n / 2;
|
||||
buf = a;
|
||||
buf = a;
|
||||
createPlan(n2);
|
||||
ftbaseexecuteplan(&buf, 0, n2, &curplan);
|
||||
result.resize(n);
|
||||
uint idx;
|
||||
complexd hn, hmnc, v;
|
||||
for (i = 0; i <= n2; i++) {
|
||||
idx = 2 * (i % n2);
|
||||
hn = complexd(buf[idx + 0], buf[idx + 1]);
|
||||
idx = 2 * ((n2 - i) % n2);
|
||||
hmnc = complexd(buf[idx + 0], -buf[idx + 1]);
|
||||
v = complexd(sin(M_PI * i / n2), cos(M_PI * i / n2));
|
||||
idx = 2 * (i % n2);
|
||||
hn = complexd(buf[idx + 0], buf[idx + 1]);
|
||||
idx = 2 * ((n2 - i) % n2);
|
||||
hmnc = complexd(buf[idx + 0], -buf[idx + 1]);
|
||||
v = complexd(sin(M_PI * i / n2), cos(M_PI * i / n2));
|
||||
result[i] = ((hn + hmnc) - (v * (hn - hmnc)));
|
||||
result[i] *= 0.5;
|
||||
}
|
||||
@@ -169,22 +170,31 @@ void PIFFT_double::ftbasegeneratecomplexfftplan(uint n, ftplan * plan) {
|
||||
int tmpmemsize;
|
||||
int stackmemsize;
|
||||
ae_int_t stackptr;
|
||||
planarraysize = 1;
|
||||
plansize = 0;
|
||||
planarraysize = 1;
|
||||
plansize = 0;
|
||||
precomputedsize = 0;
|
||||
stackmemsize = 0;
|
||||
stackptr = 0;
|
||||
tmpmemsize = 2 * n;
|
||||
stackmemsize = 0;
|
||||
stackptr = 0;
|
||||
tmpmemsize = 2 * n;
|
||||
curplan.plan.resize(planarraysize);
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
ftbase_ftbasegenerateplanrec(n, ftbase_ftbasecffttask, plan, &plansize, &precomputedsize, &planarraysize, &tmpmemsize, &stackmemsize, stackptr);
|
||||
assert(stackptr==0);
|
||||
curplan.stackbuf.resize(piMax<int>(stackmemsize, 1)); //ae_vector_set_length(&curplan.stackbuf, ae_maxint(stackmemsize, 1));
|
||||
curplan.tmpbuf.resize(piMax<int>(tmpmemsize, 1)); //ae_vector_set_length(&(curplan.tmpbuf), ae_maxint(tmpmemsize, 1));
|
||||
curplan.precomputed.resize(piMax<int>(precomputedsize, 1)); //ae_vector_set_length(&curplan.precomputed, ae_maxint(precomputedsize, 1));
|
||||
ftbase_ftbasegenerateplanrec(n,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
&plansize,
|
||||
&precomputedsize,
|
||||
&planarraysize,
|
||||
&tmpmemsize,
|
||||
&stackmemsize,
|
||||
stackptr);
|
||||
assert(stackptr == 0);
|
||||
curplan.stackbuf.resize(piMax<int>(stackmemsize, 1)); // ae_vector_set_length(&curplan.stackbuf, ae_maxint(stackmemsize, 1));
|
||||
curplan.tmpbuf.resize(piMax<int>(tmpmemsize, 1)); // ae_vector_set_length(&(curplan.tmpbuf), ae_maxint(tmpmemsize, 1));
|
||||
curplan.precomputed.resize(piMax<int>(precomputedsize, 1)); // ae_vector_set_length(&curplan.precomputed, ae_maxint(precomputedsize,
|
||||
// 1));
|
||||
stackptr = 0;
|
||||
ftbase_ftbaseprecomputeplanrec(plan, 0, stackptr);
|
||||
assert(stackptr==0);
|
||||
assert(stackptr == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -192,49 +202,49 @@ void PIFFT_double::ftbasegeneratecomplexfftplan(uint n, ftplan * plan) {
|
||||
Recurrent subroutine for the FFTGeneratePlan:
|
||||
|
||||
PARAMETERS:
|
||||
N plan size
|
||||
IsReal whether input is real or not.
|
||||
subroutine MUST NOT ignore this flag because real
|
||||
inputs comes with non-initialized imaginary parts,
|
||||
so ignoring this flag will result in corrupted output
|
||||
HalfOut whether full output or only half of it from 0 to
|
||||
floor(N/2) is needed. This flag may be ignored if
|
||||
doing so will simplify calculations
|
||||
Plan plan array
|
||||
PlanSize size of used part (in integers)
|
||||
PrecomputedSize size of precomputed array allocated yet
|
||||
PlanArraySize plan array size (actual)
|
||||
TmpMemSize temporary memory required size
|
||||
BluesteinMemSize temporary memory required size
|
||||
N plan size
|
||||
IsReal whether input is real or not.
|
||||
subroutine MUST NOT ignore this flag because real
|
||||
inputs comes with non-initialized imaginary parts,
|
||||
so ignoring this flag will result in corrupted output
|
||||
HalfOut whether full output or only half of it from 0 to
|
||||
floor(N/2) is needed. This flag may be ignored if
|
||||
doing so will simplify calculations
|
||||
Plan plan array
|
||||
PlanSize size of used part (in integers)
|
||||
PrecomputedSize size of precomputed array allocated yet
|
||||
PlanArraySize plan array size (actual)
|
||||
TmpMemSize temporary memory required size
|
||||
BluesteinMemSize temporary memory required size
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_double::ftbase_ftbasegenerateplanrec(
|
||||
int n,
|
||||
int tasktype,
|
||||
ftplan * plan,
|
||||
int * plansize,
|
||||
int * precomputedsize,
|
||||
int * planarraysize,
|
||||
int * tmpmemsize,
|
||||
int * stackmemsize,
|
||||
ae_int_t stackptr, int debugi) {
|
||||
void PIFFT_double::ftbase_ftbasegenerateplanrec(int n,
|
||||
int tasktype,
|
||||
ftplan * plan,
|
||||
int * plansize,
|
||||
int * precomputedsize,
|
||||
int * planarraysize,
|
||||
int * tmpmemsize,
|
||||
int * stackmemsize,
|
||||
ae_int_t stackptr,
|
||||
int debugi) {
|
||||
int k, m, n1, n2, esize, entryoffset;
|
||||
int ftbase_ftbaseplanentrysize = 8;
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_ftbaseplanentrysize = 8;
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
if (*plansize + ftbase_ftbaseplanentrysize > (*planarraysize)) {
|
||||
curplan.plan.resize(8 * (*planarraysize));
|
||||
*planarraysize = 8 * (*planarraysize);
|
||||
}
|
||||
entryoffset = *plansize;
|
||||
esize = ftbase_ftbaseplanentrysize;
|
||||
*plansize = *plansize + esize;
|
||||
esize = ftbase_ftbaseplanentrysize;
|
||||
*plansize = *plansize + esize;
|
||||
if (n == 1) {
|
||||
curplan.plan[entryoffset + 0] = esize;
|
||||
curplan.plan[entryoffset + 1] = -1;
|
||||
@@ -248,7 +258,7 @@ ae_int_t stackptr, int debugi) {
|
||||
}
|
||||
ftbasefactorize(n, &n1, &n2);
|
||||
if (n1 != 1) {
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * n1 * n2);
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * n1 * n2);
|
||||
curplan.plan[entryoffset + 0] = esize;
|
||||
curplan.plan[entryoffset + 1] = n1;
|
||||
curplan.plan[entryoffset + 2] = n2;
|
||||
@@ -259,9 +269,27 @@ ae_int_t stackptr, int debugi) {
|
||||
curplan.plan[entryoffset + 4] = 0;
|
||||
curplan.plan[entryoffset + 5] = *plansize;
|
||||
debugi++;
|
||||
ftbase_ftbasegenerateplanrec(n1, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr, debugi);
|
||||
ftbase_ftbasegenerateplanrec(n1,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
plansize,
|
||||
precomputedsize,
|
||||
planarraysize,
|
||||
tmpmemsize,
|
||||
stackmemsize,
|
||||
stackptr,
|
||||
debugi);
|
||||
curplan.plan[entryoffset + 6] = *plansize;
|
||||
ftbase_ftbasegenerateplanrec(n2, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr, debugi);
|
||||
ftbase_ftbasegenerateplanrec(n2,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
plansize,
|
||||
precomputedsize,
|
||||
planarraysize,
|
||||
tmpmemsize,
|
||||
stackmemsize,
|
||||
stackptr,
|
||||
debugi);
|
||||
curplan.plan[entryoffset + 7] = -1;
|
||||
return;
|
||||
} else {
|
||||
@@ -274,28 +302,34 @@ ae_int_t stackptr, int debugi) {
|
||||
curplan.plan[entryoffset + 5] = -1;
|
||||
curplan.plan[entryoffset + 6] = -1;
|
||||
curplan.plan[entryoffset + 7] = *precomputedsize;
|
||||
if (n == 3)
|
||||
*precomputedsize = *precomputedsize + 2;
|
||||
if (n == 5)
|
||||
*precomputedsize = *precomputedsize + 5;
|
||||
if (n == 3) *precomputedsize = *precomputedsize + 2;
|
||||
if (n == 5) *precomputedsize = *precomputedsize + 5;
|
||||
return;
|
||||
} else {
|
||||
k = 2 * n2 - 1;
|
||||
m = ftbasefindsmooth(k);
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * m);
|
||||
k = 2 * n2 - 1;
|
||||
m = ftbasefindsmooth(k);
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * m);
|
||||
curplan.plan[entryoffset + 0] = esize;
|
||||
curplan.plan[entryoffset + 1] = n2;
|
||||
curplan.plan[entryoffset + 2] = -1;
|
||||
curplan.plan[entryoffset + 3] = ftbase_fftbluesteinplan;
|
||||
curplan.plan[entryoffset + 4] = m;
|
||||
curplan.plan[entryoffset + 5] = *plansize;
|
||||
stackptr = stackptr + 2 * 2 * m;
|
||||
*stackmemsize = piMax<int>(*stackmemsize, stackptr);
|
||||
ftbase_ftbasegenerateplanrec(m, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr);
|
||||
stackptr = stackptr - 2 * 2 * m;
|
||||
stackptr = stackptr + 2 * 2 * m;
|
||||
*stackmemsize = piMax<int>(*stackmemsize, stackptr);
|
||||
ftbase_ftbasegenerateplanrec(m,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
plansize,
|
||||
precomputedsize,
|
||||
planarraysize,
|
||||
tmpmemsize,
|
||||
stackmemsize,
|
||||
stackptr);
|
||||
stackptr = stackptr - 2 * 2 * m;
|
||||
curplan.plan[entryoffset + 6] = -1;
|
||||
curplan.plan[entryoffset + 7] = *precomputedsize;
|
||||
*precomputedsize = *precomputedsize + 2 * m + 2 * n;
|
||||
*precomputedsize = *precomputedsize + 2 * m + 2 * n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -306,20 +340,19 @@ ae_int_t stackptr, int debugi) {
|
||||
Recurrent subroutine for precomputing FFT plans
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_double::ftbase_ftbaseprecomputeplanrec(ftplan * plan,
|
||||
int entryoffset,
|
||||
ae_int_t stackptr) {
|
||||
void PIFFT_double::ftbase_ftbaseprecomputeplanrec(ftplan * plan, int entryoffset, ae_int_t stackptr) {
|
||||
int n1, n2, n, m, offs;
|
||||
double v, bx, by;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
if ((curplan.plan[entryoffset + 3] == ftbase_fftcooleytukeyplan || curplan.plan[entryoffset + 3] == ftbase_fftrealcooleytukeyplan) || curplan.plan[entryoffset + 3] == ftbase_fhtcooleytukeyplan) {
|
||||
if ((curplan.plan[entryoffset + 3] == ftbase_fftcooleytukeyplan || curplan.plan[entryoffset + 3] == ftbase_fftrealcooleytukeyplan) ||
|
||||
curplan.plan[entryoffset + 3] == ftbase_fhtcooleytukeyplan) {
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset + 5], stackptr);
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
return;
|
||||
@@ -327,16 +360,16 @@ ae_int_t stackptr) {
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftcodeletplan || curplan.plan[entryoffset + 3] == ftbase_fhtcodeletplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
if (n == 3) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
curplan.precomputed[offs + 0] = cos(2 * M_PI / 3) - 1;
|
||||
curplan.precomputed[offs + 1] = sin(2 * M_PI / 3);
|
||||
return;
|
||||
}
|
||||
if (n == 5) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
v = 2 * M_PI / 5;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
v = 2 * M_PI / 5;
|
||||
curplan.precomputed[offs + 0] = (cos(v) + cos(2 * v)) / 2 - 1;
|
||||
curplan.precomputed[offs + 1] = (cos(v) - cos(2 * v)) / 2;
|
||||
curplan.precomputed[offs + 2] = -sin(v);
|
||||
@@ -347,16 +380,16 @@ ae_int_t stackptr) {
|
||||
}
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftbluesteinplan) {
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset + 5], stackptr);
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
for (int i = 0; i <= 2 * m - 1; i++)
|
||||
curplan.precomputed[offs + i] = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
bx = cos(M_PI * sqr(i) / n);
|
||||
by = sin(M_PI * sqr(i) / n);
|
||||
curplan.precomputed[offs + 2 * i + 0] = bx;
|
||||
curplan.precomputed[offs + 2 * i + 1] = by;
|
||||
bx = cos(M_PI * sqr(i) / n);
|
||||
by = sin(M_PI * sqr(i) / n);
|
||||
curplan.precomputed[offs + 2 * i + 0] = bx;
|
||||
curplan.precomputed[offs + 2 * i + 1] = by;
|
||||
curplan.precomputed[offs + 2 * m + 2 * i + 0] = bx;
|
||||
curplan.precomputed[offs + 2 * m + 2 * i + 1] = by;
|
||||
if (i > 0) {
|
||||
@@ -371,7 +404,7 @@ ae_int_t stackptr) {
|
||||
|
||||
|
||||
void PIFFT_double::ftbasefactorize(int n, int * n1, int * n2) {
|
||||
*n1 = *n2 = 0;
|
||||
*n1 = *n2 = 0;
|
||||
int ftbase_ftbasecodeletrecommended = 5;
|
||||
if ((*n1) * (*n2) != n) {
|
||||
for (int j = ftbase_ftbasecodeletrecommended; j >= 2; j--) {
|
||||
@@ -406,19 +439,16 @@ void PIFFT_double::ftbasefactorize(int n, int * n1, int * n2) {
|
||||
Is number smooth?
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_double::ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int * best) {
|
||||
if (seed >= n) {
|
||||
*best = piMini(*best, seed);
|
||||
return;
|
||||
}
|
||||
if (leastfactor <= 2)
|
||||
ftbase_ftbasefindsmoothrec(n, seed * 2, 2, best);
|
||||
if (leastfactor <= 3)
|
||||
ftbase_ftbasefindsmoothrec(n, seed * 3, 3, best);
|
||||
if (leastfactor <= 5)
|
||||
ftbase_ftbasefindsmoothrec(n, seed * 5, 5, best);
|
||||
if (leastfactor <= 2) ftbase_ftbasefindsmoothrec(n, seed * 2, 2, best);
|
||||
if (leastfactor <= 3) ftbase_ftbasefindsmoothrec(n, seed * 3, 3, best);
|
||||
if (leastfactor <= 5) ftbase_ftbasefindsmoothrec(n, seed * 5, 5, best);
|
||||
}
|
||||
|
||||
|
||||
@@ -435,37 +465,42 @@ int PIFFT_double::ftbasefindsmooth(int n) {
|
||||
|
||||
void PIFFT_double::ftbase_internalreallintranspose(PIVector<double> * a, int m, int n, int astart, PIVector<double> * buf) {
|
||||
ftbase_fftirltrec(a, astart, n, buf, 0, m, m, n);
|
||||
for (int i = 0; i < 2 * m * n; i++) (*a)[astart + i] = (*buf)[i];
|
||||
for (int i = 0; i < 2 * m * n; i++)
|
||||
(*a)[astart + i] = (*buf)[i];
|
||||
}
|
||||
|
||||
|
||||
void PIFFT_double::ftbase_fftirltrec(PIVector<double> * a, int astart, int astride, PIVector<double> * b, int bstart, int bstride, int m, int n) {
|
||||
void PIFFT_double::ftbase_fftirltrec(PIVector<double> * a,
|
||||
int astart,
|
||||
int astride,
|
||||
PIVector<double> * b,
|
||||
int bstart,
|
||||
int bstride,
|
||||
int m,
|
||||
int n) {
|
||||
int idx1, idx2;
|
||||
int m1, n1;
|
||||
if (m == 0 || n == 0)
|
||||
return;
|
||||
if (m == 0 || n == 0) return;
|
||||
if (piMaxi(m, n) <= 8) {
|
||||
for (int i = 0; i <= m - 1; i++) {
|
||||
idx1 = bstart + i;
|
||||
idx2 = astart + i * astride;
|
||||
for (int j = 0; j <= n - 1; j++) {
|
||||
(*b)[idx1] = a->at(idx2);
|
||||
idx1 = idx1 + bstride;
|
||||
idx2 = idx2 + 1;
|
||||
idx1 = idx1 + bstride;
|
||||
idx2 = idx2 + 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (n > m) {
|
||||
n1 = n / 2;
|
||||
if (n - n1 >= 8 && n1 % 8 != 0)
|
||||
n1 = n1 + (8 - n1 % 8);
|
||||
if (n - n1 >= 8 && n1 % 8 != 0) n1 = n1 + (8 - n1 % 8);
|
||||
ftbase_fftirltrec(a, astart, astride, b, bstart, bstride, m, n1);
|
||||
ftbase_fftirltrec(a, astart + n1, astride, b, bstart + n1 * bstride, bstride, m, n - n1);
|
||||
} else {
|
||||
m1 = m / 2;
|
||||
if (m - m1 >= 8 && m1 % 8 != 0)
|
||||
m1 = m1 + (8 - m1 % 8);
|
||||
if (m - m1 >= 8 && m1 % 8 != 0) m1 = m1 + (8 - m1 % 8);
|
||||
ftbase_fftirltrec(a, astart, astride, b, bstart, bstride, m1, n);
|
||||
ftbase_fftirltrec(a, astart + m1 * astride, astride, b, bstart + m1, bstride, m - m1, n);
|
||||
}
|
||||
@@ -479,10 +514,16 @@ void PIFFT_double::ftbase_internalcomplexlintranspose(PIVector<double> * a, int
|
||||
}
|
||||
|
||||
|
||||
void PIFFT_double::ftbase_ffticltrec(PIVector<double> * a, int astart, int astride, PIVector<double> * b, int bstart, int bstride, int m, int n) {
|
||||
void PIFFT_double::ftbase_ffticltrec(PIVector<double> * a,
|
||||
int astart,
|
||||
int astride,
|
||||
PIVector<double> * b,
|
||||
int bstart,
|
||||
int bstride,
|
||||
int m,
|
||||
int n) {
|
||||
int idx1, idx2, m2, m1, n1;
|
||||
if (m == 0 || n == 0)
|
||||
return;
|
||||
if (m == 0 || n == 0) return;
|
||||
if (piMax<int>(m, n) <= 8) {
|
||||
m2 = 2 * bstride;
|
||||
for (int i = 0; i <= m - 1; i++) {
|
||||
@@ -491,22 +532,20 @@ void PIFFT_double::ftbase_ffticltrec(PIVector<double> * a, int astart, int astri
|
||||
for (int j = 0; j <= n - 1; j++) {
|
||||
(*b)[idx1 + 0] = a->at(idx2 + 0);
|
||||
(*b)[idx1 + 1] = a->at(idx2 + 1);
|
||||
idx1 = idx1 + m2;
|
||||
idx2 = idx2 + 2;
|
||||
idx1 = idx1 + m2;
|
||||
idx2 = idx2 + 2;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (n > m) {
|
||||
n1 = n / 2;
|
||||
if (n - n1 >= 8 && n1 % 8 != 0)
|
||||
n1 = n1 + (8 - n1 % 8);
|
||||
if (n - n1 >= 8 && n1 % 8 != 0) n1 = n1 + (8 - n1 % 8);
|
||||
ftbase_ffticltrec(a, astart, astride, b, bstart, bstride, m, n1);
|
||||
ftbase_ffticltrec(a, astart + 2 * n1, astride, b, bstart + 2 * n1 * bstride, bstride, m, n - n1);
|
||||
} else {
|
||||
m1 = m / 2;
|
||||
if (m - m1 >= 8 && m1 % 8 != 0)
|
||||
m1 = m1 + (8 - m1 % 8);
|
||||
if (m - m1 >= 8 && m1 % 8 != 0) m1 = m1 + (8 - m1 % 8);
|
||||
ftbase_ffticltrec(a, astart, astride, b, bstart, bstride, m1, n);
|
||||
ftbase_ffticltrec(a, astart + 2 * m1 * astride, astride, b, bstart + 2 * m1, bstride, m - m1, n);
|
||||
}
|
||||
@@ -524,11 +563,11 @@ void PIFFT_double::ftbaseexecuteplan(PIVector<double> * a, int aoffset, int n, f
|
||||
Recurrent subroutine for the FTBaseExecutePlan
|
||||
|
||||
Parameters:
|
||||
A FFT'ed array
|
||||
AOffset offset of the FFT'ed part (distance is measured in doubles)
|
||||
A FFT'ed array
|
||||
AOffset offset of the FFT'ed part (distance is measured in doubles)
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftplan * plan, int entryoffset, ae_int_t stackptr) {
|
||||
int n1, n2, n, m, offs, offs1, offs2, offsa, offsb, offsp;
|
||||
@@ -538,17 +577,16 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
double m1x, m1y, m2x, m2y, m3x, m3y, m4x, m4y, m5x, m5y;
|
||||
double s1x, s1y, s2x, s2y, s3x, s3y, s4x, s4y, s5x, s5y;
|
||||
double c1, c2, c3, c4, c5;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
PIVector<double> & tmpb(curplan.tmpbuf);
|
||||
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftemptyplan)
|
||||
return;
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftemptyplan) return;
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftcooleytukeyplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
@@ -571,26 +609,26 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
for (int k = 0; k <= n2 - 1; k++)
|
||||
(*a)[offs + 2 * k + 1] = (*a)[offs + 2 * n2 + 2 * k + 0];
|
||||
ftbaseexecuteplanrec(a, offs, plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
tmpb[0] = (*a)[offs + 0];
|
||||
tmpb[1] = 0;
|
||||
tmpb[0] = (*a)[offs + 0];
|
||||
tmpb[1] = 0;
|
||||
tmpb[2 * n2 + 0] = (*a)[offs + 1];
|
||||
tmpb[2 * n2 + 1] = 0;
|
||||
for (int k = 1; k <= n2 - 1; k++) {
|
||||
offs1 = 2 * k;
|
||||
offs2 = 2 * n2 + 2 * k;
|
||||
hk = (*a)[offs + 2 * k + 0];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 0];
|
||||
offs1 = 2 * k;
|
||||
offs2 = 2 * n2 + 2 * k;
|
||||
hk = (*a)[offs + 2 * k + 0];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 0];
|
||||
tmpb[offs1 + 0] = 0.5 * (hk + hnk);
|
||||
tmpb[offs2 + 1] = -0.5 * (hk - hnk);
|
||||
hk = (*a)[offs + 2 * k + 1];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 1];
|
||||
hk = (*a)[offs + 2 * k + 1];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 1];
|
||||
tmpb[offs2 + 0] = 0.5 * (hk + hnk);
|
||||
tmpb[offs1 + 1] = 0.5 * (hk - hnk);
|
||||
}
|
||||
for (int k = 0; k < 2 * n2 * 2; k++) (*a)[offs + k] = tmpb[k];
|
||||
for (int k = 0; k < 2 * n2 * 2; k++)
|
||||
(*a)[offs + k] = tmpb[k];
|
||||
}
|
||||
if (n1 % 2 != 0)
|
||||
ftbaseexecuteplanrec(a, aoffset + (n1 - 1)*n2 * 2, plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
if (n1 % 2 != 0) ftbaseexecuteplanrec(a, aoffset + (n1 - 1) * n2 * 2, plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
ftbase_ffttwcalc(a, aoffset, n2, n1);
|
||||
ftbase_internalcomplexlintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
for (int i = 0; i <= n2 - 1; i++)
|
||||
@@ -601,16 +639,16 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fhtcooleytukeyplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
ftbase_internalreallintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
for (int i = 0; i <= n2 - 1; i++)
|
||||
ftbaseexecuteplanrec(a, aoffset + i * n1, plan, curplan.plan[entryoffset + 5], stackptr);
|
||||
for (int i = 0; i <= n2 - 1; i++) {
|
||||
for (int j = 0; j <= n1 - 1; j++) {
|
||||
offsa = aoffset + i * n1;
|
||||
hk = (*a)[offsa + j];
|
||||
hnk = (*a)[offsa + (n1 - j) % n1];
|
||||
offs = 2 * (i * n1 + j);
|
||||
offsa = aoffset + i * n1;
|
||||
hk = (*a)[offsa + j];
|
||||
hnk = (*a)[offsa + (n1 - j) % n1];
|
||||
offs = 2 * (i * n1 + j);
|
||||
tmpb[offs + 0] = -0.5 * (hnk - hk);
|
||||
tmpb[offs + 1] = 0.5 * (hk + hnk);
|
||||
}
|
||||
@@ -619,13 +657,13 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
for (int j = 0; j <= n1 - 1; j++)
|
||||
(*a)[aoffset + j] = tmpb[2 * j + 0] + tmpb[2 * j + 1];
|
||||
if (n2 % 2 == 0) {
|
||||
offs = 2 * (n2 / 2) * n1;
|
||||
offs = 2 * (n2 / 2) * n1;
|
||||
offsa = aoffset + n2 / 2 * n1;
|
||||
for (int j = 0; j <= n1 - 1; j++)
|
||||
(*a)[offsa + j] = tmpb[offs + 2 * j + 0] + tmpb[offs + 2 * j + 1];
|
||||
}
|
||||
for (int i = 1; i <= (n2 + 1) / 2 - 1; i++) {
|
||||
offs = 2 * i * n1;
|
||||
offs = 2 * i * n1;
|
||||
offs2 = 2 * (n2 - i) * n1;
|
||||
offsa = aoffset + i * n1;
|
||||
for (int j = 0; j <= n1 - 1; j++)
|
||||
@@ -643,16 +681,16 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftcodeletplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
if (n == 2) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
v0 = a0x + a1x;
|
||||
v1 = a0y + a1y;
|
||||
v2 = a0x - a1x;
|
||||
v3 = a0y - a1y;
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
v0 = a0x + a1x;
|
||||
v1 = a0y + a1y;
|
||||
v2 = a0x - a1x;
|
||||
v3 = a0y - a1y;
|
||||
(*a)[aoffset + 0] = v0;
|
||||
(*a)[aoffset + 1] = v1;
|
||||
(*a)[aoffset + 2] = v2;
|
||||
@@ -660,29 +698,29 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
return;
|
||||
}
|
||||
if (n == 3) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
t1x = a1x + a2x;
|
||||
t1y = a1y + a2y;
|
||||
a0x = a0x + t1x;
|
||||
a0y = a0y + t1y;
|
||||
m1x = c1 * t1x;
|
||||
m1y = c1 * t1y;
|
||||
m2x = c2 * (a1y - a2y);
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
s1y = a0y + m1y;
|
||||
a1x = s1x + m2x;
|
||||
a1y = s1y + m2y;
|
||||
a2x = s1x - m2x;
|
||||
a2y = s1y - m2y;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
t1x = a1x + a2x;
|
||||
t1y = a1y + a2y;
|
||||
a0x = a0x + t1x;
|
||||
a0y = a0y + t1y;
|
||||
m1x = c1 * t1x;
|
||||
m1y = c1 * t1y;
|
||||
m2x = c2 * (a1y - a2y);
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
s1y = a0y + m1y;
|
||||
a1x = s1x + m2x;
|
||||
a1y = s1y + m2y;
|
||||
a2x = s1x - m2x;
|
||||
a2y = s1y - m2y;
|
||||
(*a)[aoffset + 0] = a0x;
|
||||
(*a)[aoffset + 1] = a0y;
|
||||
(*a)[aoffset + 2] = a1x;
|
||||
@@ -692,22 +730,22 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
return;
|
||||
}
|
||||
if (n == 4) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
a3x = (*a)[aoffset + 6];
|
||||
a3y = (*a)[aoffset + 7];
|
||||
t1x = a0x + a2x;
|
||||
t1y = a0y + a2y;
|
||||
t2x = a1x + a3x;
|
||||
t2y = a1y + a3y;
|
||||
m2x = a0x - a2x;
|
||||
m2y = a0y - a2y;
|
||||
m3x = a1y - a3y;
|
||||
m3y = a3x - a1x;
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
a3x = (*a)[aoffset + 6];
|
||||
a3y = (*a)[aoffset + 7];
|
||||
t1x = a0x + a2x;
|
||||
t1y = a0y + a2y;
|
||||
t2x = a1x + a3x;
|
||||
t2y = a1y + a3y;
|
||||
m2x = a0x - a2x;
|
||||
m2y = a0y - a2y;
|
||||
m3x = a1y - a3y;
|
||||
m3y = a3x - a1x;
|
||||
(*a)[aoffset + 0] = t1x + t2x;
|
||||
(*a)[aoffset + 1] = t1y + t2y;
|
||||
(*a)[aoffset + 4] = t1x - t2x;
|
||||
@@ -719,44 +757,44 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
return;
|
||||
}
|
||||
if (n == 5) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 2] + (*a)[aoffset + 8];
|
||||
t1y = (*a)[aoffset + 3] + (*a)[aoffset + 9];
|
||||
t2x = (*a)[aoffset + 4] + (*a)[aoffset + 6];
|
||||
t2y = (*a)[aoffset + 5] + (*a)[aoffset + 7];
|
||||
t3x = (*a)[aoffset + 2] - (*a)[aoffset + 8];
|
||||
t3y = (*a)[aoffset + 3] - (*a)[aoffset + 9];
|
||||
t4x = (*a)[aoffset + 6] - (*a)[aoffset + 4];
|
||||
t4y = (*a)[aoffset + 7] - (*a)[aoffset + 5];
|
||||
t5x = t1x + t2x;
|
||||
t5y = t1y + t2y;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 2] + (*a)[aoffset + 8];
|
||||
t1y = (*a)[aoffset + 3] + (*a)[aoffset + 9];
|
||||
t2x = (*a)[aoffset + 4] + (*a)[aoffset + 6];
|
||||
t2y = (*a)[aoffset + 5] + (*a)[aoffset + 7];
|
||||
t3x = (*a)[aoffset + 2] - (*a)[aoffset + 8];
|
||||
t3y = (*a)[aoffset + 3] - (*a)[aoffset + 9];
|
||||
t4x = (*a)[aoffset + 6] - (*a)[aoffset + 4];
|
||||
t4y = (*a)[aoffset + 7] - (*a)[aoffset + 5];
|
||||
t5x = t1x + t2x;
|
||||
t5y = t1y + t2y;
|
||||
(*a)[aoffset + 0] = (*a)[aoffset + 0] + t5x;
|
||||
(*a)[aoffset + 1] = (*a)[aoffset + 1] + t5y;
|
||||
m1x = c1 * t5x;
|
||||
m1y = c1 * t5y;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m2y = c2 * (t1y - t2y);
|
||||
m3x = -c3 * (t3y + t4y);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
m4x = -c4 * t4y;
|
||||
m4y = c4 * t4x;
|
||||
m5x = -c5 * t3y;
|
||||
m5y = c5 * t3x;
|
||||
s3x = m3x - m4x;
|
||||
s3y = m3y - m4y;
|
||||
s5x = m3x + m5x;
|
||||
s5y = m3y + m5y;
|
||||
s1x = (*a)[aoffset + 0] + m1x;
|
||||
s1y = (*a)[aoffset + 1] + m1y;
|
||||
s2x = s1x + m2x;
|
||||
s2y = s1y + m2y;
|
||||
s4x = s1x - m2x;
|
||||
s4y = s1y - m2y;
|
||||
m1x = c1 * t5x;
|
||||
m1y = c1 * t5y;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m2y = c2 * (t1y - t2y);
|
||||
m3x = -c3 * (t3y + t4y);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
m4x = -c4 * t4y;
|
||||
m4y = c4 * t4x;
|
||||
m5x = -c5 * t3y;
|
||||
m5y = c5 * t3x;
|
||||
s3x = m3x - m4x;
|
||||
s3y = m3y - m4y;
|
||||
s5x = m3x + m5x;
|
||||
s5y = m3y + m5y;
|
||||
s1x = (*a)[aoffset + 0] + m1x;
|
||||
s1y = (*a)[aoffset + 1] + m1y;
|
||||
s2x = s1x + m2x;
|
||||
s2y = s1y + m2y;
|
||||
s4x = s1x - m2x;
|
||||
s4y = s1y - m2y;
|
||||
(*a)[aoffset + 2] = s2x + s3x;
|
||||
(*a)[aoffset + 3] = s2y + s3y;
|
||||
(*a)[aoffset + 4] = s4x + s5x;
|
||||
@@ -771,40 +809,40 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fhtcodeletplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
if (n == 2) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
(*a)[aoffset + 0] = a0x + a1x;
|
||||
(*a)[aoffset + 1] = a0x - a1x;
|
||||
return;
|
||||
}
|
||||
if (n == 3) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
t1x = a1x + a2x;
|
||||
a0x = a0x + t1x;
|
||||
m1x = c1 * t1x;
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
t1x = a1x + a2x;
|
||||
a0x = a0x + t1x;
|
||||
m1x = c1 * t1x;
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
(*a)[aoffset + 0] = a0x;
|
||||
(*a)[aoffset + 1] = s1x - m2y;
|
||||
(*a)[aoffset + 2] = s1x + m2y;
|
||||
return;
|
||||
}
|
||||
if (n == 4) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
a3x = (*a)[aoffset + 3];
|
||||
t1x = a0x + a2x;
|
||||
t2x = a1x + a3x;
|
||||
m2x = a0x - a2x;
|
||||
m3y = a3x - a1x;
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
a3x = (*a)[aoffset + 3];
|
||||
t1x = a0x + a2x;
|
||||
t2x = a1x + a3x;
|
||||
m2x = a0x - a2x;
|
||||
m3y = a3x - a1x;
|
||||
(*a)[aoffset + 0] = t1x + t2x;
|
||||
(*a)[aoffset + 1] = m2x - m3y;
|
||||
(*a)[aoffset + 2] = t1x - t2x;
|
||||
@@ -812,26 +850,26 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
return;
|
||||
}
|
||||
if (n == 5) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 1] + (*a)[aoffset + 4];
|
||||
t2x = (*a)[aoffset + 2] + (*a)[aoffset + 3];
|
||||
t3x = (*a)[aoffset + 1] - (*a)[aoffset + 4];
|
||||
t4x = (*a)[aoffset + 3] - (*a)[aoffset + 2];
|
||||
t5x = t1x + t2x;
|
||||
v0 = (*a)[aoffset + 0] + t5x;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 1] + (*a)[aoffset + 4];
|
||||
t2x = (*a)[aoffset + 2] + (*a)[aoffset + 3];
|
||||
t3x = (*a)[aoffset + 1] - (*a)[aoffset + 4];
|
||||
t4x = (*a)[aoffset + 3] - (*a)[aoffset + 2];
|
||||
t5x = t1x + t2x;
|
||||
v0 = (*a)[aoffset + 0] + t5x;
|
||||
(*a)[aoffset + 0] = v0;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
s3y = m3y - c4 * t4x;
|
||||
s5y = m3y + c5 * t3x;
|
||||
s1x = v0 + c1 * t5x;
|
||||
s2x = s1x + m2x;
|
||||
s4x = s1x - m2x;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
s3y = m3y - c4 * t4x;
|
||||
s5y = m3y + c5 * t3x;
|
||||
s1x = v0 + c1 * t5x;
|
||||
s2x = s1x + m2x;
|
||||
s4x = s1x - m2x;
|
||||
(*a)[aoffset + 1] = s2x - s3y;
|
||||
(*a)[aoffset + 2] = s4x - s5y;
|
||||
(*a)[aoffset + 3] = s4x + s5y;
|
||||
@@ -840,8 +878,8 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
}
|
||||
}
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftbluesteinplan) {
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
for (int i = stackptr + 2 * n; i <= stackptr + 2 * m - 1; i++)
|
||||
curplan.stackbuf[i] = 0;
|
||||
@@ -849,43 +887,43 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
offsa = aoffset;
|
||||
offsb = stackptr;
|
||||
for (int i = 0; i < n; i++) {
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = (*a)[offsa + 0];
|
||||
y = (*a)[offsa + 1];
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = (*a)[offsa + 0];
|
||||
y = (*a)[offsa + 1];
|
||||
curplan.stackbuf[offsb + 0] = x * bx - y * (-by);
|
||||
curplan.stackbuf[offsb + 1] = x * (-by) + y * bx;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
}
|
||||
ftbaseexecuteplanrec(&curplan.stackbuf, stackptr, plan, curplan.plan[entryoffset + 5], stackptr + 2 * 2 * m);
|
||||
offsb = stackptr;
|
||||
offsp = offs;
|
||||
for (int i = 0; i <= m - 1; i++) {
|
||||
x = curplan.stackbuf[offsb + 0];
|
||||
y = curplan.stackbuf[offsb + 1];
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = curplan.stackbuf[offsb + 0];
|
||||
y = curplan.stackbuf[offsb + 1];
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
curplan.stackbuf[offsb + 0] = x * bx - y * by;
|
||||
curplan.stackbuf[offsb + 1] = -(x * by + y * bx);
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
}
|
||||
ftbaseexecuteplanrec(&curplan.stackbuf, stackptr, plan, curplan.plan[entryoffset + 5], stackptr + 2 * 2 * m);
|
||||
offsb = stackptr;
|
||||
offsp = offs + 2 * m;
|
||||
offsa = aoffset;
|
||||
for (int i = 0; i < n; i++) {
|
||||
x = curplan.stackbuf[offsb + 0] / m;
|
||||
y = -curplan.stackbuf[offsb + 1] / m;
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = curplan.stackbuf[offsb + 0] / m;
|
||||
y = -curplan.stackbuf[offsb + 1] / m;
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
(*a)[offsa + 0] = x * bx - y * (-by);
|
||||
(*a)[offsa + 1] = x * (-by) + y * bx;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -896,54 +934,54 @@ void PIFFT_double::ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftpla
|
||||
Twiddle factors calculation
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_double::ftbase_ffttwcalc(PIVector<double> * a, int aoffset, int n1, int n2) {
|
||||
int n, idx, offs;
|
||||
double x, y, twxm1, twy, twbasexm1, twbasey, twrowxm1, twrowy, tmpx, tmpy, v;
|
||||
int ftbase_ftbaseupdatetw = 4;
|
||||
n = n1 * n2;
|
||||
v = -2 * M_PI / n;
|
||||
twbasexm1 = -2 * sqr(sin(0.5 * v));
|
||||
twbasey = sin(v);
|
||||
twrowxm1 = 0;
|
||||
twrowy = 0;
|
||||
n = n1 * n2;
|
||||
v = -2 * M_PI / n;
|
||||
twbasexm1 = -2 * sqr(sin(0.5 * v));
|
||||
twbasey = sin(v);
|
||||
twrowxm1 = 0;
|
||||
twrowy = 0;
|
||||
for (int i = 0, j = 0; i <= n2 - 1; i++) {
|
||||
twxm1 = 0;
|
||||
twy = 0;
|
||||
twy = 0;
|
||||
for (j = 0; j <= n1 - 1; j++) {
|
||||
idx = i * n1 + j;
|
||||
offs = aoffset + 2 * idx;
|
||||
x = (*a)[offs + 0];
|
||||
y = (*a)[offs + 1];
|
||||
tmpx = x * twxm1 - y * twy;
|
||||
tmpy = x * twy + y * twxm1;
|
||||
idx = i * n1 + j;
|
||||
offs = aoffset + 2 * idx;
|
||||
x = (*a)[offs + 0];
|
||||
y = (*a)[offs + 1];
|
||||
tmpx = x * twxm1 - y * twy;
|
||||
tmpy = x * twy + y * twxm1;
|
||||
(*a)[offs + 0] = x + tmpx;
|
||||
(*a)[offs + 1] = y + tmpy;
|
||||
if (j < n1 - 1) {
|
||||
if (j % ftbase_ftbaseupdatetw == 0) {
|
||||
v = -2 * M_PI * i * (j + 1) / n;
|
||||
v = -2 * M_PI * i * (j + 1) / n;
|
||||
twxm1 = -2 * sqr(sin(0.5 * v));
|
||||
twy = sin(v);
|
||||
twy = sin(v);
|
||||
} else {
|
||||
tmpx = twrowxm1 + twxm1 * twrowxm1 - twy * twrowy;
|
||||
tmpy = twrowy + twxm1 * twrowy + twy * twrowxm1;
|
||||
tmpx = twrowxm1 + twxm1 * twrowxm1 - twy * twrowy;
|
||||
tmpy = twrowy + twxm1 * twrowy + twy * twrowxm1;
|
||||
twxm1 = twxm1 + tmpx;
|
||||
twy = twy + tmpy;
|
||||
twy = twy + tmpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < n2 - 1) {
|
||||
if (j % ftbase_ftbaseupdatetw == 0) {
|
||||
v = -2 * M_PI * (i + 1) / n;
|
||||
v = -2 * M_PI * (i + 1) / n;
|
||||
twrowxm1 = -2 * sqr(sin(0.5 * v));
|
||||
twrowy = sin(v);
|
||||
twrowy = sin(v);
|
||||
} else {
|
||||
tmpx = twbasexm1 + twrowxm1 * twbasexm1 - twrowy * twbasey;
|
||||
tmpy = twbasey + twrowxm1 * twbasey + twrowy * twbasexm1;
|
||||
tmpx = twbasexm1 + twrowxm1 * twbasexm1 - twrowy * twbasey;
|
||||
tmpy = twbasey + twrowxm1 * twbasey + twrowy * twbasexm1;
|
||||
twrowxm1 = twrowxm1 + tmpx;
|
||||
twrowy = twrowy + tmpy;
|
||||
twrowy = twrowy + tmpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -957,8 +995,7 @@ void PIFFT_double::ftbase_ffttwcalc(PIVector<double> * a, int aoffset, int n1, i
|
||||
//=================================================================================================
|
||||
|
||||
|
||||
PIFFT_float::PIFFT_float() {
|
||||
}
|
||||
PIFFT_float::PIFFT_float() {}
|
||||
|
||||
|
||||
PIVector<complexf> * PIFFT_float::calcFFT(const PIVector<complexf> & val) {
|
||||
@@ -981,8 +1018,10 @@ PIVector<complexf> * PIFFT_float::calcHilbert(const PIVector<float> & val) {
|
||||
result.clear();
|
||||
if (val.size_s() < 4) return &result;
|
||||
fftc1r(val, val.size());
|
||||
for (uint i = 0; i < result.size() / 2; i++) result[i] = result[i] * 2.f;
|
||||
for (uint i = result.size() / 2; i < result.size(); i++) result[i] = 0;
|
||||
for (uint i = 0; i < result.size() / 2; i++)
|
||||
result[i] = result[i] * 2.f;
|
||||
for (uint i = result.size() / 2; i < result.size(); i++)
|
||||
result[i] = 0;
|
||||
fftc1dinv(result, result.size());
|
||||
return &result;
|
||||
}
|
||||
@@ -1001,7 +1040,7 @@ PIVector<float> PIFFT_float::getAmplitude() const {
|
||||
ret.resize(result.size());
|
||||
float tmp;
|
||||
for (uint i = 0; i < result.size(); i++) {
|
||||
tmp = sqrt(result[i].real() * result[i].real() + result[i].imag() * result[i].imag());
|
||||
tmp = sqrt(result[i].real() * result[i].real() + result[i].imag() * result[i].imag());
|
||||
ret[i] = tmp;
|
||||
}
|
||||
return ret;
|
||||
@@ -1047,18 +1086,18 @@ void PIFFT_float::fftc1r(const PIVector<float> & a, uint n) {
|
||||
if (n % 2 == 0) {
|
||||
PIVector<float> buf;
|
||||
uint n2 = n / 2;
|
||||
buf = a;
|
||||
buf = a;
|
||||
createPlan(n2);
|
||||
ftbaseexecuteplan(&buf, 0, n2, &curplan);
|
||||
result.resize(n);
|
||||
uint idx;
|
||||
complexf hn, hmnc, v;
|
||||
for (i = 0; i <= n2; i++) {
|
||||
idx = 2 * (i % n2);
|
||||
hn = complexf(buf[idx + 0], buf[idx + 1]);
|
||||
idx = 2 * ((n2 - i) % n2);
|
||||
hmnc = complexf(buf[idx + 0], -buf[idx + 1]);
|
||||
v = complexf(sin(M_PI * i / n2), cos(M_PI * i / n2));
|
||||
idx = 2 * (i % n2);
|
||||
hn = complexf(buf[idx + 0], buf[idx + 1]);
|
||||
idx = 2 * ((n2 - i) % n2);
|
||||
hmnc = complexf(buf[idx + 0], -buf[idx + 1]);
|
||||
v = complexf(sin(M_PI * i / n2), cos(M_PI * i / n2));
|
||||
result[i] = ((hn + hmnc) - (v * (hn - hmnc)));
|
||||
result[i] *= 0.5;
|
||||
}
|
||||
@@ -1105,22 +1144,31 @@ void PIFFT_float::ftbasegeneratecomplexfftplan(uint n, ftplan * plan) {
|
||||
int tmpmemsize;
|
||||
int stackmemsize;
|
||||
ae_int_t stackptr;
|
||||
planarraysize = 1;
|
||||
plansize = 0;
|
||||
planarraysize = 1;
|
||||
plansize = 0;
|
||||
precomputedsize = 0;
|
||||
stackmemsize = 0;
|
||||
stackptr = 0;
|
||||
tmpmemsize = 2 * n;
|
||||
stackmemsize = 0;
|
||||
stackptr = 0;
|
||||
tmpmemsize = 2 * n;
|
||||
curplan.plan.resize(planarraysize);
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
ftbase_ftbasegenerateplanrec(n, ftbase_ftbasecffttask, plan, &plansize, &precomputedsize, &planarraysize, &tmpmemsize, &stackmemsize, stackptr);
|
||||
assertm(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan");
|
||||
curplan.stackbuf.resize(piMax<int>(stackmemsize, 1)); //ae_vector_set_length(&curplan.stackbuf, ae_maxint(stackmemsize, 1));
|
||||
curplan.tmpbuf.resize(piMax<int>(tmpmemsize, 1)); //ae_vector_set_length(&(curplan.tmpbuf), ae_maxint(tmpmemsize, 1));
|
||||
curplan.precomputed.resize(piMax<int>(precomputedsize, 1)); //ae_vector_set_length(&curplan.precomputed, ae_maxint(precomputedsize, 1));
|
||||
ftbase_ftbasegenerateplanrec(n,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
&plansize,
|
||||
&precomputedsize,
|
||||
&planarraysize,
|
||||
&tmpmemsize,
|
||||
&stackmemsize,
|
||||
stackptr);
|
||||
assertm(stackptr == 0, "Internal error in FTBaseGenerateComplexFFTPlan");
|
||||
curplan.stackbuf.resize(piMax<int>(stackmemsize, 1)); // ae_vector_set_length(&curplan.stackbuf, ae_maxint(stackmemsize, 1));
|
||||
curplan.tmpbuf.resize(piMax<int>(tmpmemsize, 1)); // ae_vector_set_length(&(curplan.tmpbuf), ae_maxint(tmpmemsize, 1));
|
||||
curplan.precomputed.resize(piMax<int>(precomputedsize, 1)); // ae_vector_set_length(&curplan.precomputed, ae_maxint(precomputedsize,
|
||||
// 1));
|
||||
stackptr = 0;
|
||||
ftbase_ftbaseprecomputeplanrec(plan, 0, stackptr);
|
||||
assertm(stackptr==0, "Internal error in FTBaseGenerateComplexFFTPlan");
|
||||
assertm(stackptr == 0, "Internal error in FTBaseGenerateComplexFFTPlan");
|
||||
}
|
||||
|
||||
|
||||
@@ -1128,49 +1176,49 @@ void PIFFT_float::ftbasegeneratecomplexfftplan(uint n, ftplan * plan) {
|
||||
Recurrent subroutine for the FFTGeneratePlan:
|
||||
|
||||
PARAMETERS:
|
||||
N plan size
|
||||
IsReal whether input is real or not.
|
||||
subroutine MUST NOT ignore this flag because real
|
||||
inputs comes with non-initialized imaginary parts,
|
||||
so ignoring this flag will result in corrupted output
|
||||
HalfOut whether full output or only half of it from 0 to
|
||||
floor(N/2) is needed. This flag may be ignored if
|
||||
doing so will simplify calculations
|
||||
Plan plan array
|
||||
PlanSize size of used part (in integers)
|
||||
PrecomputedSize size of precomputed array allocated yet
|
||||
PlanArraySize plan array size (actual)
|
||||
TmpMemSize temporary memory required size
|
||||
BluesteinMemSize temporary memory required size
|
||||
N plan size
|
||||
IsReal whether input is real or not.
|
||||
subroutine MUST NOT ignore this flag because real
|
||||
inputs comes with non-initialized imaginary parts,
|
||||
so ignoring this flag will result in corrupted output
|
||||
HalfOut whether full output or only half of it from 0 to
|
||||
floor(N/2) is needed. This flag may be ignored if
|
||||
doing so will simplify calculations
|
||||
Plan plan array
|
||||
PlanSize size of used part (in integers)
|
||||
PrecomputedSize size of precomputed array allocated yet
|
||||
PlanArraySize plan array size (actual)
|
||||
TmpMemSize temporary memory required size
|
||||
BluesteinMemSize temporary memory required size
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_float::ftbase_ftbasegenerateplanrec(
|
||||
int n,
|
||||
int tasktype,
|
||||
ftplan * plan,
|
||||
int * plansize,
|
||||
int * precomputedsize,
|
||||
int * planarraysize,
|
||||
int * tmpmemsize,
|
||||
int * stackmemsize,
|
||||
ae_int_t stackptr, int debugi) {
|
||||
void PIFFT_float::ftbase_ftbasegenerateplanrec(int n,
|
||||
int tasktype,
|
||||
ftplan * plan,
|
||||
int * plansize,
|
||||
int * precomputedsize,
|
||||
int * planarraysize,
|
||||
int * tmpmemsize,
|
||||
int * stackmemsize,
|
||||
ae_int_t stackptr,
|
||||
int debugi) {
|
||||
int k, m, n1, n2, esize, entryoffset;
|
||||
int ftbase_ftbaseplanentrysize = 4;
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_ftbaseplanentrysize = 4;
|
||||
int ftbase_ftbasecffttask = 0;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
if (*plansize + ftbase_ftbaseplanentrysize > (*planarraysize)) {
|
||||
curplan.plan.resize(4 * (*planarraysize));
|
||||
*planarraysize = 4 * (*planarraysize);
|
||||
}
|
||||
entryoffset = *plansize;
|
||||
esize = ftbase_ftbaseplanentrysize;
|
||||
*plansize = *plansize + esize;
|
||||
esize = ftbase_ftbaseplanentrysize;
|
||||
*plansize = *plansize + esize;
|
||||
if (n == 1) {
|
||||
curplan.plan[entryoffset + 0] = esize;
|
||||
curplan.plan[entryoffset + 1] = -1;
|
||||
@@ -1184,7 +1232,7 @@ ae_int_t stackptr, int debugi) {
|
||||
}
|
||||
ftbasefactorize(n, &n1, &n2);
|
||||
if (n1 != 1) {
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * n1 * n2);
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * n1 * n2);
|
||||
curplan.plan[entryoffset + 0] = esize;
|
||||
curplan.plan[entryoffset + 1] = n1;
|
||||
curplan.plan[entryoffset + 2] = n2;
|
||||
@@ -1195,9 +1243,27 @@ ae_int_t stackptr, int debugi) {
|
||||
curplan.plan[entryoffset + 4] = 0;
|
||||
curplan.plan[entryoffset + 5] = *plansize;
|
||||
debugi++;
|
||||
ftbase_ftbasegenerateplanrec(n1, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr, debugi);
|
||||
ftbase_ftbasegenerateplanrec(n1,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
plansize,
|
||||
precomputedsize,
|
||||
planarraysize,
|
||||
tmpmemsize,
|
||||
stackmemsize,
|
||||
stackptr,
|
||||
debugi);
|
||||
curplan.plan[entryoffset + 6] = *plansize;
|
||||
ftbase_ftbasegenerateplanrec(n2, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr, debugi);
|
||||
ftbase_ftbasegenerateplanrec(n2,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
plansize,
|
||||
precomputedsize,
|
||||
planarraysize,
|
||||
tmpmemsize,
|
||||
stackmemsize,
|
||||
stackptr,
|
||||
debugi);
|
||||
curplan.plan[entryoffset + 7] = -1;
|
||||
return;
|
||||
} else {
|
||||
@@ -1210,28 +1276,34 @@ ae_int_t stackptr, int debugi) {
|
||||
curplan.plan[entryoffset + 5] = -1;
|
||||
curplan.plan[entryoffset + 6] = -1;
|
||||
curplan.plan[entryoffset + 7] = *precomputedsize;
|
||||
if (n == 3)
|
||||
*precomputedsize = *precomputedsize + 2;
|
||||
if (n == 5)
|
||||
*precomputedsize = *precomputedsize + 5;
|
||||
if (n == 3) *precomputedsize = *precomputedsize + 2;
|
||||
if (n == 5) *precomputedsize = *precomputedsize + 5;
|
||||
return;
|
||||
} else {
|
||||
k = 2 * n2 - 1;
|
||||
m = ftbasefindsmooth(k);
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * m);
|
||||
k = 2 * n2 - 1;
|
||||
m = ftbasefindsmooth(k);
|
||||
*tmpmemsize = piMax<int>(*tmpmemsize, 2 * m);
|
||||
curplan.plan[entryoffset + 0] = esize;
|
||||
curplan.plan[entryoffset + 1] = n2;
|
||||
curplan.plan[entryoffset + 2] = -1;
|
||||
curplan.plan[entryoffset + 3] = ftbase_fftbluesteinplan;
|
||||
curplan.plan[entryoffset + 4] = m;
|
||||
curplan.plan[entryoffset + 5] = *plansize;
|
||||
stackptr = stackptr + 2 * 2 * m;
|
||||
*stackmemsize = piMax<int>(*stackmemsize, stackptr);
|
||||
ftbase_ftbasegenerateplanrec(m, ftbase_ftbasecffttask, plan, plansize, precomputedsize, planarraysize, tmpmemsize, stackmemsize, stackptr);
|
||||
stackptr = stackptr - 2 * 2 * m;
|
||||
stackptr = stackptr + 2 * 2 * m;
|
||||
*stackmemsize = piMax<int>(*stackmemsize, stackptr);
|
||||
ftbase_ftbasegenerateplanrec(m,
|
||||
ftbase_ftbasecffttask,
|
||||
plan,
|
||||
plansize,
|
||||
precomputedsize,
|
||||
planarraysize,
|
||||
tmpmemsize,
|
||||
stackmemsize,
|
||||
stackptr);
|
||||
stackptr = stackptr - 2 * 2 * m;
|
||||
curplan.plan[entryoffset + 6] = -1;
|
||||
curplan.plan[entryoffset + 7] = *precomputedsize;
|
||||
*precomputedsize = *precomputedsize + 2 * m + 2 * n;
|
||||
*precomputedsize = *precomputedsize + 2 * m + 2 * n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1242,20 +1314,19 @@ ae_int_t stackptr, int debugi) {
|
||||
Recurrent subroutine for precomputing FFT plans
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_float::ftbase_ftbaseprecomputeplanrec(ftplan * plan,
|
||||
int entryoffset,
|
||||
ae_int_t stackptr) {
|
||||
void PIFFT_float::ftbase_ftbaseprecomputeplanrec(ftplan * plan, int entryoffset, ae_int_t stackptr) {
|
||||
int n1, n2, n, m, offs;
|
||||
float v, bx, by;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
if ((curplan.plan[entryoffset + 3] == ftbase_fftcooleytukeyplan || curplan.plan[entryoffset + 3] == ftbase_fftrealcooleytukeyplan) || curplan.plan[entryoffset + 3] == ftbase_fhtcooleytukeyplan) {
|
||||
if ((curplan.plan[entryoffset + 3] == ftbase_fftcooleytukeyplan || curplan.plan[entryoffset + 3] == ftbase_fftrealcooleytukeyplan) ||
|
||||
curplan.plan[entryoffset + 3] == ftbase_fhtcooleytukeyplan) {
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset + 5], stackptr);
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
return;
|
||||
@@ -1263,16 +1334,16 @@ ae_int_t stackptr) {
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftcodeletplan || curplan.plan[entryoffset + 3] == ftbase_fhtcodeletplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
if (n == 3) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
curplan.precomputed[offs + 0] = cos(2 * M_PI / 3) - 1;
|
||||
curplan.precomputed[offs + 1] = sin(2 * M_PI / 3);
|
||||
return;
|
||||
}
|
||||
if (n == 5) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
v = 2 * M_PI / 5;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
v = 2 * M_PI / 5;
|
||||
curplan.precomputed[offs + 0] = (cos(v) + cos(2 * v)) / 2 - 1;
|
||||
curplan.precomputed[offs + 1] = (cos(v) - cos(2 * v)) / 2;
|
||||
curplan.precomputed[offs + 2] = -sin(v);
|
||||
@@ -1283,16 +1354,16 @@ ae_int_t stackptr) {
|
||||
}
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftbluesteinplan) {
|
||||
ftbase_ftbaseprecomputeplanrec(plan, curplan.plan[entryoffset + 5], stackptr);
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
for (int i = 0; i <= 2 * m - 1; i++)
|
||||
curplan.precomputed[offs + i] = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
bx = cos(M_PI * sqr(i) / n);
|
||||
by = sin(M_PI * sqr(i) / n);
|
||||
curplan.precomputed[offs + 2 * i + 0] = bx;
|
||||
curplan.precomputed[offs + 2 * i + 1] = by;
|
||||
bx = cos(M_PI * sqr(i) / n);
|
||||
by = sin(M_PI * sqr(i) / n);
|
||||
curplan.precomputed[offs + 2 * i + 0] = bx;
|
||||
curplan.precomputed[offs + 2 * i + 1] = by;
|
||||
curplan.precomputed[offs + 2 * m + 2 * i + 0] = bx;
|
||||
curplan.precomputed[offs + 2 * m + 2 * i + 1] = by;
|
||||
if (i > 0) {
|
||||
@@ -1307,7 +1378,7 @@ ae_int_t stackptr) {
|
||||
|
||||
|
||||
void PIFFT_float::ftbasefactorize(int n, int * n1, int * n2) {
|
||||
*n1 = *n2 = 0;
|
||||
*n1 = *n2 = 0;
|
||||
int ftbase_ftbasecodeletrecommended = 5;
|
||||
if ((*n1) * (*n2) != n) {
|
||||
for (int j = ftbase_ftbasecodeletrecommended; j >= 2; j--) {
|
||||
@@ -1342,19 +1413,16 @@ void PIFFT_float::ftbasefactorize(int n, int * n1, int * n2) {
|
||||
Is number smooth?
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_float::ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int * best) {
|
||||
if (seed >= n) {
|
||||
*best = piMini(*best, seed);
|
||||
return;
|
||||
}
|
||||
if (leastfactor <= 2)
|
||||
ftbase_ftbasefindsmoothrec(n, seed * 2, 2, best);
|
||||
if (leastfactor <= 3)
|
||||
ftbase_ftbasefindsmoothrec(n, seed * 3, 3, best);
|
||||
if (leastfactor <= 5)
|
||||
ftbase_ftbasefindsmoothrec(n, seed * 5, 5, best);
|
||||
if (leastfactor <= 2) ftbase_ftbasefindsmoothrec(n, seed * 2, 2, best);
|
||||
if (leastfactor <= 3) ftbase_ftbasefindsmoothrec(n, seed * 3, 3, best);
|
||||
if (leastfactor <= 5) ftbase_ftbasefindsmoothrec(n, seed * 5, 5, best);
|
||||
}
|
||||
|
||||
|
||||
@@ -1371,37 +1439,42 @@ int PIFFT_float::ftbasefindsmooth(int n) {
|
||||
|
||||
void PIFFT_float::ftbase_internalreallintranspose(PIVector<float> * a, int m, int n, int astart, PIVector<float> * buf) {
|
||||
ftbase_fftirltrec(a, astart, n, buf, 0, m, m, n);
|
||||
for (int i = 0; i < 2 * m * n; i++) (*a)[astart + i] = (*buf)[i];
|
||||
for (int i = 0; i < 2 * m * n; i++)
|
||||
(*a)[astart + i] = (*buf)[i];
|
||||
}
|
||||
|
||||
|
||||
void PIFFT_float::ftbase_fftirltrec(PIVector<float> * a, int astart, int astride, PIVector<float> * b, int bstart, int bstride, int m, int n) {
|
||||
void PIFFT_float::ftbase_fftirltrec(PIVector<float> * a,
|
||||
int astart,
|
||||
int astride,
|
||||
PIVector<float> * b,
|
||||
int bstart,
|
||||
int bstride,
|
||||
int m,
|
||||
int n) {
|
||||
int idx1, idx2;
|
||||
int m1, n1;
|
||||
if (m == 0 || n == 0)
|
||||
return;
|
||||
if (m == 0 || n == 0) return;
|
||||
if (piMaxi(m, n) <= 8) {
|
||||
for (int i = 0; i <= m - 1; i++) {
|
||||
idx1 = bstart + i;
|
||||
idx2 = astart + i * astride;
|
||||
for (int j = 0; j <= n - 1; j++) {
|
||||
(*b)[idx1] = a->at(idx2);
|
||||
idx1 = idx1 + bstride;
|
||||
idx2 = idx2 + 1;
|
||||
idx1 = idx1 + bstride;
|
||||
idx2 = idx2 + 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (n > m) {
|
||||
n1 = n / 2;
|
||||
if (n - n1 >= 8 && n1 % 8 != 0)
|
||||
n1 = n1 + (8 - n1 % 8);
|
||||
if (n - n1 >= 8 && n1 % 8 != 0) n1 = n1 + (8 - n1 % 8);
|
||||
ftbase_fftirltrec(a, astart, astride, b, bstart, bstride, m, n1);
|
||||
ftbase_fftirltrec(a, astart + n1, astride, b, bstart + n1 * bstride, bstride, m, n - n1);
|
||||
} else {
|
||||
m1 = m / 2;
|
||||
if (m - m1 >= 8 && m1 % 8 != 0)
|
||||
m1 = m1 + (8 - m1 % 8);
|
||||
if (m - m1 >= 8 && m1 % 8 != 0) m1 = m1 + (8 - m1 % 8);
|
||||
ftbase_fftirltrec(a, astart, astride, b, bstart, bstride, m1, n);
|
||||
ftbase_fftirltrec(a, astart + m1 * astride, astride, b, bstart + m1, bstride, m - m1, n);
|
||||
}
|
||||
@@ -1415,10 +1488,16 @@ void PIFFT_float::ftbase_internalcomplexlintranspose(PIVector<float> * a, int m,
|
||||
}
|
||||
|
||||
|
||||
void PIFFT_float::ftbase_ffticltrec(PIVector<float> * a, int astart, int astride, PIVector<float> * b, int bstart, int bstride, int m, int n) {
|
||||
void PIFFT_float::ftbase_ffticltrec(PIVector<float> * a,
|
||||
int astart,
|
||||
int astride,
|
||||
PIVector<float> * b,
|
||||
int bstart,
|
||||
int bstride,
|
||||
int m,
|
||||
int n) {
|
||||
int idx1, idx2, m2, m1, n1;
|
||||
if (m == 0 || n == 0)
|
||||
return;
|
||||
if (m == 0 || n == 0) return;
|
||||
if (piMax<int>(m, n) <= 8) {
|
||||
m2 = 2 * bstride;
|
||||
for (int i = 0; i <= m - 1; i++) {
|
||||
@@ -1427,22 +1506,20 @@ void PIFFT_float::ftbase_ffticltrec(PIVector<float> * a, int astart, int astride
|
||||
for (int j = 0; j <= n - 1; j++) {
|
||||
(*b)[idx1 + 0] = a->at(idx2 + 0);
|
||||
(*b)[idx1 + 1] = a->at(idx2 + 1);
|
||||
idx1 = idx1 + m2;
|
||||
idx2 = idx2 + 2;
|
||||
idx1 = idx1 + m2;
|
||||
idx2 = idx2 + 2;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (n > m) {
|
||||
n1 = n / 2;
|
||||
if (n - n1 >= 8 && n1 % 8 != 0)
|
||||
n1 = n1 + (8 - n1 % 8);
|
||||
if (n - n1 >= 8 && n1 % 8 != 0) n1 = n1 + (8 - n1 % 8);
|
||||
ftbase_ffticltrec(a, astart, astride, b, bstart, bstride, m, n1);
|
||||
ftbase_ffticltrec(a, astart + 2 * n1, astride, b, bstart + 2 * n1 * bstride, bstride, m, n - n1);
|
||||
} else {
|
||||
m1 = m / 2;
|
||||
if (m - m1 >= 8 && m1 % 8 != 0)
|
||||
m1 = m1 + (8 - m1 % 8);
|
||||
if (m - m1 >= 8 && m1 % 8 != 0) m1 = m1 + (8 - m1 % 8);
|
||||
ftbase_ffticltrec(a, astart, astride, b, bstart, bstride, m1, n);
|
||||
ftbase_ffticltrec(a, astart + 2 * m1 * astride, astride, b, bstart + 2 * m1, bstride, m - m1, n);
|
||||
}
|
||||
@@ -1460,11 +1537,11 @@ void PIFFT_float::ftbaseexecuteplan(PIVector<float> * a, int aoffset, int n, ftp
|
||||
Recurrent subroutine for the FTBaseExecutePlan
|
||||
|
||||
Parameters:
|
||||
A FFT'ed array
|
||||
AOffset offset of the FFT'ed part (distance is measured in floats)
|
||||
A FFT'ed array
|
||||
AOffset offset of the FFT'ed part (distance is measured in floats)
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan * plan, int entryoffset, ae_int_t stackptr) {
|
||||
int n1, n2, n, m, offs, offs1, offs2, offsa, offsb, offsp;
|
||||
@@ -1474,17 +1551,16 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
float m1x, m1y, m2x, m2y, m3x, m3y, m4x, m4y, m5x, m5y;
|
||||
float s1x, s1y, s2x, s2y, s3x, s3y, s4x, s4y, s5x, s5y;
|
||||
float c1, c2, c3, c4, c5;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftcooleytukeyplan = 0;
|
||||
int ftbase_fftbluesteinplan = 1;
|
||||
int ftbase_fftcodeletplan = 2;
|
||||
int ftbase_fhtcooleytukeyplan = 3;
|
||||
int ftbase_fhtcodeletplan = 4;
|
||||
int ftbase_fftrealcooleytukeyplan = 5;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
int ftbase_fftemptyplan = 6;
|
||||
PIVector<float> & tmpb(curplan.tmpbuf);
|
||||
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftemptyplan)
|
||||
return;
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftemptyplan) return;
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftcooleytukeyplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
@@ -1507,26 +1583,26 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
for (int k = 0; k <= n2 - 1; k++)
|
||||
(*a)[offs + 2 * k + 1] = (*a)[offs + 2 * n2 + 2 * k + 0];
|
||||
ftbaseexecuteplanrec(a, offs, plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
tmpb[0] = (*a)[offs + 0];
|
||||
tmpb[1] = 0;
|
||||
tmpb[0] = (*a)[offs + 0];
|
||||
tmpb[1] = 0;
|
||||
tmpb[2 * n2 + 0] = (*a)[offs + 1];
|
||||
tmpb[2 * n2 + 1] = 0;
|
||||
for (int k = 1; k <= n2 - 1; k++) {
|
||||
offs1 = 2 * k;
|
||||
offs2 = 2 * n2 + 2 * k;
|
||||
hk = (*a)[offs + 2 * k + 0];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 0];
|
||||
offs1 = 2 * k;
|
||||
offs2 = 2 * n2 + 2 * k;
|
||||
hk = (*a)[offs + 2 * k + 0];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 0];
|
||||
tmpb[offs1 + 0] = 0.5 * (hk + hnk);
|
||||
tmpb[offs2 + 1] = -0.5 * (hk - hnk);
|
||||
hk = (*a)[offs + 2 * k + 1];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 1];
|
||||
hk = (*a)[offs + 2 * k + 1];
|
||||
hnk = (*a)[offs + 2 * (n2 - k) + 1];
|
||||
tmpb[offs2 + 0] = 0.5 * (hk + hnk);
|
||||
tmpb[offs1 + 1] = 0.5 * (hk - hnk);
|
||||
}
|
||||
for (int k = 0; k < 2 * n2 * 2; k++) (*a)[offs + k] = tmpb[k];
|
||||
for (int k = 0; k < 2 * n2 * 2; k++)
|
||||
(*a)[offs + k] = tmpb[k];
|
||||
}
|
||||
if (n1 % 2 != 0)
|
||||
ftbaseexecuteplanrec(a, aoffset + (n1 - 1)*n2 * 2, plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
if (n1 % 2 != 0) ftbaseexecuteplanrec(a, aoffset + (n1 - 1) * n2 * 2, plan, curplan.plan[entryoffset + 6], stackptr);
|
||||
ftbase_ffttwcalc(a, aoffset, n2, n1);
|
||||
ftbase_internalcomplexlintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
for (int i = 0; i <= n2 - 1; i++)
|
||||
@@ -1537,16 +1613,16 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fhtcooleytukeyplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
ftbase_internalreallintranspose(a, n1, n2, aoffset, &(curplan.tmpbuf));
|
||||
for (int i = 0; i <= n2 - 1; i++)
|
||||
ftbaseexecuteplanrec(a, aoffset + i * n1, plan, curplan.plan[entryoffset + 5], stackptr);
|
||||
for (int i = 0; i <= n2 - 1; i++) {
|
||||
for (int j = 0; j <= n1 - 1; j++) {
|
||||
offsa = aoffset + i * n1;
|
||||
hk = (*a)[offsa + j];
|
||||
hnk = (*a)[offsa + (n1 - j) % n1];
|
||||
offs = 2 * (i * n1 + j);
|
||||
offsa = aoffset + i * n1;
|
||||
hk = (*a)[offsa + j];
|
||||
hnk = (*a)[offsa + (n1 - j) % n1];
|
||||
offs = 2 * (i * n1 + j);
|
||||
tmpb[offs + 0] = -0.5 * (hnk - hk);
|
||||
tmpb[offs + 1] = 0.5 * (hk + hnk);
|
||||
}
|
||||
@@ -1555,13 +1631,13 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
for (int j = 0; j <= n1 - 1; j++)
|
||||
(*a)[aoffset + j] = tmpb[2 * j + 0] + tmpb[2 * j + 1];
|
||||
if (n2 % 2 == 0) {
|
||||
offs = 2 * (n2 / 2) * n1;
|
||||
offs = 2 * (n2 / 2) * n1;
|
||||
offsa = aoffset + n2 / 2 * n1;
|
||||
for (int j = 0; j <= n1 - 1; j++)
|
||||
(*a)[offsa + j] = tmpb[offs + 2 * j + 0] + tmpb[offs + 2 * j + 1];
|
||||
}
|
||||
for (int i = 1; i <= (n2 + 1) / 2 - 1; i++) {
|
||||
offs = 2 * i * n1;
|
||||
offs = 2 * i * n1;
|
||||
offs2 = 2 * (n2 - i) * n1;
|
||||
offsa = aoffset + i * n1;
|
||||
for (int j = 0; j <= n1 - 1; j++)
|
||||
@@ -1579,16 +1655,16 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftcodeletplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
if (n == 2) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
v0 = a0x + a1x;
|
||||
v1 = a0y + a1y;
|
||||
v2 = a0x - a1x;
|
||||
v3 = a0y - a1y;
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
v0 = a0x + a1x;
|
||||
v1 = a0y + a1y;
|
||||
v2 = a0x - a1x;
|
||||
v3 = a0y - a1y;
|
||||
(*a)[aoffset + 0] = v0;
|
||||
(*a)[aoffset + 1] = v1;
|
||||
(*a)[aoffset + 2] = v2;
|
||||
@@ -1596,29 +1672,29 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
return;
|
||||
}
|
||||
if (n == 3) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
t1x = a1x + a2x;
|
||||
t1y = a1y + a2y;
|
||||
a0x = a0x + t1x;
|
||||
a0y = a0y + t1y;
|
||||
m1x = c1 * t1x;
|
||||
m1y = c1 * t1y;
|
||||
m2x = c2 * (a1y - a2y);
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
s1y = a0y + m1y;
|
||||
a1x = s1x + m2x;
|
||||
a1y = s1y + m2y;
|
||||
a2x = s1x - m2x;
|
||||
a2y = s1y - m2y;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
t1x = a1x + a2x;
|
||||
t1y = a1y + a2y;
|
||||
a0x = a0x + t1x;
|
||||
a0y = a0y + t1y;
|
||||
m1x = c1 * t1x;
|
||||
m1y = c1 * t1y;
|
||||
m2x = c2 * (a1y - a2y);
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
s1y = a0y + m1y;
|
||||
a1x = s1x + m2x;
|
||||
a1y = s1y + m2y;
|
||||
a2x = s1x - m2x;
|
||||
a2y = s1y - m2y;
|
||||
(*a)[aoffset + 0] = a0x;
|
||||
(*a)[aoffset + 1] = a0y;
|
||||
(*a)[aoffset + 2] = a1x;
|
||||
@@ -1628,22 +1704,22 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
return;
|
||||
}
|
||||
if (n == 4) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
a3x = (*a)[aoffset + 6];
|
||||
a3y = (*a)[aoffset + 7];
|
||||
t1x = a0x + a2x;
|
||||
t1y = a0y + a2y;
|
||||
t2x = a1x + a3x;
|
||||
t2y = a1y + a3y;
|
||||
m2x = a0x - a2x;
|
||||
m2y = a0y - a2y;
|
||||
m3x = a1y - a3y;
|
||||
m3y = a3x - a1x;
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a0y = (*a)[aoffset + 1];
|
||||
a1x = (*a)[aoffset + 2];
|
||||
a1y = (*a)[aoffset + 3];
|
||||
a2x = (*a)[aoffset + 4];
|
||||
a2y = (*a)[aoffset + 5];
|
||||
a3x = (*a)[aoffset + 6];
|
||||
a3y = (*a)[aoffset + 7];
|
||||
t1x = a0x + a2x;
|
||||
t1y = a0y + a2y;
|
||||
t2x = a1x + a3x;
|
||||
t2y = a1y + a3y;
|
||||
m2x = a0x - a2x;
|
||||
m2y = a0y - a2y;
|
||||
m3x = a1y - a3y;
|
||||
m3y = a3x - a1x;
|
||||
(*a)[aoffset + 0] = t1x + t2x;
|
||||
(*a)[aoffset + 1] = t1y + t2y;
|
||||
(*a)[aoffset + 4] = t1x - t2x;
|
||||
@@ -1655,44 +1731,44 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
return;
|
||||
}
|
||||
if (n == 5) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 2] + (*a)[aoffset + 8];
|
||||
t1y = (*a)[aoffset + 3] + (*a)[aoffset + 9];
|
||||
t2x = (*a)[aoffset + 4] + (*a)[aoffset + 6];
|
||||
t2y = (*a)[aoffset + 5] + (*a)[aoffset + 7];
|
||||
t3x = (*a)[aoffset + 2] - (*a)[aoffset + 8];
|
||||
t3y = (*a)[aoffset + 3] - (*a)[aoffset + 9];
|
||||
t4x = (*a)[aoffset + 6] - (*a)[aoffset + 4];
|
||||
t4y = (*a)[aoffset + 7] - (*a)[aoffset + 5];
|
||||
t5x = t1x + t2x;
|
||||
t5y = t1y + t2y;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 2] + (*a)[aoffset + 8];
|
||||
t1y = (*a)[aoffset + 3] + (*a)[aoffset + 9];
|
||||
t2x = (*a)[aoffset + 4] + (*a)[aoffset + 6];
|
||||
t2y = (*a)[aoffset + 5] + (*a)[aoffset + 7];
|
||||
t3x = (*a)[aoffset + 2] - (*a)[aoffset + 8];
|
||||
t3y = (*a)[aoffset + 3] - (*a)[aoffset + 9];
|
||||
t4x = (*a)[aoffset + 6] - (*a)[aoffset + 4];
|
||||
t4y = (*a)[aoffset + 7] - (*a)[aoffset + 5];
|
||||
t5x = t1x + t2x;
|
||||
t5y = t1y + t2y;
|
||||
(*a)[aoffset + 0] = (*a)[aoffset + 0] + t5x;
|
||||
(*a)[aoffset + 1] = (*a)[aoffset + 1] + t5y;
|
||||
m1x = c1 * t5x;
|
||||
m1y = c1 * t5y;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m2y = c2 * (t1y - t2y);
|
||||
m3x = -c3 * (t3y + t4y);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
m4x = -c4 * t4y;
|
||||
m4y = c4 * t4x;
|
||||
m5x = -c5 * t3y;
|
||||
m5y = c5 * t3x;
|
||||
s3x = m3x - m4x;
|
||||
s3y = m3y - m4y;
|
||||
s5x = m3x + m5x;
|
||||
s5y = m3y + m5y;
|
||||
s1x = (*a)[aoffset + 0] + m1x;
|
||||
s1y = (*a)[aoffset + 1] + m1y;
|
||||
s2x = s1x + m2x;
|
||||
s2y = s1y + m2y;
|
||||
s4x = s1x - m2x;
|
||||
s4y = s1y - m2y;
|
||||
m1x = c1 * t5x;
|
||||
m1y = c1 * t5y;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m2y = c2 * (t1y - t2y);
|
||||
m3x = -c3 * (t3y + t4y);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
m4x = -c4 * t4y;
|
||||
m4y = c4 * t4x;
|
||||
m5x = -c5 * t3y;
|
||||
m5y = c5 * t3x;
|
||||
s3x = m3x - m4x;
|
||||
s3y = m3y - m4y;
|
||||
s5x = m3x + m5x;
|
||||
s5y = m3y + m5y;
|
||||
s1x = (*a)[aoffset + 0] + m1x;
|
||||
s1y = (*a)[aoffset + 1] + m1y;
|
||||
s2x = s1x + m2x;
|
||||
s2y = s1y + m2y;
|
||||
s4x = s1x - m2x;
|
||||
s4y = s1y - m2y;
|
||||
(*a)[aoffset + 2] = s2x + s3x;
|
||||
(*a)[aoffset + 3] = s2y + s3y;
|
||||
(*a)[aoffset + 4] = s4x + s5x;
|
||||
@@ -1707,40 +1783,40 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fhtcodeletplan) {
|
||||
n1 = curplan.plan[entryoffset + 1];
|
||||
n2 = curplan.plan[entryoffset + 2];
|
||||
n = n1 * n2;
|
||||
n = n1 * n2;
|
||||
if (n == 2) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
(*a)[aoffset + 0] = a0x + a1x;
|
||||
(*a)[aoffset + 1] = a0x - a1x;
|
||||
return;
|
||||
}
|
||||
if (n == 3) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
t1x = a1x + a2x;
|
||||
a0x = a0x + t1x;
|
||||
m1x = c1 * t1x;
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
t1x = a1x + a2x;
|
||||
a0x = a0x + t1x;
|
||||
m1x = c1 * t1x;
|
||||
m2y = c2 * (a2x - a1x);
|
||||
s1x = a0x + m1x;
|
||||
(*a)[aoffset + 0] = a0x;
|
||||
(*a)[aoffset + 1] = s1x - m2y;
|
||||
(*a)[aoffset + 2] = s1x + m2y;
|
||||
return;
|
||||
}
|
||||
if (n == 4) {
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
a3x = (*a)[aoffset + 3];
|
||||
t1x = a0x + a2x;
|
||||
t2x = a1x + a3x;
|
||||
m2x = a0x - a2x;
|
||||
m3y = a3x - a1x;
|
||||
a0x = (*a)[aoffset + 0];
|
||||
a1x = (*a)[aoffset + 1];
|
||||
a2x = (*a)[aoffset + 2];
|
||||
a3x = (*a)[aoffset + 3];
|
||||
t1x = a0x + a2x;
|
||||
t2x = a1x + a3x;
|
||||
m2x = a0x - a2x;
|
||||
m3y = a3x - a1x;
|
||||
(*a)[aoffset + 0] = t1x + t2x;
|
||||
(*a)[aoffset + 1] = m2x - m3y;
|
||||
(*a)[aoffset + 2] = t1x - t2x;
|
||||
@@ -1748,26 +1824,26 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
return;
|
||||
}
|
||||
if (n == 5) {
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 1] + (*a)[aoffset + 4];
|
||||
t2x = (*a)[aoffset + 2] + (*a)[aoffset + 3];
|
||||
t3x = (*a)[aoffset + 1] - (*a)[aoffset + 4];
|
||||
t4x = (*a)[aoffset + 3] - (*a)[aoffset + 2];
|
||||
t5x = t1x + t2x;
|
||||
v0 = (*a)[aoffset + 0] + t5x;
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
c1 = curplan.precomputed[offs + 0];
|
||||
c2 = curplan.precomputed[offs + 1];
|
||||
c3 = curplan.precomputed[offs + 2];
|
||||
c4 = curplan.precomputed[offs + 3];
|
||||
c5 = curplan.precomputed[offs + 4];
|
||||
t1x = (*a)[aoffset + 1] + (*a)[aoffset + 4];
|
||||
t2x = (*a)[aoffset + 2] + (*a)[aoffset + 3];
|
||||
t3x = (*a)[aoffset + 1] - (*a)[aoffset + 4];
|
||||
t4x = (*a)[aoffset + 3] - (*a)[aoffset + 2];
|
||||
t5x = t1x + t2x;
|
||||
v0 = (*a)[aoffset + 0] + t5x;
|
||||
(*a)[aoffset + 0] = v0;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
s3y = m3y - c4 * t4x;
|
||||
s5y = m3y + c5 * t3x;
|
||||
s1x = v0 + c1 * t5x;
|
||||
s2x = s1x + m2x;
|
||||
s4x = s1x - m2x;
|
||||
m2x = c2 * (t1x - t2x);
|
||||
m3y = c3 * (t3x + t4x);
|
||||
s3y = m3y - c4 * t4x;
|
||||
s5y = m3y + c5 * t3x;
|
||||
s1x = v0 + c1 * t5x;
|
||||
s2x = s1x + m2x;
|
||||
s4x = s1x - m2x;
|
||||
(*a)[aoffset + 1] = s2x - s3y;
|
||||
(*a)[aoffset + 2] = s4x - s5y;
|
||||
(*a)[aoffset + 3] = s4x + s5y;
|
||||
@@ -1776,8 +1852,8 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
}
|
||||
}
|
||||
if (curplan.plan[entryoffset + 3] == ftbase_fftbluesteinplan) {
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
n = curplan.plan[entryoffset + 1];
|
||||
m = curplan.plan[entryoffset + 4];
|
||||
offs = curplan.plan[entryoffset + 7];
|
||||
for (int i = stackptr + 2 * n; i <= stackptr + 2 * m - 1; i++)
|
||||
curplan.stackbuf[i] = 0;
|
||||
@@ -1785,43 +1861,43 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
offsa = aoffset;
|
||||
offsb = stackptr;
|
||||
for (int i = 0; i < n; i++) {
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = (*a)[offsa + 0];
|
||||
y = (*a)[offsa + 1];
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = (*a)[offsa + 0];
|
||||
y = (*a)[offsa + 1];
|
||||
curplan.stackbuf[offsb + 0] = x * bx - y * (-by);
|
||||
curplan.stackbuf[offsb + 1] = x * (-by) + y * bx;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
}
|
||||
ftbaseexecuteplanrec(&curplan.stackbuf, stackptr, plan, curplan.plan[entryoffset + 5], stackptr + 2 * 2 * m);
|
||||
offsb = stackptr;
|
||||
offsp = offs;
|
||||
for (int i = 0; i <= m - 1; i++) {
|
||||
x = curplan.stackbuf[offsb + 0];
|
||||
y = curplan.stackbuf[offsb + 1];
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = curplan.stackbuf[offsb + 0];
|
||||
y = curplan.stackbuf[offsb + 1];
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
curplan.stackbuf[offsb + 0] = x * bx - y * by;
|
||||
curplan.stackbuf[offsb + 1] = -(x * by + y * bx);
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
}
|
||||
ftbaseexecuteplanrec(&curplan.stackbuf, stackptr, plan, curplan.plan[entryoffset + 5], stackptr + 2 * 2 * m);
|
||||
offsb = stackptr;
|
||||
offsp = offs + 2 * m;
|
||||
offsa = aoffset;
|
||||
for (int i = 0; i < n; i++) {
|
||||
x = curplan.stackbuf[offsb + 0] / m;
|
||||
y = -curplan.stackbuf[offsb + 1] / m;
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
x = curplan.stackbuf[offsb + 0] / m;
|
||||
y = -curplan.stackbuf[offsb + 1] / m;
|
||||
bx = curplan.precomputed[offsp + 0];
|
||||
by = curplan.precomputed[offsp + 1];
|
||||
(*a)[offsa + 0] = x * bx - y * (-by);
|
||||
(*a)[offsa + 1] = x * (-by) + y * bx;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
offsp = offsp + 2;
|
||||
offsa = offsa + 2;
|
||||
offsb = offsb + 2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1832,54 +1908,54 @@ void PIFFT_float::ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan
|
||||
Twiddle factors calculation
|
||||
|
||||
-- ALGLIB --
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
Copyright 01.05.2009 by Bochkanov Sergey
|
||||
*************************************************************************/
|
||||
void PIFFT_float::ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int n2) {
|
||||
int n, idx, offs;
|
||||
float x, y, twxm1, twy, twbasexm1, twbasey, twrowxm1, twrowy, tmpx, tmpy, v;
|
||||
int ftbase_ftbaseupdatetw = 4;
|
||||
n = n1 * n2;
|
||||
v = -2 * M_PI / n;
|
||||
twbasexm1 = -2 * sqr(sin(0.5 * v));
|
||||
twbasey = sin(v);
|
||||
twrowxm1 = 0;
|
||||
twrowy = 0;
|
||||
n = n1 * n2;
|
||||
v = -2 * M_PI / n;
|
||||
twbasexm1 = -2 * sqr(sin(0.5 * v));
|
||||
twbasey = sin(v);
|
||||
twrowxm1 = 0;
|
||||
twrowy = 0;
|
||||
for (int i = 0, j = 0; i <= n2 - 1; i++) {
|
||||
twxm1 = 0;
|
||||
twy = 0;
|
||||
twy = 0;
|
||||
for (j = 0; j <= n1 - 1; j++) {
|
||||
idx = i * n1 + j;
|
||||
offs = aoffset + 2 * idx;
|
||||
x = (*a)[offs + 0];
|
||||
y = (*a)[offs + 1];
|
||||
tmpx = x * twxm1 - y * twy;
|
||||
tmpy = x * twy + y * twxm1;
|
||||
idx = i * n1 + j;
|
||||
offs = aoffset + 2 * idx;
|
||||
x = (*a)[offs + 0];
|
||||
y = (*a)[offs + 1];
|
||||
tmpx = x * twxm1 - y * twy;
|
||||
tmpy = x * twy + y * twxm1;
|
||||
(*a)[offs + 0] = x + tmpx;
|
||||
(*a)[offs + 1] = y + tmpy;
|
||||
if (j < n1 - 1) {
|
||||
if (j % ftbase_ftbaseupdatetw == 0) {
|
||||
v = -2 * M_PI * i * (j + 1) / n;
|
||||
v = -2 * M_PI * i * (j + 1) / n;
|
||||
twxm1 = -2 * sqr(sin(0.5 * v));
|
||||
twy = sin(v);
|
||||
twy = sin(v);
|
||||
} else {
|
||||
tmpx = twrowxm1 + twxm1 * twrowxm1 - twy * twrowy;
|
||||
tmpy = twrowy + twxm1 * twrowy + twy * twrowxm1;
|
||||
tmpx = twrowxm1 + twxm1 * twrowxm1 - twy * twrowy;
|
||||
tmpy = twrowy + twxm1 * twrowy + twy * twrowxm1;
|
||||
twxm1 = twxm1 + tmpx;
|
||||
twy = twy + tmpy;
|
||||
twy = twy + tmpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < n2 - 1) {
|
||||
if (j % ftbase_ftbaseupdatetw == 0) {
|
||||
v = -2 * M_PI * (i + 1) / n;
|
||||
v = -2 * M_PI * (i + 1) / n;
|
||||
twrowxm1 = -2 * sqr(sin(0.5 * v));
|
||||
twrowy = sin(v);
|
||||
twrowy = sin(v);
|
||||
} else {
|
||||
tmpx = twbasexm1 + twrowxm1 * twbasexm1 - twrowy * twbasey;
|
||||
tmpy = twbasey + twrowxm1 * twbasey + twrowy * twbasexm1;
|
||||
tmpx = twbasexm1 + twrowxm1 * twbasexm1 - twrowy * twbasey;
|
||||
tmpy = twbasey + twrowxm1 * twbasey + twrowy * twbasexm1;
|
||||
twrowxm1 = twrowxm1 + tmpx;
|
||||
twrowy = twrowy + tmpy;
|
||||
twrowy = twrowy + tmpy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,22 +6,22 @@
|
||||
* \~russian БПФ, ОБПФ и преобразования Гильберта
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Class for FFT, IFFT and Hilbert transformations
|
||||
Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Class for FFT, IFFT and Hilbert transformations
|
||||
Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
//! \defgroup FFTW FFTW
|
||||
//! \~\brief
|
||||
@@ -62,21 +62,20 @@
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
|
||||
#include "pip_fftw_export.h"
|
||||
# include "pip_fftw_export.h"
|
||||
|
||||
class PIP_EXPORT PIFFT_double
|
||||
{
|
||||
class PIP_EXPORT PIFFT_double {
|
||||
public:
|
||||
PIFFT_double();
|
||||
|
||||
PIVector<complexd> * calcFFT(const PIVector<complexd> &val);
|
||||
PIVector<complexd> * calcFFT(const PIVector<double> &val);
|
||||
PIVector<complexd> * calcFFTinverse(const PIVector<complexd> &val);
|
||||
PIVector<complexd> * calcHilbert(const PIVector<double> &val);
|
||||
|
||||
PIVector<complexd> * calcFFT(const PIVector<complexd> & val);
|
||||
PIVector<complexd> * calcFFT(const PIVector<double> & val);
|
||||
PIVector<complexd> * calcFFTinverse(const PIVector<complexd> & val);
|
||||
PIVector<complexd> * calcHilbert(const PIVector<double> & val);
|
||||
PIVector<double> getAmplitude() const;
|
||||
PIVector<double> getReal() const;
|
||||
PIVector<double> getImag() const;
|
||||
|
||||
|
||||
private:
|
||||
PIVector<complexd> result;
|
||||
typedef ptrdiff_t ae_int_t;
|
||||
@@ -90,35 +89,43 @@ private:
|
||||
|
||||
ftplan curplan;
|
||||
|
||||
void fftc1d(const PIVector<complexd> &a, uint n);
|
||||
void fftc1r(const PIVector<double> &a, uint n);
|
||||
void fftc1dinv(const PIVector<complexd> &a, uint n);
|
||||
void fftc1d(const PIVector<complexd> & a, uint n);
|
||||
void fftc1r(const PIVector<double> & a, uint n);
|
||||
void fftc1dinv(const PIVector<complexd> & a, uint n);
|
||||
|
||||
void createPlan(uint n);
|
||||
void ftbasegeneratecomplexfftplan(uint n, ftplan *plan);
|
||||
void ftbase_ftbasegenerateplanrec(int n, int tasktype, ftplan *plan, int *plansize, int *precomputedsize, int *planarraysize, int *tmpmemsize, int *stackmemsize, ae_int_t stackptr, int debugi=0);
|
||||
void ftbase_ftbaseprecomputeplanrec(ftplan *plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbasefactorize(int n, int *n1, int *n2);
|
||||
void ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int *best);
|
||||
void ftbasegeneratecomplexfftplan(uint n, ftplan * plan);
|
||||
void ftbase_ftbasegenerateplanrec(int n,
|
||||
int tasktype,
|
||||
ftplan * plan,
|
||||
int * plansize,
|
||||
int * precomputedsize,
|
||||
int * planarraysize,
|
||||
int * tmpmemsize,
|
||||
int * stackmemsize,
|
||||
ae_int_t stackptr,
|
||||
int debugi = 0);
|
||||
void ftbase_ftbaseprecomputeplanrec(ftplan * plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbasefactorize(int n, int * n1, int * n2);
|
||||
void ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int * best);
|
||||
int ftbasefindsmooth(int n);
|
||||
void ftbaseexecuteplan(PIVector<double> *a, int aoffset, int n, ftplan *plan);
|
||||
void ftbaseexecuteplanrec(PIVector<double> *a, int aoffset, ftplan *plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbase_internalcomplexlintranspose(PIVector<double> *a, int m, int n, int astart, PIVector<double> *buf);
|
||||
void ftbase_ffticltrec(PIVector<double> *a, int astart, int astride, PIVector<double> *b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_internalreallintranspose(PIVector<double> *a, int m, int n, int astart, PIVector<double> *buf);
|
||||
void ftbase_fftirltrec(PIVector<double> *a, int astart, int astride, PIVector<double> *b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_ffttwcalc(PIVector<double> *a, int aoffset, int n1, int n2);
|
||||
void ftbaseexecuteplan(PIVector<double> * a, int aoffset, int n, ftplan * plan);
|
||||
void ftbaseexecuteplanrec(PIVector<double> * a, int aoffset, ftplan * plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbase_internalcomplexlintranspose(PIVector<double> * a, int m, int n, int astart, PIVector<double> * buf);
|
||||
void ftbase_ffticltrec(PIVector<double> * a, int astart, int astride, PIVector<double> * b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_internalreallintranspose(PIVector<double> * a, int m, int n, int astart, PIVector<double> * buf);
|
||||
void ftbase_fftirltrec(PIVector<double> * a, int astart, int astride, PIVector<double> * b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_ffttwcalc(PIVector<double> * a, int aoffset, int n1, int n2);
|
||||
};
|
||||
|
||||
class PIP_EXPORT PIFFT_float
|
||||
{
|
||||
class PIP_EXPORT PIFFT_float {
|
||||
public:
|
||||
PIFFT_float();
|
||||
|
||||
PIVector<complexf> * calcFFT(const PIVector<complexf> &val);
|
||||
PIVector<complexf> * calcFFT(const PIVector<float> &val);
|
||||
PIVector<complexf> * calcFFTinverse(const PIVector<complexf> &val);
|
||||
PIVector<complexf> * calcHilbert(const PIVector<float> &val);
|
||||
PIVector<complexf> * calcFFT(const PIVector<complexf> & val);
|
||||
PIVector<complexf> * calcFFT(const PIVector<float> & val);
|
||||
PIVector<complexf> * calcFFTinverse(const PIVector<complexf> & val);
|
||||
PIVector<complexf> * calcHilbert(const PIVector<float> & val);
|
||||
PIVector<float> getAmplitude() const;
|
||||
PIVector<float> getReal() const;
|
||||
PIVector<float> getImag() const;
|
||||
@@ -136,63 +143,79 @@ private:
|
||||
|
||||
ftplan curplan;
|
||||
|
||||
void fftc1d(const PIVector<complexf> &a, uint n);
|
||||
void fftc1r(const PIVector<float> &a, uint n);
|
||||
void fftc1dinv(const PIVector<complexf> &a, uint n);
|
||||
void fftc1d(const PIVector<complexf> & a, uint n);
|
||||
void fftc1r(const PIVector<float> & a, uint n);
|
||||
void fftc1dinv(const PIVector<complexf> & a, uint n);
|
||||
|
||||
void createPlan(uint n);
|
||||
void ftbasegeneratecomplexfftplan(uint n, ftplan *plan);
|
||||
void ftbase_ftbasegenerateplanrec(int n, int tasktype, ftplan *plan, int *plansize, int *precomputedsize, int *planarraysize, int *tmpmemsize, int *stackmemsize, ae_int_t stackptr, int debugi=0);
|
||||
void ftbase_ftbaseprecomputeplanrec(ftplan *plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbasefactorize(int n, int *n1, int *n2);
|
||||
void ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int *best);
|
||||
void ftbasegeneratecomplexfftplan(uint n, ftplan * plan);
|
||||
void ftbase_ftbasegenerateplanrec(int n,
|
||||
int tasktype,
|
||||
ftplan * plan,
|
||||
int * plansize,
|
||||
int * precomputedsize,
|
||||
int * planarraysize,
|
||||
int * tmpmemsize,
|
||||
int * stackmemsize,
|
||||
ae_int_t stackptr,
|
||||
int debugi = 0);
|
||||
void ftbase_ftbaseprecomputeplanrec(ftplan * plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbasefactorize(int n, int * n1, int * n2);
|
||||
void ftbase_ftbasefindsmoothrec(int n, int seed, int leastfactor, int * best);
|
||||
int ftbasefindsmooth(int n);
|
||||
void ftbaseexecuteplan(PIVector<float> *a, int aoffset, int n, ftplan *plan);
|
||||
void ftbaseexecuteplanrec(PIVector<float> *a, int aoffset, ftplan *plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbase_internalcomplexlintranspose(PIVector<float> *a, int m, int n, int astart, PIVector<float> *buf);
|
||||
void ftbase_ffticltrec(PIVector<float> *a, int astart, int astride, PIVector<float> *b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_internalreallintranspose(PIVector<float> *a, int m, int n, int astart, PIVector<float> *buf);
|
||||
void ftbase_fftirltrec(PIVector<float> *a, int astart, int astride, PIVector<float> *b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_ffttwcalc(PIVector<float> *a, int aoffset, int n1, int n2);
|
||||
void ftbaseexecuteplan(PIVector<float> * a, int aoffset, int n, ftplan * plan);
|
||||
void ftbaseexecuteplanrec(PIVector<float> * a, int aoffset, ftplan * plan, int entryoffset, ae_int_t stackptr);
|
||||
void ftbase_internalcomplexlintranspose(PIVector<float> * a, int m, int n, int astart, PIVector<float> * buf);
|
||||
void ftbase_ffticltrec(PIVector<float> * a, int astart, int astride, PIVector<float> * b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_internalreallintranspose(PIVector<float> * a, int m, int n, int astart, PIVector<float> * buf);
|
||||
void ftbase_fftirltrec(PIVector<float> * a, int astart, int astride, PIVector<float> * b, int bstart, int bstride, int m, int n);
|
||||
void ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int n2);
|
||||
};
|
||||
|
||||
typedef PIFFT_double PIFFT;
|
||||
typedef PIFFT_double PIFFTd;
|
||||
typedef PIFFT_float PIFFTf;
|
||||
|
||||
#ifndef CC_VC
|
||||
# ifndef CC_VC
|
||||
|
||||
#define _PIFFTW_H(type) class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \
|
||||
public: \
|
||||
_PIFFTW_P_##type##_(); \
|
||||
~_PIFFTW_P_##type##_(); \
|
||||
const PIVector<complex<type> > & calcFFT(const PIVector<complex<type> > & in); \
|
||||
const PIVector<complex<type> > & calcFFTR(const PIVector<type> & in); \
|
||||
const PIVector<complex<type> > & calcFFTI(const PIVector<complex<type> > & in); \
|
||||
void preparePlan(int size, int op); \
|
||||
void * impl; \
|
||||
};
|
||||
# define _PIFFTW_H(type) \
|
||||
class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \
|
||||
public: \
|
||||
_PIFFTW_P_##type##_(); \
|
||||
~_PIFFTW_P_##type##_(); \
|
||||
const PIVector<complex<type>> & calcFFT(const PIVector<complex<type>> & in); \
|
||||
const PIVector<complex<type>> & calcFFTR(const PIVector<type> & in); \
|
||||
const PIVector<complex<type>> & calcFFTI(const PIVector<complex<type>> & in); \
|
||||
void preparePlan(int size, int op); \
|
||||
void * impl; \
|
||||
};
|
||||
_PIFFTW_H(float)
|
||||
_PIFFTW_H(double)
|
||||
_PIFFTW_H(ldouble)
|
||||
|
||||
template <typename T>
|
||||
class PIFFTW
|
||||
{
|
||||
template<typename T>
|
||||
class PIFFTW {
|
||||
public:
|
||||
explicit PIFFTW() {p = 0; newP(p);}
|
||||
~PIFFTW() {deleteP(p);}
|
||||
explicit PIFFTW() {
|
||||
p = 0;
|
||||
newP(p);
|
||||
}
|
||||
~PIFFTW() { deleteP(p); }
|
||||
|
||||
inline const PIVector<complex<T> > & calcFFT(const PIVector<complex<T> > & in) {return PIVector<complex<T> >().resize(in.size());}
|
||||
inline const PIVector<complex<T> > & calcFFT(const PIVector<T> & in) {return PIVector<complex<T> >().resize(in.size());}
|
||||
inline const PIVector<complex<T> > & calcFFTinverse(const PIVector<complex<T> > & in) {return PIVector<complex<T> >().resize(in.size());}
|
||||
inline const PIVector<complex<T>> & calcFFT(const PIVector<complex<T>> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
||||
inline const PIVector<complex<T>> & calcFFT(const PIVector<T> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
||||
inline const PIVector<complex<T>> & calcFFTinverse(const PIVector<complex<T>> & in) { return PIVector<complex<T>>().resize(in.size()); }
|
||||
|
||||
enum FFT_Operation {foReal, foComplex, foInverse};
|
||||
enum FFT_Operation {
|
||||
foReal,
|
||||
foComplex,
|
||||
foInverse
|
||||
};
|
||||
|
||||
inline void preparePlan(int size, FFT_Operation op) {}
|
||||
|
||||
private:
|
||||
void operator =(const PIFFTW & );
|
||||
void operator=(const PIFFTW &);
|
||||
PIFFTW(const PIFFTW &);
|
||||
inline void newP(void *& _p) {}
|
||||
inline void deleteP(void *& _p) {}
|
||||
@@ -201,36 +224,93 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template<> inline const PIVector<complex<float> > & PIFFTW<float>::calcFFT(const PIVector<complex<float> > & in) {return ((_PIFFTW_P_float_*)p)->calcFFT(in);}
|
||||
template<> inline const PIVector<complex<float> > & PIFFTW<float>::calcFFT(const PIVector<float> & in) {return ((_PIFFTW_P_float_*)p)->calcFFTR(in);}
|
||||
template<> inline const PIVector<complex<float> > & PIFFTW<float>::calcFFTinverse(const PIVector<complex<float> > & in) {return ((_PIFFTW_P_float_*)p)->calcFFTI(in);}
|
||||
template<> inline void PIFFTW<float>::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_float_*)p)->preparePlan(size, op);}
|
||||
template<> inline void PIFFTW<float>::newP(void *& _p) {_p = new _PIFFTW_P_float_();}
|
||||
template<> inline void PIFFTW<float>::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_float_*)_p; _p = 0;}
|
||||
template<>
|
||||
inline const PIVector<complex<float>> & PIFFTW<float>::calcFFT(const PIVector<complex<float>> & in) {
|
||||
return ((_PIFFTW_P_float_ *)p)->calcFFT(in);
|
||||
}
|
||||
template<>
|
||||
inline const PIVector<complex<float>> & PIFFTW<float>::calcFFT(const PIVector<float> & in) {
|
||||
return ((_PIFFTW_P_float_ *)p)->calcFFTR(in);
|
||||
}
|
||||
template<>
|
||||
inline const PIVector<complex<float>> & PIFFTW<float>::calcFFTinverse(const PIVector<complex<float>> & in) {
|
||||
return ((_PIFFTW_P_float_ *)p)->calcFFTI(in);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<float>::preparePlan(int size, FFT_Operation op) {
|
||||
((_PIFFTW_P_float_ *)p)->preparePlan(size, op);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<float>::newP(void *& _p) {
|
||||
_p = new _PIFFTW_P_float_();
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<float>::deleteP(void *& _p) {
|
||||
if (_p) delete (_PIFFTW_P_float_ *)_p;
|
||||
_p = 0;
|
||||
}
|
||||
|
||||
typedef PIFFTW<float> PIFFTWf;
|
||||
typedef PIFFTW<float> PIFFTWf;
|
||||
|
||||
|
||||
template<> inline const PIVector<complex<double> > & PIFFTW<double>::calcFFT(const PIVector<complex<double> > & in) {return ((_PIFFTW_P_double_*)p)->calcFFT(in);}
|
||||
template<> inline const PIVector<complex<double> > & PIFFTW<double>::calcFFT(const PIVector<double> & in) {return ((_PIFFTW_P_double_*)p)->calcFFTR(in);}
|
||||
template<> inline const PIVector<complex<double> > & PIFFTW<double>::calcFFTinverse(const PIVector<complex<double> > & in) {return ((_PIFFTW_P_double_*)p)->calcFFTI(in);}
|
||||
template<> inline void PIFFTW<double>::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_double_*)p)->preparePlan(size, op);}
|
||||
template<> inline void PIFFTW<double>::newP(void *& _p) {_p = new _PIFFTW_P_double_();}
|
||||
template<> inline void PIFFTW<double>::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_double_*)_p; _p = 0;}
|
||||
template<>
|
||||
inline const PIVector<complex<double>> & PIFFTW<double>::calcFFT(const PIVector<complex<double>> & in) {
|
||||
return ((_PIFFTW_P_double_ *)p)->calcFFT(in);
|
||||
}
|
||||
template<>
|
||||
inline const PIVector<complex<double>> & PIFFTW<double>::calcFFT(const PIVector<double> & in) {
|
||||
return ((_PIFFTW_P_double_ *)p)->calcFFTR(in);
|
||||
}
|
||||
template<>
|
||||
inline const PIVector<complex<double>> & PIFFTW<double>::calcFFTinverse(const PIVector<complex<double>> & in) {
|
||||
return ((_PIFFTW_P_double_ *)p)->calcFFTI(in);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<double>::preparePlan(int size, FFT_Operation op) {
|
||||
((_PIFFTW_P_double_ *)p)->preparePlan(size, op);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<double>::newP(void *& _p) {
|
||||
_p = new _PIFFTW_P_double_();
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<double>::deleteP(void *& _p) {
|
||||
if (_p) delete (_PIFFTW_P_double_ *)_p;
|
||||
_p = 0;
|
||||
}
|
||||
|
||||
typedef PIFFTW<double> PIFFTWd;
|
||||
typedef PIFFTW<double> PIFFTWd;
|
||||
|
||||
|
||||
template<> inline const PIVector<complex<ldouble> > & PIFFTW<ldouble>::calcFFT(const PIVector<complex<ldouble> > & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFT(in);}
|
||||
template<> inline const PIVector<complex<ldouble> > & PIFFTW<ldouble>::calcFFT(const PIVector<ldouble> & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFTR(in);}
|
||||
template<> inline const PIVector<complex<ldouble> > & PIFFTW<ldouble>::calcFFTinverse(const PIVector<complex<ldouble> > & in) {return ((_PIFFTW_P_ldouble_*)p)->calcFFTI(in);}
|
||||
template<> inline void PIFFTW<ldouble>::preparePlan(int size, FFT_Operation op) {((_PIFFTW_P_ldouble_*)p)->preparePlan(size, op);}
|
||||
template<> inline void PIFFTW<ldouble>::newP(void *& _p) {_p = new _PIFFTW_P_ldouble_();}
|
||||
template<> inline void PIFFTW<ldouble>::deleteP(void *& _p) {if (_p) delete (_PIFFTW_P_ldouble_*)_p; _p = 0;}
|
||||
template<>
|
||||
inline const PIVector<complex<ldouble>> & PIFFTW<ldouble>::calcFFT(const PIVector<complex<ldouble>> & in) {
|
||||
return ((_PIFFTW_P_ldouble_ *)p)->calcFFT(in);
|
||||
}
|
||||
template<>
|
||||
inline const PIVector<complex<ldouble>> & PIFFTW<ldouble>::calcFFT(const PIVector<ldouble> & in) {
|
||||
return ((_PIFFTW_P_ldouble_ *)p)->calcFFTR(in);
|
||||
}
|
||||
template<>
|
||||
inline const PIVector<complex<ldouble>> & PIFFTW<ldouble>::calcFFTinverse(const PIVector<complex<ldouble>> & in) {
|
||||
return ((_PIFFTW_P_ldouble_ *)p)->calcFFTI(in);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<ldouble>::preparePlan(int size, FFT_Operation op) {
|
||||
((_PIFFTW_P_ldouble_ *)p)->preparePlan(size, op);
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<ldouble>::newP(void *& _p) {
|
||||
_p = new _PIFFTW_P_ldouble_();
|
||||
}
|
||||
template<>
|
||||
inline void PIFFTW<ldouble>::deleteP(void *& _p) {
|
||||
if (_p) delete (_PIFFTW_P_ldouble_ *)_p;
|
||||
_p = 0;
|
||||
}
|
||||
|
||||
typedef PIFFTW<ldouble> PIFFTWld;
|
||||
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#endif // MICRO_PIP
|
||||
|
||||
|
||||
@@ -15,30 +15,30 @@
|
||||
* \~russian
|
||||
* Иван Пелипенко peri4ko@yandex.ru;
|
||||
* Андрей Бычков work.a.b@yandex.ru;
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Geometry base classes
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Geometry base classes
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PIGEOMETRY_H
|
||||
#define PIGEOMETRY_H
|
||||
|
||||
#include "pipoint.h"
|
||||
#include "piline.h"
|
||||
#include "pipoint.h"
|
||||
#include "pirect.h"
|
||||
|
||||
#endif // PIGEOMETRY_H
|
||||
|
||||
@@ -3,24 +3,24 @@
|
||||
* \brief
|
||||
* \~english Two-dimensional line class
|
||||
* \~russian Класс отрезка двумерной линии
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Two-dimensional line class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Two-dimensional line class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PILINE_H
|
||||
#define PILINE_H
|
||||
@@ -38,13 +38,14 @@
|
||||
template<typename Type>
|
||||
class PIP_EXPORT PILine {
|
||||
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
|
||||
|
||||
public:
|
||||
PIPoint<Type> p0;
|
||||
PIPoint<Type> p1;
|
||||
|
||||
//! \~russian
|
||||
//! Пустой конструктор.
|
||||
//! \details
|
||||
//! \details
|
||||
//! При выполнении пустого конструктора координаты не изменяются.
|
||||
//! Начало и конец совпадают.
|
||||
PILine() {}
|
||||
@@ -81,17 +82,15 @@ public:
|
||||
|
||||
//! \~russian
|
||||
//! Проверить на совпадение координат начала и конца.
|
||||
bool isEmpty() const {
|
||||
return (p0 == p1);
|
||||
}
|
||||
bool isEmpty() const { return (p0 == p1); }
|
||||
|
||||
//! \~russian
|
||||
//! Вычислить ширину прямоугольника, диагональю которого является данный отрезок.
|
||||
Type width() const {return piAbs<Type>(p1.x - p0.x);}
|
||||
Type width() const { return piAbs<Type>(p1.x - p0.x); }
|
||||
|
||||
//! \~russian
|
||||
//! Вычислить высоту прямоугольника, диагональю которого является данный отрезок.
|
||||
Type height() const {return piAbs<Type>(p1.y - p0.y);}
|
||||
Type height() const { return piAbs<Type>(p1.y - p0.y); }
|
||||
|
||||
//! \~russian
|
||||
//! Сдвинуть линию на \a x, \a y.
|
||||
@@ -127,12 +126,12 @@ public:
|
||||
//! \~russian
|
||||
//! Сдвинуть линию на \a x, \a y.
|
||||
//! \details Является копией метода \a translate().
|
||||
PILine<Type> & move(Type x, Type y) {return translate(x, y);}
|
||||
PILine<Type> & move(Type x, Type y) { return translate(x, y); }
|
||||
|
||||
//! \~russian
|
||||
//! Сдвинуть линию на значение координат точки \a PIPoint.
|
||||
//! \details Является копией метода \a translate().
|
||||
PILine<Type> & move(const PIPoint<Type> & p) {return translate(p);}
|
||||
PILine<Type> & move(const PIPoint<Type> & p) { return translate(p); }
|
||||
|
||||
//! \~russian
|
||||
//! Создать копию отрезка и сдвинуть её на \a x, \a y.
|
||||
@@ -142,7 +141,7 @@ public:
|
||||
l.translate(x, y);
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
//! \~russian
|
||||
//! Создать копию отрезка и сдвинуть её на значение координат точки \a PIPoint.
|
||||
//! \details Является копией метода \a translated().
|
||||
@@ -153,33 +152,33 @@ public:
|
||||
}
|
||||
|
||||
//! \~russian Сдвинуть линию по двум координатам на значение \a x.
|
||||
void operator +=(Type x) {translate(x, x);}
|
||||
void operator+=(Type x) { translate(x, x); }
|
||||
|
||||
//! \~russian Сдвинуть линию по двум координатам на величину координат точки \a PIPoint.
|
||||
void operator +=(const PIPoint<Type> & p) {translate(p);}
|
||||
void operator+=(const PIPoint<Type> & p) { translate(p); }
|
||||
|
||||
//! \~russian Сдвинуть линию по двум координатам на значение \a x.
|
||||
void operator -=(Type x) {translate(-x, -x);}
|
||||
void operator-=(Type x) { translate(-x, -x); }
|
||||
|
||||
//! \~russian Сдвинуть линию по двум координатам на величину координат точки \a PIPoint.
|
||||
void operator -=(const PIPoint<Type> & p) {translate(-p);}
|
||||
void operator-=(const PIPoint<Type> & p) { translate(-p); }
|
||||
|
||||
//! \~russian Сдвинуть линию по двум координатам на величину координат точки \a PIPoint.
|
||||
PILine<Type> operator +(const PIPoint<Type> & p) {return translated(p);}
|
||||
PILine<Type> operator+(const PIPoint<Type> & p) { return translated(p); }
|
||||
|
||||
//! \~russian Сдвинуть линию по двум координатам на величину координат точки \a PIPoint.
|
||||
PILine<Type> operator -(const PIPoint<Type> & p) {return translated(-p);}
|
||||
PILine<Type> operator-(const PIPoint<Type> & p) { return translated(-p); }
|
||||
|
||||
//! \~russian Проверить равенство координат двух отрезков.
|
||||
bool operator ==(const PILine<Type> & r) const {return (p0 == r.p0 && p1 == r.p1);}
|
||||
bool operator==(const PILine<Type> & r) const { return (p0 == r.p0 && p1 == r.p1); }
|
||||
|
||||
//! \~russian Проверить неравенство координат двух отрезков.
|
||||
bool operator !=(const PILine<Type> & r) const {return (p1 != r.p1 || p1 != r.p1);}
|
||||
bool operator!=(const PILine<Type> & r) const { return (p1 != r.p1 || p1 != r.p1); }
|
||||
};
|
||||
|
||||
//! \~russian Перегруженный оператор для вывода координат в \a PICout.
|
||||
template<typename Type>
|
||||
PICout operator <<(PICout & s, const PILine<Type> & v) {
|
||||
PICout operator<<(PICout & s, const PILine<Type> & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "Line{" << v.p0 << ", " << v.p1 << "}";
|
||||
s.restoreControls();
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Basic mathematical functions and defines
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Basic mathematical functions and defines
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pimathbase.h"
|
||||
|
||||
#include "pitime.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
@@ -39,60 +41,60 @@ double piJ0(const double & v) {
|
||||
double q2;
|
||||
double p3;
|
||||
double q3;
|
||||
xsq_ = 64. / (x * x);
|
||||
p2 = 0.0;
|
||||
p2 = 2485.271928957404011288128951 + xsq_ * p2;
|
||||
p2 = 153982.6532623911470917825993 + xsq_ * p2;
|
||||
p2 = 2016135.283049983642487182349 + xsq_ * p2;
|
||||
p2 = 8413041.456550439208464315611 + xsq_ * p2;
|
||||
p2 = 12332384.76817638145232406055 + xsq_ * p2;
|
||||
p2 = 5393485.083869438325262122897 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = 2615.700736920839685159081813 + xsq_ * q2;
|
||||
q2 = 156001.7276940030940592769933 + xsq_ * q2;
|
||||
q2 = 2025066.801570134013891035236 + xsq_ * q2;
|
||||
q2 = 8426449.050629797331554404810 + xsq_ * q2;
|
||||
q2 = 12338310.22786324960844856182 + xsq_ * q2;
|
||||
q2 = 5393485.083869438325560444960 + xsq_ * q2;
|
||||
p3 = -0.0;
|
||||
p3 = -4.887199395841261531199129300 +xsq_ * p3;
|
||||
p3 = -226.2630641933704113967255053 +xsq_ * p3;
|
||||
p3 = -2365.956170779108192723612816 +xsq_ * p3;
|
||||
p3 = -8239.066313485606568803548860 +xsq_ * p3;
|
||||
p3 = -10381.41698748464093880530341 +xsq_ * p3;
|
||||
p3 = -3984.617357595222463506790588 +xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 408.7714673983499223402830260 + xsq_ * q3;
|
||||
q3 = 15704.89191515395519392882766 + xsq_ * q3;
|
||||
q3 = 156021.3206679291652539287109 + xsq_ * q3;
|
||||
q3 = 533291.3634216897168722255057 + xsq_ * q3;
|
||||
q3 = 666745.4239319826986004038103 + xsq_ * q3;
|
||||
q3 = 255015.5108860942382983170882 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8. * p3 / q3 / x;
|
||||
nn = x- M_PI / 4.;
|
||||
xsq_ = 64. / (x * x);
|
||||
p2 = 0.0;
|
||||
p2 = 2485.271928957404011288128951 + xsq_ * p2;
|
||||
p2 = 153982.6532623911470917825993 + xsq_ * p2;
|
||||
p2 = 2016135.283049983642487182349 + xsq_ * p2;
|
||||
p2 = 8413041.456550439208464315611 + xsq_ * p2;
|
||||
p2 = 12332384.76817638145232406055 + xsq_ * p2;
|
||||
p2 = 5393485.083869438325262122897 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = 2615.700736920839685159081813 + xsq_ * q2;
|
||||
q2 = 156001.7276940030940592769933 + xsq_ * q2;
|
||||
q2 = 2025066.801570134013891035236 + xsq_ * q2;
|
||||
q2 = 8426449.050629797331554404810 + xsq_ * q2;
|
||||
q2 = 12338310.22786324960844856182 + xsq_ * q2;
|
||||
q2 = 5393485.083869438325560444960 + xsq_ * q2;
|
||||
p3 = -0.0;
|
||||
p3 = -4.887199395841261531199129300 + xsq_ * p3;
|
||||
p3 = -226.2630641933704113967255053 + xsq_ * p3;
|
||||
p3 = -2365.956170779108192723612816 + xsq_ * p3;
|
||||
p3 = -8239.066313485606568803548860 + xsq_ * p3;
|
||||
p3 = -10381.41698748464093880530341 + xsq_ * p3;
|
||||
p3 = -3984.617357595222463506790588 + xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 408.7714673983499223402830260 + xsq_ * q3;
|
||||
q3 = 15704.89191515395519392882766 + xsq_ * q3;
|
||||
q3 = 156021.3206679291652539287109 + xsq_ * q3;
|
||||
q3 = 533291.3634216897168722255057 + xsq_ * q3;
|
||||
q3 = 666745.4239319826986004038103 + xsq_ * q3;
|
||||
q3 = 255015.5108860942382983170882 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8. * p3 / q3 / x;
|
||||
nn = x - M_PI / 4.;
|
||||
result = sqrt(2. / M_PI / x) * (pzero * cos(nn) - qzero * sin(nn));
|
||||
return result;
|
||||
}
|
||||
xsq = x * x;
|
||||
p1 = 26857.86856980014981415848441;
|
||||
p1 = -40504123.71833132706360663322 + xsq * p1;
|
||||
p1 = 25071582855.36881945555156435 + xsq * p1;
|
||||
p1 = -8085222034853.793871199468171 + xsq * p1;
|
||||
p1 = 1434354939140344.111664316553 + xsq * p1;
|
||||
p1 = -136762035308817138.6865416609 + xsq * p1;
|
||||
p1 = 6382059341072356562.289432465 + xsq * p1;
|
||||
p1 = -117915762910761053603.8440800 + xsq * p1;
|
||||
p1 = 493378725179413356181.6813446 + xsq * p1;
|
||||
q1 = 1.;
|
||||
q1 = 1363.063652328970604442810507 + xsq * q1;
|
||||
q1 = 1114636.098462985378182402543 + xsq * q1;
|
||||
q1 = 669998767.2982239671814028660 + xsq * q1;
|
||||
q1 = 312304311494.1213172572469442 + xsq * q1;
|
||||
q1 = 112775673967979.8507056031594 + xsq * q1;
|
||||
q1 = 30246356167094626.98627330784 + xsq * q1;
|
||||
q1 = 5428918384092285160.200195092 + xsq * q1;
|
||||
q1 = 493378725179413356211.3278438 + xsq * q1;
|
||||
p1 = 26857.86856980014981415848441;
|
||||
p1 = -40504123.71833132706360663322 + xsq * p1;
|
||||
p1 = 25071582855.36881945555156435 + xsq * p1;
|
||||
p1 = -8085222034853.793871199468171 + xsq * p1;
|
||||
p1 = 1434354939140344.111664316553 + xsq * p1;
|
||||
p1 = -136762035308817138.6865416609 + xsq * p1;
|
||||
p1 = 6382059341072356562.289432465 + xsq * p1;
|
||||
p1 = -117915762910761053603.8440800 + xsq * p1;
|
||||
p1 = 493378725179413356181.6813446 + xsq * p1;
|
||||
q1 = 1.;
|
||||
q1 = 1363.063652328970604442810507 + xsq * q1;
|
||||
q1 = 1114636.098462985378182402543 + xsq * q1;
|
||||
q1 = 669998767.2982239671814028660 + xsq * q1;
|
||||
q1 = 312304311494.1213172572469442 + xsq * q1;
|
||||
q1 = 112775673967979.8507056031594 + xsq * q1;
|
||||
q1 = 30246356167094626.98627330784 + xsq * q1;
|
||||
q1 = 5428918384092285160.200195092 + xsq * q1;
|
||||
q1 = 493378725179413356211.3278438 + xsq * q1;
|
||||
return p1 / q1;
|
||||
#else
|
||||
return j0(v);
|
||||
@@ -112,68 +114,66 @@ double piJ1(const double & v) {
|
||||
double q1;
|
||||
double result;
|
||||
s = sign(x);
|
||||
if (x < 0)
|
||||
x = -x;
|
||||
if (x < 0) x = -x;
|
||||
if (x > 8.) {
|
||||
double xsq_;
|
||||
double p2;
|
||||
double q2;
|
||||
double p3;
|
||||
double q3;
|
||||
xsq_ = 64.0 / (x * x);
|
||||
p2 = -1611.616644324610116477412898;
|
||||
p2 = -109824.0554345934672737413139 + xsq_ * p2;
|
||||
p2 = -1523529.351181137383255105722 + xsq_ * p2;
|
||||
p2 = -6603373.248364939109255245434 + xsq_ * p2;
|
||||
p2 = -9942246.505077641195658377899 + xsq_ * p2;
|
||||
p2 = -4435757.816794127857114720794 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = -1455.009440190496182453565068 + xsq_ * q2;
|
||||
q2 = -107263.8599110382011903063867 + xsq_ * q2;
|
||||
q2 = -1511809.506634160881644546358 + xsq_ * q2;
|
||||
q2 = -6585339.479723087072826915069 + xsq_ * q2;
|
||||
q2 = -9934124.389934585658967556309 + xsq_ * q2;
|
||||
q2 = -4435757.816794127856828016962 + xsq_ * q2;
|
||||
p3 = 35.26513384663603218592175580;
|
||||
p3 = 1706.375429020768002061283546 + xsq_ * p3;
|
||||
p3 = 18494.26287322386679652009819 + xsq_ * p3;
|
||||
p3 = 66178.83658127083517939992166 + xsq_ * p3;
|
||||
p3 = 85145.16067533570196555001171 + xsq_ * p3;
|
||||
p3 = 33220.91340985722351859704442 + xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 863.8367769604990967475517183 + xsq_ * q3;
|
||||
q3 = 37890.22974577220264142952256 + xsq_ * q3;
|
||||
q3 = 400294.4358226697511708610813 + xsq_ * q3;
|
||||
q3 = 1419460.669603720892855755253 + xsq_ * q3;
|
||||
q3 = 1819458.042243997298924553839 + xsq_ * q3;
|
||||
q3 = 708712.8194102874357377502472 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8 * p3 / q3 / x;
|
||||
nn = x - 3 * M_PI / 4;
|
||||
xsq_ = 64.0 / (x * x);
|
||||
p2 = -1611.616644324610116477412898;
|
||||
p2 = -109824.0554345934672737413139 + xsq_ * p2;
|
||||
p2 = -1523529.351181137383255105722 + xsq_ * p2;
|
||||
p2 = -6603373.248364939109255245434 + xsq_ * p2;
|
||||
p2 = -9942246.505077641195658377899 + xsq_ * p2;
|
||||
p2 = -4435757.816794127857114720794 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = -1455.009440190496182453565068 + xsq_ * q2;
|
||||
q2 = -107263.8599110382011903063867 + xsq_ * q2;
|
||||
q2 = -1511809.506634160881644546358 + xsq_ * q2;
|
||||
q2 = -6585339.479723087072826915069 + xsq_ * q2;
|
||||
q2 = -9934124.389934585658967556309 + xsq_ * q2;
|
||||
q2 = -4435757.816794127856828016962 + xsq_ * q2;
|
||||
p3 = 35.26513384663603218592175580;
|
||||
p3 = 1706.375429020768002061283546 + xsq_ * p3;
|
||||
p3 = 18494.26287322386679652009819 + xsq_ * p3;
|
||||
p3 = 66178.83658127083517939992166 + xsq_ * p3;
|
||||
p3 = 85145.16067533570196555001171 + xsq_ * p3;
|
||||
p3 = 33220.91340985722351859704442 + xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 863.8367769604990967475517183 + xsq_ * q3;
|
||||
q3 = 37890.22974577220264142952256 + xsq_ * q3;
|
||||
q3 = 400294.4358226697511708610813 + xsq_ * q3;
|
||||
q3 = 1419460.669603720892855755253 + xsq_ * q3;
|
||||
q3 = 1819458.042243997298924553839 + xsq_ * q3;
|
||||
q3 = 708712.8194102874357377502472 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8 * p3 / q3 / x;
|
||||
nn = x - 3 * M_PI / 4;
|
||||
result = sqrt(2 / M_PI / x) * (pzero * cos(nn) - qzero * sin(nn));
|
||||
if (s < 0)
|
||||
result = -result;
|
||||
if (s < 0) result = -result;
|
||||
return result;
|
||||
}
|
||||
xsq = sqr(x);
|
||||
p1 = 2701.122710892323414856790990;
|
||||
p1 = -4695753.530642995859767162166 + xsq * p1;
|
||||
p1 = 3413234182.301700539091292655 + xsq * p1;
|
||||
p1 = -1322983480332.126453125473247 + xsq * p1;
|
||||
p1 = 290879526383477.5409737601689 + xsq * p1;
|
||||
p1 = -35888175699101060.50743641413 + xsq * p1;
|
||||
p1 = 2316433580634002297.931815435 + xsq * p1;
|
||||
p1 = -66721065689249162980.20941484 + xsq * p1;
|
||||
p1 = 581199354001606143928.050809 + xsq * p1;
|
||||
q1 = 1.0;
|
||||
q1 = 1606.931573481487801970916749 + xsq * q1;
|
||||
q1 = 1501793.594998585505921097578 + xsq * q1;
|
||||
q1 = 1013863514.358673989967045588 + xsq * q1;
|
||||
q1 = 524371026216.7649715406728642 + xsq * q1;
|
||||
q1 = 208166122130760.7351240184229 + xsq * q1;
|
||||
q1 = 60920613989175217.46105196863 + xsq * q1;
|
||||
q1 = 11857707121903209998.37113348 + xsq * q1;
|
||||
q1 = 1162398708003212287858.529400 + xsq * q1;
|
||||
xsq = sqr(x);
|
||||
p1 = 2701.122710892323414856790990;
|
||||
p1 = -4695753.530642995859767162166 + xsq * p1;
|
||||
p1 = 3413234182.301700539091292655 + xsq * p1;
|
||||
p1 = -1322983480332.126453125473247 + xsq * p1;
|
||||
p1 = 290879526383477.5409737601689 + xsq * p1;
|
||||
p1 = -35888175699101060.50743641413 + xsq * p1;
|
||||
p1 = 2316433580634002297.931815435 + xsq * p1;
|
||||
p1 = -66721065689249162980.20941484 + xsq * p1;
|
||||
p1 = 581199354001606143928.050809 + xsq * p1;
|
||||
q1 = 1.0;
|
||||
q1 = 1606.931573481487801970916749 + xsq * q1;
|
||||
q1 = 1501793.594998585505921097578 + xsq * q1;
|
||||
q1 = 1013863514.358673989967045588 + xsq * q1;
|
||||
q1 = 524371026216.7649715406728642 + xsq * q1;
|
||||
q1 = 208166122130760.7351240184229 + xsq * q1;
|
||||
q1 = 60920613989175217.46105196863 + xsq * q1;
|
||||
q1 = 11857707121903209998.37113348 + xsq * q1;
|
||||
q1 = 1162398708003212287858.529400 + xsq * q1;
|
||||
result = s * x * p1 / q1;
|
||||
return result;
|
||||
#else
|
||||
@@ -203,8 +203,7 @@ double piJn(int n, const double & v) {
|
||||
} else
|
||||
sg = 1;
|
||||
if (x < 0) {
|
||||
if (n % 2 != 0)
|
||||
sg = -sg;
|
||||
if (n % 2 != 0) sg = -sg;
|
||||
x = -x;
|
||||
}
|
||||
if (n == 0) {
|
||||
@@ -226,26 +225,26 @@ double piJn(int n, const double & v) {
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
k = 53;
|
||||
pk = 2 * (n + k);
|
||||
k = 53;
|
||||
pk = 2 * (n + k);
|
||||
ans = pk;
|
||||
xk = x * x;
|
||||
xk = x * x;
|
||||
do {
|
||||
pk = pk - 2.0;
|
||||
pk = pk - 2.0;
|
||||
ans = pk - xk / ans;
|
||||
k = k - 1;
|
||||
k = k - 1;
|
||||
} while (k != 0);
|
||||
ans = x / ans;
|
||||
pk = 1.0;
|
||||
ans = x / ans;
|
||||
pk = 1.0;
|
||||
pkm1 = 1.0 / ans;
|
||||
k = n - 1;
|
||||
r = 2 * k;
|
||||
k = n - 1;
|
||||
r = 2 * k;
|
||||
do {
|
||||
pkm2 = (pkm1 * r - pk * x) / x;
|
||||
pk = pkm1;
|
||||
pk = pkm1;
|
||||
pkm1 = pkm2;
|
||||
r = r - 2.0;
|
||||
k = k - 1;
|
||||
r = r - 2.0;
|
||||
k = k - 1;
|
||||
} while (k != 0);
|
||||
if (fabs(pk) > fabs(pkm1))
|
||||
ans = piJ1(x) / pk;
|
||||
@@ -275,60 +274,60 @@ double piY0(const double & v) {
|
||||
double q2;
|
||||
double p3;
|
||||
double q3;
|
||||
xsq_ = 64.0 / (x * x);
|
||||
p2 = 0.0;
|
||||
p2 = 2485.271928957404011288128951 + xsq_ * p2;
|
||||
p2 = 153982.6532623911470917825993 + xsq_ * p2;
|
||||
p2 = 2016135.283049983642487182349 + xsq_ * p2;
|
||||
p2 = 8413041.456550439208464315611 + xsq_ * p2;
|
||||
p2 = 12332384.76817638145232406055 + xsq_ * p2;
|
||||
p2 = 5393485.083869438325262122897 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = 2615.700736920839685159081813 + xsq_ * q2;
|
||||
q2 = 156001.7276940030940592769933 + xsq_ * q2;
|
||||
q2 = 2025066.801570134013891035236 + xsq_ * q2;
|
||||
q2 = 8426449.050629797331554404810 + xsq_ * q2;
|
||||
q2 = 12338310.22786324960844856182 + xsq_ * q2;
|
||||
q2 = 5393485.083869438325560444960 + xsq_ * q2;
|
||||
p3 = -0.0;
|
||||
p3 = -4.887199395841261531199129300 + xsq_ * p3;
|
||||
p3 = -226.2630641933704113967255053 + xsq_ * p3;
|
||||
p3 = -2365.956170779108192723612816 + xsq_ * p3;
|
||||
p3 = -8239.066313485606568803548860 + xsq_ * p3;
|
||||
p3 = -10381.41698748464093880530341 + xsq_ * p3;
|
||||
p3 = -3984.617357595222463506790588 + xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 408.7714673983499223402830260 + xsq_ * q3;
|
||||
q3 = 15704.89191515395519392882766 + xsq_ * q3;
|
||||
q3 = 156021.3206679291652539287109 + xsq_ * q3;
|
||||
q3 = 533291.3634216897168722255057 + xsq_ * q3;
|
||||
q3 = 666745.4239319826986004038103 + xsq_ * q3;
|
||||
q3 = 255015.5108860942382983170882 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8 * p3 / q3 / x;
|
||||
nn = x - M_PI / 4;
|
||||
xsq_ = 64.0 / (x * x);
|
||||
p2 = 0.0;
|
||||
p2 = 2485.271928957404011288128951 + xsq_ * p2;
|
||||
p2 = 153982.6532623911470917825993 + xsq_ * p2;
|
||||
p2 = 2016135.283049983642487182349 + xsq_ * p2;
|
||||
p2 = 8413041.456550439208464315611 + xsq_ * p2;
|
||||
p2 = 12332384.76817638145232406055 + xsq_ * p2;
|
||||
p2 = 5393485.083869438325262122897 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = 2615.700736920839685159081813 + xsq_ * q2;
|
||||
q2 = 156001.7276940030940592769933 + xsq_ * q2;
|
||||
q2 = 2025066.801570134013891035236 + xsq_ * q2;
|
||||
q2 = 8426449.050629797331554404810 + xsq_ * q2;
|
||||
q2 = 12338310.22786324960844856182 + xsq_ * q2;
|
||||
q2 = 5393485.083869438325560444960 + xsq_ * q2;
|
||||
p3 = -0.0;
|
||||
p3 = -4.887199395841261531199129300 + xsq_ * p3;
|
||||
p3 = -226.2630641933704113967255053 + xsq_ * p3;
|
||||
p3 = -2365.956170779108192723612816 + xsq_ * p3;
|
||||
p3 = -8239.066313485606568803548860 + xsq_ * p3;
|
||||
p3 = -10381.41698748464093880530341 + xsq_ * p3;
|
||||
p3 = -3984.617357595222463506790588 + xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 408.7714673983499223402830260 + xsq_ * q3;
|
||||
q3 = 15704.89191515395519392882766 + xsq_ * q3;
|
||||
q3 = 156021.3206679291652539287109 + xsq_ * q3;
|
||||
q3 = 533291.3634216897168722255057 + xsq_ * q3;
|
||||
q3 = 666745.4239319826986004038103 + xsq_ * q3;
|
||||
q3 = 255015.5108860942382983170882 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8 * p3 / q3 / x;
|
||||
nn = x - M_PI / 4;
|
||||
result = sqrt(2 / M_PI / x) * (pzero * sin(nn) + qzero * cos(nn));
|
||||
return result;
|
||||
}
|
||||
xsq = sqr(x);
|
||||
p4 = -41370.35497933148554125235152;
|
||||
p4 = 59152134.65686889654273830069 + xsq * p4;
|
||||
p4 = -34363712229.79040378171030138 + xsq * p4;
|
||||
p4 = 10255208596863.94284509167421 + xsq * p4;
|
||||
p4 = -1648605817185729.473122082537 + xsq * p4;
|
||||
p4 = 137562431639934407.8571335453 + xsq * p4;
|
||||
p4 = -5247065581112764941.297350814 + xsq * p4;
|
||||
p4 = 65874732757195549259.99402049 + xsq * p4;
|
||||
p4 = -27502866786291095837.01933175 + xsq * p4;
|
||||
q4 = 1.0;
|
||||
q4 = 1282.452772478993804176329391 + xsq * q4;
|
||||
q4 = 1001702.641288906265666651753 + xsq * q4;
|
||||
q4 = 579512264.0700729537480087915 + xsq * q4;
|
||||
q4 = 261306575504.1081249568482092 + xsq * q4;
|
||||
q4 = 91620380340751.85262489147968 + xsq * q4;
|
||||
q4 = 23928830434997818.57439356652 + xsq * q4;
|
||||
q4 = 4192417043410839973.904769661 + xsq * q4;
|
||||
q4 = 372645883898616588198.9980 + xsq * q4;
|
||||
xsq = sqr(x);
|
||||
p4 = -41370.35497933148554125235152;
|
||||
p4 = 59152134.65686889654273830069 + xsq * p4;
|
||||
p4 = -34363712229.79040378171030138 + xsq * p4;
|
||||
p4 = 10255208596863.94284509167421 + xsq * p4;
|
||||
p4 = -1648605817185729.473122082537 + xsq * p4;
|
||||
p4 = 137562431639934407.8571335453 + xsq * p4;
|
||||
p4 = -5247065581112764941.297350814 + xsq * p4;
|
||||
p4 = 65874732757195549259.99402049 + xsq * p4;
|
||||
p4 = -27502866786291095837.01933175 + xsq * p4;
|
||||
q4 = 1.0;
|
||||
q4 = 1282.452772478993804176329391 + xsq * q4;
|
||||
q4 = 1001702.641288906265666651753 + xsq * q4;
|
||||
q4 = 579512264.0700729537480087915 + xsq * q4;
|
||||
q4 = 261306575504.1081249568482092 + xsq * q4;
|
||||
q4 = 91620380340751.85262489147968 + xsq * q4;
|
||||
q4 = 23928830434997818.57439356652 + xsq * q4;
|
||||
q4 = 4192417043410839973.904769661 + xsq * q4;
|
||||
q4 = 372645883898616588198.9980 + xsq * q4;
|
||||
result = p4 / q4 + 2 / M_PI * piJ0(x) * log(x);
|
||||
return result;
|
||||
#else
|
||||
@@ -353,59 +352,59 @@ double piY1(const double & v) {
|
||||
double q2;
|
||||
double p3;
|
||||
double q3;
|
||||
xsq_ = 64.0 / (x * x);
|
||||
p2 = -1611.616644324610116477412898;
|
||||
p2 = -109824.0554345934672737413139 + xsq_ * p2;
|
||||
p2 = -1523529.351181137383255105722 + xsq_ * p2;
|
||||
p2 = -6603373.248364939109255245434 + xsq_ * p2;
|
||||
p2 = -9942246.505077641195658377899 + xsq_ * p2;
|
||||
p2 = -4435757.816794127857114720794 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = -1455.009440190496182453565068 + xsq_ * q2;
|
||||
q2 = -107263.8599110382011903063867 + xsq_ * q2;
|
||||
q2 = -1511809.506634160881644546358 + xsq_ * q2;
|
||||
q2 = -6585339.479723087072826915069 + xsq_ * q2;
|
||||
q2 = -9934124.389934585658967556309 + xsq_ * q2;
|
||||
q2 = -4435757.816794127856828016962 + xsq_ * q2;
|
||||
p3 = 35.26513384663603218592175580;
|
||||
p3 = 1706.375429020768002061283546 + xsq_ * p3;
|
||||
p3 = 18494.26287322386679652009819 + xsq_ * p3;
|
||||
p3 = 66178.83658127083517939992166 + xsq_ * p3;
|
||||
p3 = 85145.16067533570196555001171 + xsq_ * p3;
|
||||
p3 = 33220.91340985722351859704442 + xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 863.8367769604990967475517183 + xsq_ * q3;
|
||||
q3 = 37890.22974577220264142952256 + xsq_ * q3;
|
||||
q3 = 400294.4358226697511708610813 + xsq_ * q3;
|
||||
q3 = 1419460.669603720892855755253 + xsq_ * q3;
|
||||
q3 = 1819458.042243997298924553839 + xsq_ * q3;
|
||||
q3 = 708712.8194102874357377502472 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8 * p3 / q3 / x;
|
||||
nn = x - 3 * M_PI / 4;
|
||||
xsq_ = 64.0 / (x * x);
|
||||
p2 = -1611.616644324610116477412898;
|
||||
p2 = -109824.0554345934672737413139 + xsq_ * p2;
|
||||
p2 = -1523529.351181137383255105722 + xsq_ * p2;
|
||||
p2 = -6603373.248364939109255245434 + xsq_ * p2;
|
||||
p2 = -9942246.505077641195658377899 + xsq_ * p2;
|
||||
p2 = -4435757.816794127857114720794 + xsq_ * p2;
|
||||
q2 = 1.0;
|
||||
q2 = -1455.009440190496182453565068 + xsq_ * q2;
|
||||
q2 = -107263.8599110382011903063867 + xsq_ * q2;
|
||||
q2 = -1511809.506634160881644546358 + xsq_ * q2;
|
||||
q2 = -6585339.479723087072826915069 + xsq_ * q2;
|
||||
q2 = -9934124.389934585658967556309 + xsq_ * q2;
|
||||
q2 = -4435757.816794127856828016962 + xsq_ * q2;
|
||||
p3 = 35.26513384663603218592175580;
|
||||
p3 = 1706.375429020768002061283546 + xsq_ * p3;
|
||||
p3 = 18494.26287322386679652009819 + xsq_ * p3;
|
||||
p3 = 66178.83658127083517939992166 + xsq_ * p3;
|
||||
p3 = 85145.16067533570196555001171 + xsq_ * p3;
|
||||
p3 = 33220.91340985722351859704442 + xsq_ * p3;
|
||||
q3 = 1.0;
|
||||
q3 = 863.8367769604990967475517183 + xsq_ * q3;
|
||||
q3 = 37890.22974577220264142952256 + xsq_ * q3;
|
||||
q3 = 400294.4358226697511708610813 + xsq_ * q3;
|
||||
q3 = 1419460.669603720892855755253 + xsq_ * q3;
|
||||
q3 = 1819458.042243997298924553839 + xsq_ * q3;
|
||||
q3 = 708712.8194102874357377502472 + xsq_ * q3;
|
||||
pzero = p2 / q2;
|
||||
qzero = 8 * p3 / q3 / x;
|
||||
nn = x - 3 * M_PI / 4;
|
||||
result = sqrt(2 / M_PI / x) * (pzero * sin(nn) + qzero * cos(nn));
|
||||
return result;
|
||||
}
|
||||
xsq = sqr(x);
|
||||
p4 = -2108847.540133123652824139923;
|
||||
p4 = 3639488548.124002058278999428 + xsq * p4;
|
||||
p4 = -2580681702194.450950541426399 + xsq * p4;
|
||||
p4 = 956993023992168.3481121552788 + xsq * p4;
|
||||
p4 = -196588746272214065.8820322248 + xsq * p4;
|
||||
p4 = 21931073399177975921.11427556 + xsq * p4;
|
||||
p4 = -1212297555414509577913.561535 + xsq * p4;
|
||||
p4 = 26554738314348543268942.48968 + xsq * p4;
|
||||
p4 = -99637534243069222259967.44354 + xsq * p4;
|
||||
q4 = 1.0;
|
||||
q4 = 1612.361029677000859332072312 + xsq * q4;
|
||||
q4 = 1563282.754899580604737366452 + xsq * q4;
|
||||
q4 = 1128686837.169442121732366891 + xsq * q4;
|
||||
q4 = 646534088126.5275571961681500 + xsq * q4;
|
||||
q4 = 297663212564727.6729292742282 + xsq * q4;
|
||||
q4 = 108225825940881955.2553850180 + xsq * q4;
|
||||
q4 = 29549879358971486742.90758119 + xsq * q4;
|
||||
q4 = 5435310377188854170800.653097 + xsq * q4;
|
||||
q4 = 508206736694124324531442.4152 + xsq * q4;
|
||||
xsq = sqr(x);
|
||||
p4 = -2108847.540133123652824139923;
|
||||
p4 = 3639488548.124002058278999428 + xsq * p4;
|
||||
p4 = -2580681702194.450950541426399 + xsq * p4;
|
||||
p4 = 956993023992168.3481121552788 + xsq * p4;
|
||||
p4 = -196588746272214065.8820322248 + xsq * p4;
|
||||
p4 = 21931073399177975921.11427556 + xsq * p4;
|
||||
p4 = -1212297555414509577913.561535 + xsq * p4;
|
||||
p4 = 26554738314348543268942.48968 + xsq * p4;
|
||||
p4 = -99637534243069222259967.44354 + xsq * p4;
|
||||
q4 = 1.0;
|
||||
q4 = 1612.361029677000859332072312 + xsq * q4;
|
||||
q4 = 1563282.754899580604737366452 + xsq * q4;
|
||||
q4 = 1128686837.169442121732366891 + xsq * q4;
|
||||
q4 = 646534088126.5275571961681500 + xsq * q4;
|
||||
q4 = 297663212564727.6729292742282 + xsq * q4;
|
||||
q4 = 108225825940881955.2553850180 + xsq * q4;
|
||||
q4 = 29549879358971486742.90758119 + xsq * q4;
|
||||
q4 = 5435310377188854170800.653097 + xsq * q4;
|
||||
q4 = 508206736694124324531442.4152 + xsq * q4;
|
||||
result = x * p4 / q4 + 2 / M_PI * (piJ1(x) * log(x) - 1 / x);
|
||||
return result;
|
||||
#else
|
||||
@@ -426,8 +425,7 @@ double piYn(int n, const double & v) {
|
||||
s = 1;
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
if (n % 2 != 0)
|
||||
s = -1;
|
||||
if (n % 2 != 0) s = -1;
|
||||
}
|
||||
if (n == 0) {
|
||||
result = piY0(x);
|
||||
@@ -441,8 +439,8 @@ double piYn(int n, const double & v) {
|
||||
b = piY1(x);
|
||||
for (i = 1; i <= n - 1; i++) {
|
||||
tmp = b;
|
||||
b = 2 * i / x * b - a;
|
||||
a = tmp;
|
||||
b = 2 * i / x * b - a;
|
||||
a = tmp;
|
||||
}
|
||||
result = s * b;
|
||||
return result;
|
||||
@@ -457,13 +455,13 @@ double randomn(double dv, double sv) {
|
||||
double s = 2., v0 = 0., v1 = 0.;
|
||||
if (agen) {
|
||||
agen = false;
|
||||
v1 = v1 * sqrt(-2 * log(s) / s);
|
||||
v1 = v1 * sqrt(-2 * log(s) / s);
|
||||
return v1 * sv + dv;
|
||||
}
|
||||
while (s > 1. || s == 0.) {
|
||||
v0 = randomd();
|
||||
v1 = randomd();
|
||||
s = v0*v0 + v1*v1;
|
||||
s = v0 * v0 + v1 * v1;
|
||||
}
|
||||
v0 = v0 * sqrt(-2 * log(s) / s);
|
||||
return v0 * sv + dv;
|
||||
@@ -471,5 +469,5 @@ double randomn(double dv, double sv) {
|
||||
|
||||
|
||||
double randomd() {
|
||||
return (double) rand() / RAND_MAX * 2. - 1.;
|
||||
return (double)rand() / RAND_MAX * 2. - 1.;
|
||||
}
|
||||
|
||||
@@ -5,22 +5,22 @@
|
||||
* \~russian Базовые математические функции и дефайны
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Basic mathematical functions and defines
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Basic mathematical functions and defines
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIMATHBASE_H
|
||||
|
||||
@@ -5,32 +5,33 @@
|
||||
* \~russian Комплексные числа
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PIP math complex
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
PIP math complex
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIMATHCOMPLEX_H
|
||||
#define PIMATHCOMPLEX_H
|
||||
|
||||
#include <complex>
|
||||
#include "pimathbase.h"
|
||||
#include "pibytearray.h"
|
||||
#include "pimathbase.h"
|
||||
#include "pivector2d.h"
|
||||
|
||||
#include <complex>
|
||||
|
||||
#define PIP_MATH_COMPLEX
|
||||
|
||||
using std::complex;
|
||||
@@ -50,11 +51,19 @@ const complexld complexld_i(0., 1.);
|
||||
const complexld complexld_0(0.);
|
||||
const complexld complexld_1(1.);
|
||||
|
||||
inline complexd sign(const complexd & x) {return complexd(sign(x.real()), sign(x.imag()));}
|
||||
inline complexd sign(const complexd & x) {
|
||||
return complexd(sign(x.real()), sign(x.imag()));
|
||||
}
|
||||
|
||||
inline complexd round(const complexd & c) {return complexd(piRound<double>(c.real()), piRound<double>(c.imag()));}
|
||||
inline complexd floor(const complexd & c) {return complexd(floor(c.real()), floor(c.imag()));}
|
||||
inline complexd ceil (const complexd & c) {return complexd(ceil(c.real()), ceil(c.imag()));}
|
||||
inline complexd round(const complexd & c) {
|
||||
return complexd(piRound<double>(c.real()), piRound<double>(c.imag()));
|
||||
}
|
||||
inline complexd floor(const complexd & c) {
|
||||
return complexd(floor(c.real()), floor(c.imag()));
|
||||
}
|
||||
inline complexd ceil(const complexd & c) {
|
||||
return complexd(ceil(c.real()), ceil(c.imag()));
|
||||
}
|
||||
|
||||
#define acosc acos
|
||||
#define asinc asin
|
||||
@@ -62,15 +71,29 @@ inline complexd ceil (const complexd & c) {return complexd(ceil(c.real()), ceil(
|
||||
|
||||
#ifdef CC_GCC
|
||||
# if CC_GCC_VERSION <= 0x025F
|
||||
inline complexd tan(const complexd & c) {return sin(c) / cos(c);}
|
||||
inline complexd tanh(const complexd & c) {return sinh(c) / cosh(c);}
|
||||
inline complexd log2(const complexd & c) {return log(c) / M_LN2;}
|
||||
inline complexd log10(const complexd & c) {return log(c) / M_LN10;}
|
||||
inline complexd tan(const complexd & c) {
|
||||
return sin(c) / cos(c);
|
||||
}
|
||||
inline complexd tanh(const complexd & c) {
|
||||
return sinh(c) / cosh(c);
|
||||
}
|
||||
inline complexd log2(const complexd & c) {
|
||||
return log(c) / M_LN2;
|
||||
}
|
||||
inline complexd log10(const complexd & c) {
|
||||
return log(c) / M_LN10;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline PICout operator <<(PICout s, const complex<T> & v) {s.space(); s.saveAndSetControls(0); s << "(" << v.real() << "; " << v.imag() << ")"; s.restoreControls(); return s;}
|
||||
inline PICout operator<<(PICout s, const complex<T> & v) {
|
||||
s.space();
|
||||
s.saveAndSetControls(0);
|
||||
s << "(" << v.real() << "; " << v.imag() << ")";
|
||||
s.restoreControls();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline PIVector<double> abs(const PIVector<complexd> & v) {
|
||||
@@ -86,17 +109,17 @@ inline PIVector2D<double> abs(const PIVector2D<complexd> & v) {
|
||||
PIVector2D<double> result(v.rows(), v.cols());
|
||||
for (uint i = 0; i < v.rows(); i++)
|
||||
for (uint j = 0; j < v.cols(); j++)
|
||||
result[i][j] = abs(v.element(i,j));
|
||||
result[i][j] = abs(v.element(i, j));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief floating point number specific comparison between value passed as parameter and zero
|
||||
*
|
||||
* @param v floating point parameter for comparison
|
||||
* @return true if v in locality of zero, otherwise false
|
||||
*/
|
||||
* \brief floating point number specific comparison between value passed as parameter and zero
|
||||
*
|
||||
* @param v floating point parameter for comparison
|
||||
* @return true if v in locality of zero, otherwise false
|
||||
*/
|
||||
template<typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
|
||||
inline bool PIMathFloatNullCompare(const T v) {
|
||||
static_assert(std::is_floating_point<T>::value, "Type must be floating point");
|
||||
@@ -104,15 +127,14 @@ inline bool PIMathFloatNullCompare(const T v) {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief floating point number specific comparison between parameter value and zero.
|
||||
*
|
||||
* @param v complex with floating point real and imag parts
|
||||
* @return true if absolute of v in locality of zero, otherwise false
|
||||
*/
|
||||
template<typename T,typename std::enable_if<
|
||||
std::is_floating_point<decltype(T::real)>::value &&
|
||||
std::is_floating_point<decltype(T::imag)>::value
|
||||
, int>::type = 0>
|
||||
* \brief floating point number specific comparison between parameter value and zero.
|
||||
*
|
||||
* @param v complex with floating point real and imag parts
|
||||
* @return true if absolute of v in locality of zero, otherwise false
|
||||
*/
|
||||
template<typename T,
|
||||
typename std::enable_if<std::is_floating_point<decltype(T::real)>::value && std::is_floating_point<decltype(T::imag)>::value,
|
||||
int>::type = 0>
|
||||
inline bool PIMathFloatNullCompare(const T v) {
|
||||
static_assert(std::is_floating_point<decltype(v.real)>::value, "Type must be floating point");
|
||||
static_assert(std::is_floating_point<decltype(v.imag)>::value, "Type must be floating point");
|
||||
|
||||
@@ -5,34 +5,36 @@
|
||||
//! \~russian Математическая матрица
|
||||
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathMatrix
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathMatrix
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIMATHMATRIX_H
|
||||
#define PIMATHMATRIX_H
|
||||
|
||||
#include "pimathvector.h"
|
||||
#include "pimathcomplex.h"
|
||||
#include "pimathvector.h"
|
||||
|
||||
|
||||
/// Matrix templated
|
||||
|
||||
#define PIMM_FOR for (uint r = 0; r < Rows; ++r) for (uint c = 0; c < Cols; ++c)
|
||||
#define PIMM_FOR \
|
||||
for (uint r = 0; r < Rows; ++r) \
|
||||
for (uint c = 0; c < Cols; ++c)
|
||||
#define PIMM_FOR_C for (uint i = 0; i < Cols; ++i)
|
||||
#define PIMM_FOR_R for (uint i = 0; i < Rows; ++i)
|
||||
|
||||
@@ -42,7 +44,8 @@
|
||||
//! \brief A class for fixed size and type matrix.
|
||||
//! \tparam `Rows` rows number of matrix.
|
||||
//! \tparam `Сols` columns number of matrix.
|
||||
//! \tparam `Type` is the data type of the matrix. There are can be basic C++ language data and different classes where the arithmetic operators(=, +=, -=, *=, /=, ==, !=, +, -, *, /)
|
||||
//! \tparam `Type` is the data type of the matrix. There are can be basic C++ language data and different classes where the arithmetic
|
||||
//! operators(=, +=, -=, *=, /=, ==, !=, +, -, *, /)
|
||||
//! of the C++ language are implemented
|
||||
//! \~russian
|
||||
//! \brief Класс для работы с матрицами фиксированного размера и типа данных.
|
||||
@@ -53,7 +56,7 @@
|
||||
//! \tparam `Rows` количество строк матрицы.
|
||||
//! \tparam `Сols` количество столбцов матрицы.
|
||||
//! \tparam `Type`тип данных матрицы. Здесь можеть быть базовый тип данных C++ или различные классы,
|
||||
//! где реализованы арифметические операторы(=, +=, -=, *=, /=, ==, !=, +, -, *, /) языка C++.
|
||||
//! где реализованы арифметические операторы(=, +=, -=, *=, /=, ==, !=, +, -, *, /) языка C++.
|
||||
template<uint Rows, uint Cols = Rows, typename Type = double>
|
||||
class PIP_EXPORT PIMathMatrixT {
|
||||
typedef PIMathMatrixT<Rows, Cols, Type> _CMatrix;
|
||||
@@ -63,30 +66,32 @@ class PIP_EXPORT PIMathMatrixT {
|
||||
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
|
||||
static_assert(Rows > 0, "Row count must be > 0");
|
||||
static_assert(Cols > 0, "Column count must be > 0");
|
||||
|
||||
public:
|
||||
//! \~english
|
||||
//! \brief Constructs \a PIMathMatrixT that is filled by \a new_value.
|
||||
//! \~russian
|
||||
//! \brief Создает \a PIMathMatrixT и заполняет её из \a new_value.
|
||||
PIMathMatrixT(const Type &new_value = Type()) {PIMM_FOR m[r][c] = new_value;}
|
||||
PIMathMatrixT(const Type & new_value = Type()) { PIMM_FOR m[r][c] = new_value; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Contructs \a PIMathMatrixT from \a PIVector.
|
||||
//! \~russian
|
||||
//! \brief Создает \a PIMathMatrixT и заполняет её из \a PIVector.
|
||||
PIMathMatrixT(const PIVector<Type> &val) {
|
||||
assert(Rows*Cols == val.size());
|
||||
int i = 0;
|
||||
PIMathMatrixT(const PIVector<Type> & val) {
|
||||
assert(Rows * Cols == val.size());
|
||||
int i = 0;
|
||||
PIMM_FOR m[r][c] = val[i++];
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Contructs \a PIMathMatrixT from [C++11 initializer list](https://en.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \~russian
|
||||
//! \brief Создает \a PIMathMatrixT и заполняет её из [списка инициализации C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
//! \brief Создает \a PIMathMatrixT и заполняет её из [списка инициализации
|
||||
//! C++11](https://ru.cppreference.com/w/cpp/utility/initializer_list).
|
||||
PIMathMatrixT(std::initializer_list<Type> init_list) {
|
||||
assert(Rows*Cols == init_list.size());
|
||||
int i = 0;
|
||||
assert(Rows * Cols == init_list.size());
|
||||
int i = 0;
|
||||
PIMM_FOR m[r][c] = init_list.begin()[i++];
|
||||
}
|
||||
|
||||
@@ -98,7 +103,7 @@ public:
|
||||
//! \return единичная матрица типа \a PIMathMatrixT.
|
||||
static PIMathMatrixT<Rows, Cols, Type> identity() {
|
||||
PIMathMatrixT<Rows, Cols, Type> tm = PIMathMatrixT<Rows, Cols, Type>();
|
||||
PIMM_FOR tm.m[r][c] = (c == r ? Type(1) : Type(0));
|
||||
PIMM_FOR tm.m[r][c] = (c == r ? Type(1) : Type(0));
|
||||
return tm;
|
||||
}
|
||||
|
||||
@@ -108,7 +113,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Метод возвращающий количество столбцов в матрице.
|
||||
//! \return \a uint количество столбцов.
|
||||
constexpr uint cols() const {return Cols;}
|
||||
constexpr uint cols() const { return Cols; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Method which returns number of rows in matrix.
|
||||
@@ -116,7 +121,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Метод возвращающий количество строк в матрице.
|
||||
//! \return \a uint количество строк.
|
||||
constexpr uint rows() const {return Rows;}
|
||||
constexpr uint rows() const { return Rows; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Method which returns the selected column in PIMathVectorT format.
|
||||
@@ -160,8 +165,8 @@ public:
|
||||
//! \details Если вы введете индекс вне границ матрицы, то поведение не определено ("undefined behavior").
|
||||
//! \param index номер выбранного столбца.
|
||||
//! \param v вектор типа \a PIMathVectorT<Rows, Type>, которым необходимо заполнить столбец.
|
||||
//! \return матрица типа \a PIMathMatrixT<Rows, Cols, Type>.
|
||||
PIMathMatrixT<Rows, Cols, Type> &setCol(uint index, const PIMathVectorT<Rows, Type> &v) {
|
||||
//! \return матрица типа \a PIMathMatrixT<Rows, Cols, Type>.
|
||||
PIMathMatrixT<Rows, Cols, Type> & setCol(uint index, const PIMathVectorT<Rows, Type> & v) {
|
||||
PIMM_FOR_R m[i][index] = v[i];
|
||||
return *this;
|
||||
}
|
||||
@@ -178,7 +183,7 @@ public:
|
||||
//! \param index номер выбранной строки.
|
||||
//! \param v вектор типа \a PIMathVectorT<Cols, Type>, которым необходимо заполнить строку.
|
||||
//! \return матрица типа \a PIMathMatrixT<Rows, Cols, Type>.
|
||||
PIMathMatrixT<Rows, Cols, Type> &setRow(uint index, const PIMathVectorT<Cols, Type> &v) {
|
||||
PIMathMatrixT<Rows, Cols, Type> & setRow(uint index, const PIMathVectorT<Cols, Type> & v) {
|
||||
PIMM_FOR_C m[index][i] = v[i];
|
||||
return *this;
|
||||
}
|
||||
@@ -195,7 +200,7 @@ public:
|
||||
//! \param rf номер первой выбранной строки.
|
||||
//! \param rs номер второй выбранной строки.
|
||||
//! \return матрица типа \a PIMathMatrixT<Rows, Cols, Type>.
|
||||
PIMathMatrixT<Rows, Cols, Type> &swapRows(uint rf, uint rs) {
|
||||
PIMathMatrixT<Rows, Cols, Type> & swapRows(uint rf, uint rs) {
|
||||
PIMM_FOR_C piSwap<Type>(m[rf][i], m[rs][i]);
|
||||
return *this;
|
||||
}
|
||||
@@ -212,7 +217,7 @@ public:
|
||||
//! \param rf номер первого выбранного столбца.
|
||||
//! \param rs номер второго выбранного столбца.
|
||||
//! \return матрица типа \a PIMathMatrixT<Rows, Cols, Type>.
|
||||
PIMathMatrixT<Rows, Cols, Type> &swapCols(uint cf, uint cs) {
|
||||
PIMathMatrixT<Rows, Cols, Type> & swapCols(uint cf, uint cs) {
|
||||
PIMM_FOR_R piSwap<Type>(m[i][cf], m[i][cs]);
|
||||
return *this;
|
||||
}
|
||||
@@ -225,7 +230,7 @@ public:
|
||||
//! \brief Метод, заполняющий матрицу выбранным значением.
|
||||
//! \param v параметр тип и значения, которого выбираются и заносятся в матрицу.
|
||||
//! \return заполненная матрица типа \a PIMathMatrixT<Rows, Cols, Type>.
|
||||
PIMathMatrixT<Rows, Cols, Type> &fill(const Type &v) {
|
||||
PIMathMatrixT<Rows, Cols, Type> & fill(const Type & v) {
|
||||
PIMM_FOR m[r][c] = v;
|
||||
return *this;
|
||||
}
|
||||
@@ -287,7 +292,7 @@ public:
|
||||
//! \param row номер строки матрицы.
|
||||
//! \param col номер столбца матрицы.
|
||||
//! \return элемент матрицы.
|
||||
inline Type & element(uint row, uint col) {return m[row][col];}
|
||||
inline Type & element(uint row, uint col) { return m[row][col]; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Read-only access to element by `row` number and `col` number.
|
||||
@@ -301,7 +306,7 @@ public:
|
||||
//! \param row номер строки матрицы.
|
||||
//! \param col номер столбца матрицы.
|
||||
//! \return копия элемента матрицы.
|
||||
inline const Type & element(uint row, uint col) const {return m[row][col];}
|
||||
inline const Type & element(uint row, uint col) const { return m[row][col]; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Full access to the matrix row pointer.
|
||||
@@ -313,7 +318,7 @@ public:
|
||||
//! \details Если вы введете индекс вне границ матрицы, то поведение не определено ("undefined behavior").
|
||||
//! \param row номер строки матрицы.
|
||||
//! \return указатель на строку матрицы.
|
||||
Type *operator[](uint row) { return m[row]; }
|
||||
Type * operator[](uint row) { return m[row]; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Read-only access to the matrix row pointer.
|
||||
@@ -325,7 +330,7 @@ public:
|
||||
//! \details Если вы введете индекс вне границ матрицы, то поведение не определено ("undefined behavior").
|
||||
//! \param row номер строки матрицы.
|
||||
//! \return указатель на строку матрицы.
|
||||
const Type *operator[](uint row) const {return m[row];}
|
||||
const Type * operator[](uint row) const { return m[row]; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Matrix compare.
|
||||
@@ -335,7 +340,7 @@ public:
|
||||
//! \brief Сравнение матриц.
|
||||
//! \param sm матрица для сравнения.
|
||||
//! \return если матрицы равны true, иначе false.
|
||||
bool operator==(const PIMathMatrixT<Rows, Cols, Type> &sm) const {
|
||||
bool operator==(const PIMathMatrixT<Rows, Cols, Type> & sm) const {
|
||||
PIMM_FOR if (m[r][c] != sm.m[r][c]) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -348,7 +353,7 @@ public:
|
||||
//! \brief Отрицательное сравнение матриц.
|
||||
//! \param sm матрица для сравнения.
|
||||
//! \return если матрицы не равны true, иначе false.
|
||||
bool operator!=(const PIMathMatrixT<Rows, Cols, Type> &sm) const { return !(*this == sm); }
|
||||
bool operator!=(const PIMathMatrixT<Rows, Cols, Type> & sm) const { return !(*this == sm); }
|
||||
|
||||
//! \~english
|
||||
//! \brief Addition assignment with matrix `sm`.
|
||||
@@ -356,7 +361,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Сложение с присваиванием с матрицей `sm`.
|
||||
//! \param sm матрица для сложения с присваиванием.
|
||||
void operator+=(const PIMathMatrixT<Rows, Cols, Type> &sm) {PIMM_FOR m[r][c] += sm.m[r][c];}
|
||||
void operator+=(const PIMathMatrixT<Rows, Cols, Type> & sm) { PIMM_FOR m[r][c] += sm.m[r][c]; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Subtraction assignment with matrix `sm`.
|
||||
@@ -364,7 +369,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Вычитание с присваиванием с матрицей `sm`.
|
||||
//! \param sm матрица для вычитания с присваиванием.
|
||||
void operator-=(const PIMathMatrixT<Rows, Cols, Type> &sm) {PIMM_FOR m[r][c] -= sm.m[r][c];}
|
||||
void operator-=(const PIMathMatrixT<Rows, Cols, Type> & sm) { PIMM_FOR m[r][c] -= sm.m[r][c]; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Multiplication assignment with value `v`.
|
||||
@@ -372,9 +377,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Умножение с присваиванием с матрицей `v`.
|
||||
//! \param sm матрица для умножения с присваиванием.
|
||||
void operator*=(const Type &v) {
|
||||
PIMM_FOR m[r][c] *= v;
|
||||
}
|
||||
void operator*=(const Type & v) { PIMM_FOR m[r][c] *= v; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Division assignment with value `v`.
|
||||
@@ -382,7 +385,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Деление с присваиванием с матрицей `v`.
|
||||
//! \param sm матрица для деления с присваиванием.
|
||||
void operator/=(const Type &v) {
|
||||
void operator/=(const Type & v) {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
PIMM_FOR m[r][c] /= v;
|
||||
}
|
||||
@@ -407,7 +410,7 @@ public:
|
||||
//! \brief Матричное сложение.
|
||||
//! \param sm матричное слагаемое.
|
||||
//! \return результат матричного сложения.
|
||||
PIMathMatrixT<Rows, Cols, Type> operator+(const PIMathMatrixT<Rows, Cols, Type> &sm) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> operator+(const PIMathMatrixT<Rows, Cols, Type> & sm) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> tm = PIMathMatrixT<Rows, Cols, Type>(*this);
|
||||
PIMM_FOR tm.m[r][c] += sm.m[r][c];
|
||||
return tm;
|
||||
@@ -421,7 +424,7 @@ public:
|
||||
//! \brief Матричная разность.
|
||||
//! \param sm матричное вычитаемое.
|
||||
//! \return результат матричной разности.
|
||||
PIMathMatrixT<Rows, Cols, Type> operator-(const PIMathMatrixT<Rows, Cols, Type> &sm) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> operator-(const PIMathMatrixT<Rows, Cols, Type> & sm) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> tm = PIMathMatrixT<Rows, Cols, Type>(*this);
|
||||
PIMM_FOR tm.m[r][c] -= sm.m[r][c];
|
||||
return tm;
|
||||
@@ -435,7 +438,7 @@ public:
|
||||
//! \brief Умножение матрицы на константу.
|
||||
//! \param v множитель.
|
||||
//! \return результат произведения.
|
||||
PIMathMatrixT<Rows, Cols, Type> operator*(const Type &v) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> operator*(const Type & v) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> tm = PIMathMatrixT<Rows, Cols, Type>(*this);
|
||||
PIMM_FOR tm.m[r][c] *= v;
|
||||
return tm;
|
||||
@@ -449,7 +452,7 @@ public:
|
||||
//! \brief Деление матрицы на константу.
|
||||
//! \param v делитель.
|
||||
//! \return результат деления.
|
||||
PIMathMatrixT<Rows, Cols, Type> operator/(const Type &v) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> operator/(const Type & v) const {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
PIMathMatrixT<Rows, Cols, Type> tm = PIMathMatrixT<Rows, Cols, Type>(*this);
|
||||
PIMM_FOR tm.m[r][c] /= v;
|
||||
@@ -457,7 +460,7 @@ public:
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Calculate Determinant of the matrix.
|
||||
//! \brief Calculate Determinant of the matrix.
|
||||
//! \details Works only with square matrix, nonzero matrices and invertible matrix.
|
||||
//! \param ok is a parameter with which we can find out if the method worked correctly.
|
||||
//! \return matrix determinant.
|
||||
@@ -466,7 +469,7 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return опеределитель матрицы.
|
||||
Type determinant(bool *ok = 0) const {
|
||||
Type determinant(bool * ok = 0) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> m(*this);
|
||||
bool k;
|
||||
Type ret = Type(0);
|
||||
@@ -505,7 +508,7 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return преобразованная верхнетреугольная матрицы.
|
||||
PIMathMatrixT<Rows, Cols, Type> &toUpperTriangular(bool *ok = 0) {
|
||||
PIMathMatrixT<Rows, Cols, Type> & toUpperTriangular(bool * ok = 0) {
|
||||
static_assert(Rows == Cols, "Works only with square matrix");
|
||||
PIMathMatrixT<Rows, Cols, Type> smat(*this);
|
||||
bool ndet;
|
||||
@@ -513,7 +516,8 @@ public:
|
||||
Type mul;
|
||||
for (uint i = 0; i < Cols; ++i) {
|
||||
ndet = true;
|
||||
for (uint j = 0; j < Rows; ++j) if (smat.m[i][j] != 0) ndet = false;
|
||||
for (uint j = 0; j < Rows; ++j)
|
||||
if (smat.m[i][j] != 0) ndet = false;
|
||||
if (ndet) {
|
||||
if (ok != 0) *ok = false;
|
||||
return *this;
|
||||
@@ -525,7 +529,8 @@ public:
|
||||
smat.swapRows(i, ++crow);
|
||||
for (uint j = i + 1; j < Rows; ++j) {
|
||||
mul = smat.m[i][j] / smat.m[i][i];
|
||||
for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i];
|
||||
for (uint k = i; k < Cols; ++k)
|
||||
smat.m[k][j] -= mul * smat.m[k][i];
|
||||
}
|
||||
if (i < Cols - 1) {
|
||||
if (piAbs<Type>(smat.m[i + 1][i + 1]) < Type(1E-200)) {
|
||||
@@ -540,7 +545,7 @@ public:
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \details Works only with square matrix, nonzero matrices and invertible matrix.
|
||||
//! \param ok is a parameter with which we can find out if the method worked correctly.
|
||||
//! \return inverted matrix.
|
||||
@@ -549,7 +554,7 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return обратная матрица.
|
||||
PIMathMatrixT<Rows, Cols, Type> &invert(bool *ok = 0) {
|
||||
PIMathMatrixT<Rows, Cols, Type> & invert(bool * ok = 0) {
|
||||
static_assert(Rows == Cols, "Works only with square matrix");
|
||||
PIMathMatrixT<Rows, Cols, Type> mtmp = PIMathMatrixT<Rows, Cols, Type>::identity(), smat(*this);
|
||||
bool ndet;
|
||||
@@ -557,7 +562,8 @@ public:
|
||||
Type mul, iddiv;
|
||||
for (uint i = 0; i < Cols; ++i) {
|
||||
ndet = true;
|
||||
for (uint j = 0; j < Rows; ++j) if (smat.m[i][j] != 0) ndet = false;
|
||||
for (uint j = 0; j < Rows; ++j)
|
||||
if (smat.m[i][j] != 0) ndet = false;
|
||||
if (ndet) {
|
||||
if (ok != 0) *ok = false;
|
||||
return *this;
|
||||
@@ -572,8 +578,10 @@ public:
|
||||
}
|
||||
for (uint j = i + 1; j < Rows; ++j) {
|
||||
mul = smat.m[i][j] / smat.m[i][i];
|
||||
for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i];
|
||||
for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i];
|
||||
for (uint k = i; k < Cols; ++k)
|
||||
smat.m[k][j] -= mul * smat.m[k][i];
|
||||
for (uint k = 0; k < Cols; ++k)
|
||||
mtmp.m[k][j] -= mul * mtmp.m[k][i];
|
||||
}
|
||||
if (i < Cols - 1) {
|
||||
if (piAbs<Type>(smat.m[i + 1][i + 1]) < Type(1E-200)) {
|
||||
@@ -582,14 +590,17 @@ public:
|
||||
}
|
||||
}
|
||||
iddiv = smat.m[i][i];
|
||||
for (uint j = i; j < Cols; ++j) smat.m[j][i] /= iddiv;
|
||||
for (uint j = 0; j < Cols; ++j) mtmp.m[j][i] /= iddiv;
|
||||
for (uint j = i; j < Cols; ++j)
|
||||
smat.m[j][i] /= iddiv;
|
||||
for (uint j = 0; j < Cols; ++j)
|
||||
mtmp.m[j][i] /= iddiv;
|
||||
}
|
||||
for (uint i = Cols - 1; i > 0; --i) {
|
||||
for (uint j = 0; j < i; ++j) {
|
||||
mul = smat.m[i][j];
|
||||
smat.m[i][j] -= mul;
|
||||
for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mtmp.m[k][i] * mul;
|
||||
for (uint k = 0; k < Cols; ++k)
|
||||
mtmp.m[k][j] -= mtmp.m[k][i] * mul;
|
||||
}
|
||||
}
|
||||
if (ok != 0) *ok = true;
|
||||
@@ -598,7 +609,7 @@ public:
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \details Works only with square matrix, nonzero matrices and invertible matrix.
|
||||
//! \param ok is a parameter with which we can find out if the method worked correctly.
|
||||
//! \return copy of inverted matrix.
|
||||
@@ -607,14 +618,14 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return копия обратной матрицы.
|
||||
PIMathMatrixT<Rows, Cols, Type> inverted(bool *ok = 0) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> inverted(bool * ok = 0) const {
|
||||
PIMathMatrixT<Rows, Cols, Type> tm(*this);
|
||||
tm.invert(ok);
|
||||
return tm;
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Matrix transposition operation.
|
||||
//! \brief Matrix transposition operation.
|
||||
//! \details Works only with square matrix.
|
||||
//! \return copy of transposed matrix
|
||||
//! \~russian
|
||||
@@ -641,9 +652,9 @@ public:
|
||||
Type s = std::sin(angle);
|
||||
PIMathMatrixT<2u, 2u> tm;
|
||||
tm[0][0] = tm[1][1] = c;
|
||||
tm[0][1] = -s;
|
||||
tm[1][0] = s;
|
||||
*this = *this * tm;
|
||||
tm[0][1] = -s;
|
||||
tm[1][0] = s;
|
||||
*this = *this * tm;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -655,16 +666,16 @@ public:
|
||||
//! \brief Операция поворота матрицы.
|
||||
//! \details Работает только с матрицами 2x2.
|
||||
//! \return копия повернутой матрицы.
|
||||
PIMathMatrixT<Rows, Cols, Type>& rotated(Type angle) {
|
||||
PIMathMatrixT<Rows, Cols, Type> & rotated(Type angle) {
|
||||
static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix");
|
||||
PIMathMatrixT<Cols, Rows, Type> outm;
|
||||
Type c = std::cos(angle);
|
||||
Type s = std::sin(angle);
|
||||
PIMathMatrixT<2u, 2u> tm;
|
||||
tm[0][0] = tm[1][1] = c;
|
||||
tm[0][1] = -s;
|
||||
tm[1][0] = s;
|
||||
outm = outm * tm;
|
||||
tm[0][1] = -s;
|
||||
tm[1][0] = s;
|
||||
outm = outm * tm;
|
||||
return outm;
|
||||
}
|
||||
|
||||
@@ -677,7 +688,7 @@ private:
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
template<uint Rows, uint Cols, typename Type>
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT<Rows, Cols, Type> & m) {
|
||||
inline std::ostream & operator<<(std::ostream & s, const PIMathMatrixT<Rows, Cols, Type> & m) {
|
||||
s << "{";
|
||||
for (uint r = 0; r < Rows; ++r) {
|
||||
for (uint c = 0; c < Cols; ++c) {
|
||||
@@ -702,7 +713,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT<Rows, Co
|
||||
//! \param m типа \a PIMathMatrixT.
|
||||
//! \return непечатанная в консоль \a PICout.
|
||||
template<uint Rows, uint Cols, typename Type>
|
||||
inline PICout operator<<(PICout s, const PIMathMatrixT<Rows, Cols, Type> &m) {
|
||||
inline PICout operator<<(PICout s, const PIMathMatrixT<Rows, Cols, Type> & m) {
|
||||
s << "{";
|
||||
for (uint r = 0; r < Rows; ++r) {
|
||||
for (uint c = 0; c < Cols; ++c) {
|
||||
@@ -716,7 +727,7 @@ inline PICout operator<<(PICout s, const PIMathMatrixT<Rows, Cols, Type> &m) {
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Multiplying matrices by each other.
|
||||
//! \brief Multiplying matrices by each other.
|
||||
//! \param fm first matrix multiplier.
|
||||
//! \param sm second matrix multiplier.
|
||||
//! \return matrix that is the result of multiplication.
|
||||
@@ -726,8 +737,7 @@ inline PICout operator<<(PICout s, const PIMathMatrixT<Rows, Cols, Type> &m) {
|
||||
//! \param sm второй множитель-матрица.
|
||||
//! \return матрица, являющаяся результатом умножения.
|
||||
template<uint CR, uint Rows0, uint Cols1, typename Type>
|
||||
inline PIMathMatrixT<Rows0, Cols1, Type> operator*(const PIMathMatrixT<Rows0, CR, Type> &fm,
|
||||
const PIMathMatrixT<CR, Cols1, Type> &sm) {
|
||||
inline PIMathMatrixT<Rows0, Cols1, Type> operator*(const PIMathMatrixT<Rows0, CR, Type> & fm, const PIMathMatrixT<CR, Cols1, Type> & sm) {
|
||||
PIMathMatrixT<Rows0, Cols1, Type> tm;
|
||||
Type t;
|
||||
for (uint j = 0; j < Rows0; ++j) {
|
||||
@@ -752,8 +762,7 @@ inline PIMathMatrixT<Rows0, Cols1, Type> operator*(const PIMathMatrixT<Rows0, CR
|
||||
//! \param sv второй множитель-вектор.
|
||||
//! \return вектор, являющийся результатом умножения.
|
||||
template<uint Cols, uint Rows, typename Type>
|
||||
inline PIMathVectorT<Rows, Type> operator*(const PIMathMatrixT<Rows, Cols, Type> &fm,
|
||||
const PIMathVectorT<Cols, Type> &sv) {
|
||||
inline PIMathVectorT<Rows, Type> operator*(const PIMathMatrixT<Rows, Cols, Type> & fm, const PIMathVectorT<Cols, Type> & sv) {
|
||||
PIMathVectorT<Rows, Type> tv;
|
||||
Type t;
|
||||
for (uint j = 0; j < Rows; ++j) {
|
||||
@@ -776,8 +785,7 @@ inline PIMathVectorT<Rows, Type> operator*(const PIMathMatrixT<Rows, Cols, Type>
|
||||
//! \param fm первый множитель-матрица.
|
||||
//! \return вектор, являющийся результатом умножения.
|
||||
template<uint Cols, uint Rows, typename Type>
|
||||
inline PIMathVectorT<Cols, Type> operator*(const PIMathVectorT<Rows, Type> &sv,
|
||||
const PIMathMatrixT<Rows, Cols, Type> &fm) {
|
||||
inline PIMathVectorT<Cols, Type> operator*(const PIMathVectorT<Rows, Type> & sv, const PIMathMatrixT<Rows, Cols, Type> & fm) {
|
||||
PIMathVectorT<Cols, Type> tv;
|
||||
Type t;
|
||||
for (uint j = 0; j < Cols; ++j) {
|
||||
@@ -800,7 +808,7 @@ inline PIMathVectorT<Cols, Type> operator*(const PIMathVectorT<Rows, Type> &sv,
|
||||
//! \param v вторая множитель-матрица.
|
||||
//! \return матрица, являющаяся результатом умножения.
|
||||
template<uint Cols, uint Rows, typename Type>
|
||||
inline PIMathMatrixT<Rows, Cols, Type> operator*(const Type &x, const PIMathMatrixT<Rows, Cols, Type> &v) {
|
||||
inline PIMathMatrixT<Rows, Cols, Type> operator*(const Type & x, const PIMathMatrixT<Rows, Cols, Type> & v) {
|
||||
return v * x;
|
||||
}
|
||||
|
||||
@@ -821,28 +829,28 @@ class PIMathMatrix;
|
||||
#undef PIMM_FOR_R
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Matrix
|
||||
|
||||
#define PIMM_FOR for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_; ++c)
|
||||
#define PIMM_FOR \
|
||||
for (uint r = 0; r < _V2D::rows_; ++r) \
|
||||
for (uint c = 0; c < _V2D::cols_; ++c)
|
||||
#define PIMM_FOR_A for (uint i = 0; i < _V2D::mat.size(); ++i)
|
||||
#define PIMM_FOR_C for (uint i = 0; i < _V2D::cols_; ++i)
|
||||
#define PIMM_FOR_R for (uint i = 0; i < _V2D::rows_; ++i)
|
||||
|
||||
//! \~english
|
||||
//! \brief A class for dynamic size and fixed type matrix.
|
||||
//! \tparam `Type` There are can be basic C++ language data and different classes where the arithmetic operators(=, +=, -=, *=, /=, ==, !=, +, -, *, /)
|
||||
//! of the C++ language are implemented.
|
||||
//! \tparam `Type` There are can be basic C++ language data and different classes where the arithmetic operators(=, +=, -=, *=, /=, ==, !=,
|
||||
//! +, -, *, /) of the C++ language are implemented.
|
||||
//! \~russian
|
||||
//! \brief Класс для работы с матрицами динамического размера и фиксированного типа.
|
||||
//! \tparam `Type` Здесь можеть быть базовый тип данных C++ или различные классы,
|
||||
//! где реализованы арифметические операторы(=, +=, -=, *=, /=, ==, !=, +, -, *, /) языка C++.
|
||||
//! где реализованы арифметические операторы(=, +=, -=, *=, /=, ==, !=, +, -, *, /) языка C++.
|
||||
template<typename Type>
|
||||
class PIP_EXPORT PIMathMatrix : public PIVector2D<Type> {
|
||||
class PIP_EXPORT PIMathMatrix: public PIVector2D<Type> {
|
||||
typedef PIVector2D<Type> _V2D;
|
||||
typedef PIMathMatrix<Type> _CMatrix;
|
||||
|
||||
public:
|
||||
//! \~english
|
||||
//! \brief Constructor of class \a PIMathMatrix, which creates a matrix.
|
||||
@@ -854,7 +862,7 @@ public:
|
||||
//! \param cols количество столбов матрицы типа \a uint.
|
||||
//! \param rows количество строк матрицы типа \a uint.
|
||||
//! \param f тип элементов матрицы.
|
||||
PIMathMatrix(const uint cols = 0, const uint rows = 0, const Type &f = Type()) { _V2D::resize(rows, cols, f); }
|
||||
PIMathMatrix(const uint cols = 0, const uint rows = 0, const Type & f = Type()) { _V2D::resize(rows, cols, f); }
|
||||
|
||||
//! \~english
|
||||
//! \brief Constructor of class \a PIMathMatrix, which creates a matrix
|
||||
@@ -866,9 +874,9 @@ public:
|
||||
//! \param cols количество столбов матрицы типа \a uint.
|
||||
//! \param rows количество строк матрицы типа \a uint.
|
||||
//! \param val тип \a PIVector<Type> элементов матрицы.
|
||||
PIMathMatrix(const uint cols, const uint rows, const PIVector<Type> &val) {
|
||||
PIMathMatrix(const uint cols, const uint rows, const PIVector<Type> & val) {
|
||||
_V2D::resize(rows, cols);
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
PIMM_FOR _V2D::element(r, c) = val[i++];
|
||||
}
|
||||
|
||||
@@ -878,7 +886,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Конструктор класса \a PIMathMatrix, который создает матрицу.
|
||||
//! \param val тип \a PIVector<Type>, который создает матрицу.
|
||||
PIMathMatrix(const PIVector<PIVector<Type> > &val) {
|
||||
PIMathMatrix(const PIVector<PIVector<Type>> & val) {
|
||||
if (!val.isEmpty()) {
|
||||
_V2D::resize(val.size(), val[0].size());
|
||||
for (uint r = 0; r < _V2D::rows_; ++r) {
|
||||
@@ -895,7 +903,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Конструктор класса \a PIMathMatrix, который создает матрицу.
|
||||
//! \param val тип \a PIVector2D<Type>, который создает матрицу.
|
||||
PIMathMatrix(const PIVector2D<Type> &val) {
|
||||
PIMathMatrix(const PIVector2D<Type> & val) {
|
||||
if (!val.isEmpty()) {
|
||||
_V2D::resize(val.rows(), val.cols());
|
||||
PIMM_FOR _V2D::element(r, c) = val.element(r, c);
|
||||
@@ -914,7 +922,9 @@ public:
|
||||
//! \return единичная матрица matrix(`cols`, `rows`)
|
||||
static PIMathMatrix<Type> identity(const uint cols, const uint rows) {
|
||||
PIMathMatrix<Type> tm(cols, rows);
|
||||
for (uint r = 0; r < rows; ++r) for (uint c = 0; c < cols; ++c) tm.element(r, c) = (c == r ? Type(1) : Type(0));
|
||||
for (uint r = 0; r < rows; ++r)
|
||||
for (uint c = 0; c < cols; ++c)
|
||||
tm.element(r, c) = (c == r ? Type(1) : Type(0));
|
||||
return tm;
|
||||
}
|
||||
|
||||
@@ -926,7 +936,7 @@ public:
|
||||
//! \brief Создает матрицу-строку, каждый элемент которой равен каждому элементу вектора
|
||||
//! \param val вектор типа \a PIMathVector
|
||||
//! \return матрица-строка, каждый элемент которой равен каждому элементу вектора
|
||||
static PIMathMatrix<Type> matrixRow(const PIMathVector<Type> &val) {return PIMathMatrix<Type>(val.size(), 1, val.toVector());}
|
||||
static PIMathMatrix<Type> matrixRow(const PIMathVector<Type> & val) { return PIMathMatrix<Type>(val.size(), 1, val.toVector()); }
|
||||
|
||||
//! \~english
|
||||
//! \brief Creates a column matrix of every element that is equal to every element of the vector
|
||||
@@ -936,23 +946,23 @@ public:
|
||||
//! \brief Создает матрицу-столбец, каждый элемент которой равен каждому элементу вектора
|
||||
//! \param val вектор типа \a PIMathVector
|
||||
//! \return матрица-столбец, каждый элемент которой равен каждому элементу вектора
|
||||
static PIMathMatrix<Type> matrixCol(const PIMathVector<Type> &val) {return PIMathMatrix<Type>(1, val.size(), val.toVector());}
|
||||
static PIMathMatrix<Type> matrixCol(const PIMathVector<Type> & val) { return PIMathMatrix<Type>(1, val.size(), val.toVector()); }
|
||||
|
||||
//! \~english
|
||||
//! \brief Set the selected column in matrix.
|
||||
//! \brief Set the selected column in matrix.
|
||||
//! \details If there are more elements of the vector than elements in the column of the matrix
|
||||
//! or index larger than the number of columns otherwise there will be "undefined behavior".
|
||||
//! \param index is the number of the selected column.
|
||||
//! \param v is a vector of the type \a PIMathVector<Type> that needs to fill the column.
|
||||
//! \return matrix type \a PIMathMatrix<Type>
|
||||
//! \~russian
|
||||
//! \brief Определить выбранный столбец матрицы.
|
||||
//! \details Если элементов в векторе больше, чем элементов в столбце матрицы
|
||||
//! \brief Определить выбранный столбец матрицы.
|
||||
//! \details Если элементов в векторе больше, чем элементов в столбце матрицы
|
||||
//! или индекс больше количества стобцов, то поведение не определено ("undefined behavior").
|
||||
//! \param index номер выбранного столбца.
|
||||
//! \param v вектор типа \a PIMathVector<Type>, которым нужно заполнить столбец.
|
||||
//! \return матрица типа \a PIMathMatrix<Type>.
|
||||
PIMathMatrix<Type> &setCol(uint index, const PIMathVector<Type> &v) {
|
||||
PIMathMatrix<Type> & setCol(uint index, const PIMathVector<Type> & v) {
|
||||
assert(_V2D::rows() == v.size());
|
||||
PIMM_FOR_R _V2D::element(i, index) = v[i];
|
||||
return *this;
|
||||
@@ -966,13 +976,13 @@ public:
|
||||
//! \param v is a vector of the type \a PIMathVector<Type> that needs to fill the row.
|
||||
//! \return matrix type \a PIMathMatrix<Type>.
|
||||
//! \~russian
|
||||
//! \brief Определить выбранную строку матрицы.
|
||||
//! \details Если элементов в векторе больше, чем элементов в строке матрицы
|
||||
//! \brief Определить выбранную строку матрицы.
|
||||
//! \details Если элементов в векторе больше, чем элементов в строке матрицы
|
||||
//! или индекс больше количества стобцов, то поведение не определено ("undefined behavior").
|
||||
//! \param index номер выбранной строки.
|
||||
//! \param v вектор типа \a PIMathVector<Type>, которым нужно заполнить строку.
|
||||
//! \return матрица типа \a PIMathMatrix<Type>.
|
||||
PIMathMatrix<Type> &setRow(uint index, const PIMathVector<Type> &v) {
|
||||
PIMathMatrix<Type> & setRow(uint index, const PIMathVector<Type> & v) {
|
||||
assert(_V2D::cols() == v.size());
|
||||
PIMM_FOR_C _V2D::element(index, i) = v[i];
|
||||
return *this;
|
||||
@@ -987,12 +997,12 @@ public:
|
||||
//! \return matrix type \a PIMathMatrix<Type>.
|
||||
//! \~russian
|
||||
//! \brief Метод меняющий местами выбранные строки в матрице.
|
||||
//! \details Вы не можете использовать индекс, который больше количества столбцов,
|
||||
//! \details Вы не можете использовать индекс, который больше количества столбцов,
|
||||
//! иначе будет неопределенное повередение ("undefined behavior").
|
||||
//! \param r0 номер первой выбранного стобца.
|
||||
//! \param r1 номер второй выбранного столбца.
|
||||
//! \return матрица типа \a PIMathMatrix<Type>.
|
||||
PIMathMatrix<Type> &swapCols(uint r0, uint r1) {
|
||||
PIMathMatrix<Type> & swapCols(uint r0, uint r1) {
|
||||
PIMM_FOR_C piSwap<Type>(_V2D::element(i, r0), _V2D::element(i, r1));
|
||||
return *this;
|
||||
}
|
||||
@@ -1006,12 +1016,12 @@ public:
|
||||
//! \return matrix type \a PIMathMatrix<Type>.
|
||||
//! \~russian
|
||||
//! \brief Метод меняющий местами выбранные строки в матрице.
|
||||
//! \details Вы не можете использовать индекс, который больше количества строк,
|
||||
//! \details Вы не можете использовать индекс, который больше количества строк,
|
||||
//! иначе будет неопределенное повередение ("undefined behavior").
|
||||
//! \param с0 номер первой выбранной строки.
|
||||
//! \param с1 номер второй выбранной строки.
|
||||
//! \return матрица типа \a PIMathMatrix<Type>.
|
||||
PIMathMatrix<Type> &swapRows(uint c0, uint c1) {
|
||||
PIMathMatrix<Type> & swapRows(uint c0, uint c1) {
|
||||
PIMM_FOR_R piSwap<Type>(_V2D::element(c0, i), _V2D::element(c1, i));
|
||||
return *this;
|
||||
}
|
||||
@@ -1024,7 +1034,7 @@ public:
|
||||
//! \brief Метод заполняющий матрицу выбранным значением.
|
||||
//! \param v параметр выбранного типа и значения, которым будет заполнена матрица.
|
||||
//! \return заполненная матрица типа \a PIMathMatrix<Type>.
|
||||
PIMathMatrix<Type> &fill(const Type &v) {
|
||||
PIMathMatrix<Type> & fill(const Type & v) {
|
||||
PIMM_FOR_A _V2D::mat[i] = v;
|
||||
return *this;
|
||||
}
|
||||
@@ -1044,7 +1054,7 @@ public:
|
||||
//! \brief Метод, проверяющий содержит ли главная диагональ единицы и все остальные поля нули.
|
||||
//! \return true если матрица единичная, иначе false.
|
||||
bool isIdentity() const {
|
||||
PIMM_FOR if ((c == r) ? _V2D::element(r, c) != Type(1) : _V2D::element(r, c) != Type(0))return false;
|
||||
PIMM_FOR if ((c == r) ? _V2D::element(r, c) != Type(1) : _V2D::element(r, c) != Type(0)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1073,7 +1083,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Сложение с присваиванием с матрицей `sm`.
|
||||
//! \param sm матрица для сложения с присваиванием.
|
||||
void operator+=(const PIMathMatrix<Type> &sm) {
|
||||
void operator+=(const PIMathMatrix<Type> & sm) {
|
||||
assert(_V2D::rows() == sm.rows());
|
||||
assert(_V2D::cols() == sm.cols());
|
||||
PIMM_FOR_A _V2D::mat[i] += sm.mat[i];
|
||||
@@ -1085,7 +1095,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Вычитание с присваиванием с матрицей `sm`.
|
||||
//! \param sm матрица для вычитания с присваиванием.
|
||||
void operator-=(const PIMathMatrix<Type> &sm) {
|
||||
void operator-=(const PIMathMatrix<Type> & sm) {
|
||||
assert(_V2D::rows() == sm.rows());
|
||||
assert(_V2D::cols() == sm.cols());
|
||||
PIMM_FOR_A _V2D::mat[i] -= sm.mat[i];
|
||||
@@ -1097,9 +1107,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Умножение с присваиванием с матрицей `v`.
|
||||
//! \param sm матрица для умножения с присваиванием.
|
||||
void operator*=(const Type &v) {
|
||||
PIMM_FOR_A _V2D::mat[i] *= v;
|
||||
}
|
||||
void operator*=(const Type & v) { PIMM_FOR_A _V2D::mat[i] *= v; }
|
||||
|
||||
//! \~english
|
||||
//! \brief Division assignment with value `v`.
|
||||
@@ -1107,7 +1115,7 @@ public:
|
||||
//! \~russian
|
||||
//! \brief Деление с присваиванием с матрицей `v`.
|
||||
//! \param sm матрица для деления с присваиванием.
|
||||
void operator/=(const Type &v) {
|
||||
void operator/=(const Type & v) {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
PIMM_FOR_A _V2D::mat[i] /= v;
|
||||
}
|
||||
@@ -1132,7 +1140,7 @@ public:
|
||||
//! \brief Матричное сложение.
|
||||
//! \param sm матричное слагаемое.
|
||||
//! \return результат матричного сложения.
|
||||
PIMathMatrix<Type> operator+(const PIMathMatrix<Type> &sm) const {
|
||||
PIMathMatrix<Type> operator+(const PIMathMatrix<Type> & sm) const {
|
||||
PIMathMatrix<Type> tm(*this);
|
||||
assert(tm.rows() == sm.rows());
|
||||
assert(tm.cols() == sm.cols());
|
||||
@@ -1148,7 +1156,7 @@ public:
|
||||
//! \brief Матричная разность.
|
||||
//! \param sm матричное вычитаемое.
|
||||
//! \return результат матричной разности.
|
||||
PIMathMatrix<Type> operator-(const PIMathMatrix<Type> &sm) const {
|
||||
PIMathMatrix<Type> operator-(const PIMathMatrix<Type> & sm) const {
|
||||
PIMathMatrix<Type> tm(*this);
|
||||
assert(tm.rows() == sm.rows());
|
||||
assert(tm.cols() == sm.cols());
|
||||
@@ -1164,7 +1172,7 @@ public:
|
||||
//! \brief Матричное произведение.
|
||||
//! \param v множитель.
|
||||
//! \return результат произведения.
|
||||
PIMathMatrix<Type> operator*(const Type &v) const {
|
||||
PIMathMatrix<Type> operator*(const Type & v) const {
|
||||
PIMathMatrix<Type> tm(*this);
|
||||
PIMM_FOR_A tm.mat[i] *= v;
|
||||
return tm;
|
||||
@@ -1178,7 +1186,7 @@ public:
|
||||
//! \brief Матричное деление.
|
||||
//! \param v делитель.
|
||||
//! \return результат деления.
|
||||
PIMathMatrix<Type> operator/(const Type &v) const {
|
||||
PIMathMatrix<Type> operator/(const Type & v) const {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
PIMathMatrix<Type> tm(*this);
|
||||
PIMM_FOR_A tm.mat[i] /= v;
|
||||
@@ -1186,7 +1194,7 @@ public:
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Calculate Determinant of the matrix.
|
||||
//! \brief Calculate Determinant of the matrix.
|
||||
//! \details Works only with square matrix, nonzero matrices and invertible matrix.
|
||||
//! \param ok is a parameter with which we can find out if the method worked correctly.
|
||||
//! \return matrix determinant.
|
||||
@@ -1195,7 +1203,7 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return опеределитель матрицы.
|
||||
Type determinant(bool *ok = 0) const {
|
||||
Type determinant(bool * ok = 0) const {
|
||||
PIMathMatrix<Type> m(*this);
|
||||
bool k;
|
||||
m.toUpperTriangular(&k);
|
||||
@@ -1205,8 +1213,7 @@ public:
|
||||
ret = Type(1);
|
||||
for (uint c = 0; c < _V2D::cols_; ++c)
|
||||
for (uint r = 0; r < _V2D::rows_; ++r)
|
||||
if (r == c)
|
||||
ret *= m.element(r, c);
|
||||
if (r == c) ret *= m.element(r, c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1237,7 +1244,7 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return копия преобразованной верхнетреугольной матрицы.
|
||||
PIMathMatrix<Type> &toUpperTriangular(bool *ok = 0) {
|
||||
PIMathMatrix<Type> & toUpperTriangular(bool * ok = 0) {
|
||||
assert(isSquare());
|
||||
PIMathMatrix<Type> smat(*this);
|
||||
bool ndet;
|
||||
@@ -1245,7 +1252,8 @@ public:
|
||||
Type mul;
|
||||
for (uint i = 0; i < _V2D::cols_; ++i) {
|
||||
ndet = true;
|
||||
for (uint j = 0; j < _V2D::rows_; ++j) if (smat.element(i, j) != 0) ndet = false;
|
||||
for (uint j = 0; j < _V2D::rows_; ++j)
|
||||
if (smat.element(i, j) != 0) ndet = false;
|
||||
if (ndet) {
|
||||
if (ok != 0) *ok = false;
|
||||
return *this;
|
||||
@@ -1257,7 +1265,8 @@ public:
|
||||
smat.swapRows(i, ++crow);
|
||||
for (uint j = i + 1; j < _V2D::rows_; ++j) {
|
||||
mul = smat.element(i, j) / smat.element(i, i);
|
||||
for (uint k = i; k < _V2D::cols_; ++k) smat.element(k, j) -= mul * smat.element(k, i);
|
||||
for (uint k = i; k < _V2D::cols_; ++k)
|
||||
smat.element(k, j) -= mul * smat.element(k, i);
|
||||
}
|
||||
if (i < _V2D::cols_ - 1) {
|
||||
if (PIMathFloatNullCompare(smat.element(i + 1, i + 1))) {
|
||||
@@ -1272,7 +1281,7 @@ public:
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \details Works only with square matrix, nonzero matrices and invertible matrix.
|
||||
//! \param ok is a parameter with which we can find out if the method worked correctly.
|
||||
//! \return inverted matrix.
|
||||
@@ -1281,7 +1290,7 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return обратная матрица.
|
||||
PIMathMatrix<Type> &invert(bool *ok = 0, PIMathVector<Type> *sv = 0) {
|
||||
PIMathMatrix<Type> & invert(bool * ok = 0, PIMathVector<Type> * sv = 0) {
|
||||
assert(isSquare());
|
||||
PIMathMatrix<Type> mtmp = PIMathMatrix<Type>::identity(_V2D::cols_, _V2D::rows_), smat(*this);
|
||||
bool ndet;
|
||||
@@ -1289,7 +1298,8 @@ public:
|
||||
Type mul, iddiv;
|
||||
for (uint i = 0; i < _V2D::cols_; ++i) {
|
||||
ndet = true;
|
||||
for (uint j = 0; j < _V2D::rows_; ++j) if (smat.element(i, j) != Type(0)) ndet = false;
|
||||
for (uint j = 0; j < _V2D::rows_; ++j)
|
||||
if (smat.element(i, j) != Type(0)) ndet = false;
|
||||
if (ndet) {
|
||||
if (ok != 0) *ok = false;
|
||||
return *this;
|
||||
@@ -1305,8 +1315,10 @@ public:
|
||||
}
|
||||
for (uint j = i + 1; j < _V2D::rows_; ++j) {
|
||||
mul = smat.element(i, j) / smat.element(i, i);
|
||||
for (uint k = i; k < _V2D::cols_; ++k) smat.element(k, j) -= mul * smat.element(k, i);
|
||||
for (uint k = 0; k < _V2D::cols_; ++k) mtmp.element(k, j) -= mul * mtmp.element(k, i);
|
||||
for (uint k = i; k < _V2D::cols_; ++k)
|
||||
smat.element(k, j) -= mul * smat.element(k, i);
|
||||
for (uint k = 0; k < _V2D::cols_; ++k)
|
||||
mtmp.element(k, j) -= mul * mtmp.element(k, i);
|
||||
if (sv != 0) (*sv)[j] -= mul * (*sv)[i];
|
||||
}
|
||||
if (i < _V2D::cols_ - 1) {
|
||||
@@ -1316,15 +1328,18 @@ public:
|
||||
}
|
||||
}
|
||||
iddiv = smat.element(i, i);
|
||||
for (uint j = i; j < _V2D::cols_; ++j) smat.element(j, i) /= iddiv;
|
||||
for (uint j = 0; j < _V2D::cols_; ++j) mtmp.element(j, i) /= iddiv;
|
||||
for (uint j = i; j < _V2D::cols_; ++j)
|
||||
smat.element(j, i) /= iddiv;
|
||||
for (uint j = 0; j < _V2D::cols_; ++j)
|
||||
mtmp.element(j, i) /= iddiv;
|
||||
if (sv != 0) (*sv)[i] /= iddiv;
|
||||
}
|
||||
for (uint i = _V2D::cols_ - 1; i > 0; --i) {
|
||||
for (uint j = 0; j < i; ++j) {
|
||||
mul = smat.element(i, j);
|
||||
smat.element(i, j) -= mul;
|
||||
for (uint k = 0; k < _V2D::cols_; ++k) mtmp.element(k, j) -= mul * mtmp.element(k, i);
|
||||
for (uint k = 0; k < _V2D::cols_; ++k)
|
||||
mtmp.element(k, j) -= mul * mtmp.element(k, i);
|
||||
if (sv != 0) (*sv)[j] -= mul * (*sv)[i];
|
||||
}
|
||||
}
|
||||
@@ -1334,7 +1349,7 @@ public:
|
||||
}
|
||||
|
||||
//! \~english
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \brief Matrix inversion operation.
|
||||
//! \details Works only with square matrix, nonzero matrices and invertible matrix.
|
||||
//! \param ok is a parameter with which we can find out if the method worked correctly.
|
||||
//! \return copy of inverted matrix.
|
||||
@@ -1343,7 +1358,7 @@ public:
|
||||
//! \details Работает только с квадратными, ненулевыми и обратимыми матрицами.
|
||||
//! \param ok это параметр, с помощью которого мы можем узнать, правильно ли сработал метод.
|
||||
//! \return копия обратной матрицы.
|
||||
PIMathMatrix<Type> inverted(bool *ok = 0) const {
|
||||
PIMathMatrix<Type> inverted(bool * ok = 0) const {
|
||||
PIMathMatrix<Type> tm(*this);
|
||||
tm.invert(ok);
|
||||
return tm;
|
||||
@@ -1367,7 +1382,18 @@ public:
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
template<typename Type>
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrix<Type> & m) {s << "{"; for (uint r = 0; r < m.rows(); ++r) { for (uint c = 0; c < m.cols(); ++c) { s << m.element(r, c); if (c < m.cols() - 1 || r < m.rows() - 1) s << ", ";} if (r < m.rows() - 1) s << std::endl << " ";} s << "}"; return s;}
|
||||
inline std::ostream & operator<<(std::ostream & s, const PIMathMatrix<Type> & m) {
|
||||
s << "{";
|
||||
for (uint r = 0; r < m.rows(); ++r) {
|
||||
for (uint c = 0; c < m.cols(); ++c) {
|
||||
s << m.element(r, c);
|
||||
if (c < m.cols() - 1 || r < m.rows() - 1) s << ", ";
|
||||
}
|
||||
if (r < m.rows() - 1) s << std::endl << " ";
|
||||
}
|
||||
s << "}";
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! \~english
|
||||
@@ -1381,7 +1407,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIMathMatrix<Type> & m
|
||||
//! \param m типа \a PIMathMatrixT.
|
||||
//! \return непечатанная в консоль \a PICout.
|
||||
template<typename Type>
|
||||
inline PICout operator<<(PICout s, const PIMathMatrix<Type> &m) {
|
||||
inline PICout operator<<(PICout s, const PIMathMatrix<Type> & m) {
|
||||
s << "Matrix{";
|
||||
for (uint r = 0; r < m.rows(); ++r) {
|
||||
for (uint c = 0; c < m.cols(); ++c) {
|
||||
@@ -1402,9 +1428,9 @@ inline PICout operator<<(PICout s, const PIMathMatrix<Type> &m) {
|
||||
//! \brief Inline-оператор для сериализации матрицы в \a PIBinaryStream.
|
||||
//! \param s типа \a PIBinaryStream.
|
||||
//! \param v типа \a PIMathMatrix.
|
||||
template <typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMathMatrix<T> & v) {
|
||||
s << (const PIVector2D<T> &) v;
|
||||
template<typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMathMatrix<T> & v) {
|
||||
s << (const PIVector2D<T> &)v;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -1416,15 +1442,15 @@ inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMathMatrix
|
||||
//! \brief Inline-оператор для сериализации матрицы в \a PIByteArray.
|
||||
//! \param s типа \a PIBinaryStream.
|
||||
//! \param v типа \a PIMathMatrix.
|
||||
template <typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMathMatrix<T> & v) {
|
||||
s >> (PIVector2D<T> &) v;
|
||||
template<typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMathMatrix<T> & v) {
|
||||
s >> (PIVector2D<T> &)v;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
//! \~english
|
||||
//! \brief Multiplying matrices by each other.
|
||||
//! \brief Multiplying matrices by each other.
|
||||
//! \details If you enter an index out of the border of the matrix there will be "undefined behavior".
|
||||
//! \param fm first matrix multiplier.
|
||||
//! \param sm second matrix multiplier.
|
||||
@@ -1436,8 +1462,7 @@ inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMathMatrix<T> &
|
||||
//! \param sm вторая множитель-матрица.
|
||||
//! \return матрица, являющаяся результатом умножения.
|
||||
template<typename Type>
|
||||
inline PIMathMatrix<Type> operator*(const PIMathMatrix<Type> &fm,
|
||||
const PIMathMatrix<Type> &sm) {
|
||||
inline PIMathMatrix<Type> operator*(const PIMathMatrix<Type> & fm, const PIMathMatrix<Type> & sm) {
|
||||
assert(fm.cols() == sm.rows());
|
||||
PIMathMatrix<Type> tm(sm.cols(), fm.rows());
|
||||
Type t;
|
||||
@@ -1465,8 +1490,7 @@ inline PIMathMatrix<Type> operator*(const PIMathMatrix<Type> &fm,
|
||||
//! \param sv второй множитель-вектор.
|
||||
//! \return вектор, являющийся результатом умножения.
|
||||
template<typename Type>
|
||||
inline PIMathVector<Type> operator*(const PIMathMatrix<Type> &fm,
|
||||
const PIMathVector<Type> &sv) {
|
||||
inline PIMathVector<Type> operator*(const PIMathMatrix<Type> & fm, const PIMathVector<Type> & sv) {
|
||||
assert(fm.cols() == sv.size());
|
||||
PIMathVector<Type> tv(fm.rows());
|
||||
Type t;
|
||||
@@ -1492,8 +1516,7 @@ inline PIMathVector<Type> operator*(const PIMathMatrix<Type> &fm,
|
||||
//! \param fm первый множитель-матрица.
|
||||
//! \return вектор, являющийся результатом умножения.
|
||||
template<typename Type>
|
||||
inline PIMathVector<Type> operator*(const PIMathVector<Type> &sv,
|
||||
const PIMathMatrix<Type> &fm) {
|
||||
inline PIMathVector<Type> operator*(const PIMathVector<Type> & sv, const PIMathMatrix<Type> & fm) {
|
||||
PIMathVector<Type> tv(fm.cols());
|
||||
assert(fm.rows() == sv.size());
|
||||
Type t;
|
||||
@@ -1517,7 +1540,7 @@ inline PIMathVector<Type> operator*(const PIMathVector<Type> &sv,
|
||||
//! \param v второй множитель-матрица.
|
||||
//! \return матрица, являющаяся результатом умножения.
|
||||
template<typename Type>
|
||||
inline PIMathMatrix<Type> operator*(const Type &x, const PIMathMatrix<Type> &v) {
|
||||
inline PIMathMatrix<Type> operator*(const Type & x, const PIMathMatrix<Type> & v) {
|
||||
return v * x;
|
||||
}
|
||||
|
||||
@@ -1533,8 +1556,8 @@ typedef PIMathMatrix<double> PIMathMatrixd;
|
||||
//! \param m сопряженная транспонированная матрица.
|
||||
//! \return результат преобразования.
|
||||
template<typename T>
|
||||
PIMathMatrix<complex<T> > hermitian(const PIMathMatrix<complex<T> > &m) {
|
||||
PIMathMatrix<complex<T> > ret(m);
|
||||
PIMathMatrix<complex<T>> hermitian(const PIMathMatrix<complex<T>> & m) {
|
||||
PIMathMatrix<complex<T>> ret(m);
|
||||
for (uint r = 0; r < ret.rows(); ++r)
|
||||
for (uint c = 0; c < ret.cols(); ++c)
|
||||
ret.element(r, c).imag(-(ret.element(r, c).imag()));
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Module includes
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Module includes
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
//! \defgroup Math Math
|
||||
//! \~\brief
|
||||
@@ -51,11 +51,11 @@
|
||||
#ifndef PIMATHMODULE_H
|
||||
#define PIMATHMODULE_H
|
||||
|
||||
#include "pimathsolver.h"
|
||||
#include "pistatistic.h"
|
||||
#include "picrc.h"
|
||||
#include "pievaluator.h"
|
||||
#include "pifft.h"
|
||||
#include "picrc.h"
|
||||
#include "pimathsolver.h"
|
||||
#include "piquaternion.h"
|
||||
#include "pistatistic.h"
|
||||
|
||||
#endif // PIMATHMODULE_H
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathSolver
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathSolver
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pimathsolver.h"
|
||||
|
||||
const char PIMathSolver::methods_desc[] = "b{Methods:}\
|
||||
const char PIMathSolver::methods_desc[] = "b{Methods:}\
|
||||
\n -1 - Global settings\
|
||||
\n 01 - Eyler 1\
|
||||
\n 02 - Eyler 2\
|
||||
@@ -43,7 +43,8 @@ void PIMathSolver::solve(double u, double h) {
|
||||
case RungeKutta_4: solveRK4(u, h); break;
|
||||
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
||||
case AdamsBashfortMoulton_3: solveABM3(u, h); break;
|
||||
case AdamsBashfortMoulton_4: default: solveABM4(u, h); break;
|
||||
case AdamsBashfortMoulton_4:
|
||||
default: solveABM4(u, h); break;
|
||||
case PolynomialApproximation_2: solvePA2(u, h); break;
|
||||
case PolynomialApproximation_3: solvePA3(u, h); break;
|
||||
case PolynomialApproximation_4: solvePA4(u, h); break;
|
||||
@@ -55,7 +56,8 @@ void PIMathSolver::solve(double u, double h) {
|
||||
case RungeKutta_4: solveRK4(u, h); break;
|
||||
case AdamsBashfortMoulton_2: solveABM2(u, h); break;
|
||||
case AdamsBashfortMoulton_3: solveABM3(u, h); break;
|
||||
case AdamsBashfortMoulton_4: default: solveABM4(u, h); break;
|
||||
case AdamsBashfortMoulton_4:
|
||||
default: solveABM4(u, h); break;
|
||||
case PolynomialApproximation_2: solvePA2(u, h); break;
|
||||
case PolynomialApproximation_3: solvePA3(u, h); break;
|
||||
case PolynomialApproximation_4: solvePA4(u, h); break;
|
||||
@@ -67,7 +69,7 @@ void PIMathSolver::solve(double u, double h) {
|
||||
|
||||
void PIMathSolver::fromTF(const TransferFunction & TF) {
|
||||
if (TF.vector_An.size() >= TF.vector_Bm.size())
|
||||
size = TF.vector_An.size()-1;
|
||||
size = TF.vector_An.size() - 1;
|
||||
else {
|
||||
piCout << "PIMathSolver error: {A} should be greater than {B}";
|
||||
return;
|
||||
@@ -77,19 +79,29 @@ void PIMathSolver::fromTF(const TransferFunction & TF) {
|
||||
step = 0;
|
||||
times.fill(0.);
|
||||
A.resize(size, size);
|
||||
d.resize(size + 1); d.fill(0.);
|
||||
a1.resize(size + 1); a1.fill(0.);
|
||||
b1.resize(size + 1); b1.fill(0.);
|
||||
X.resize(size); X.fill(0.);
|
||||
d.resize(size + 1);
|
||||
d.fill(0.);
|
||||
a1.resize(size + 1);
|
||||
a1.fill(0.);
|
||||
b1.resize(size + 1);
|
||||
b1.fill(0.);
|
||||
X.resize(size);
|
||||
X.fill(0.);
|
||||
F.resize(5);
|
||||
for (uint i = 0; i < 5; ++i)
|
||||
F[i].resize(size), F[i].fill(0.);
|
||||
k1.resize(size); k1.fill(0.);
|
||||
k2.resize(size); k2.fill(0.);
|
||||
k3.resize(size); k3.fill(0.);
|
||||
k4.resize(size); k4.fill(0.);
|
||||
xx.resize(size); xx.fill(0.);
|
||||
XX.resize(size); XX.fill(0.);
|
||||
k1.resize(size);
|
||||
k1.fill(0.);
|
||||
k2.resize(size);
|
||||
k2.fill(0.);
|
||||
k3.resize(size);
|
||||
k3.fill(0.);
|
||||
k4.resize(size);
|
||||
k4.fill(0.);
|
||||
xx.resize(size);
|
||||
xx.fill(0.);
|
||||
XX.resize(size);
|
||||
XX.fill(0.);
|
||||
for (uint i = 0; i < size + 1; ++i)
|
||||
a1[size - i] = TF.vector_An[i];
|
||||
for (uint i = 0; i < TF.vector_Bm.size(); ++i)
|
||||
@@ -108,7 +120,7 @@ void PIMathSolver::fromTF(const TransferFunction & TF) {
|
||||
|
||||
for (uint i = 0; i < size - 1; ++i)
|
||||
for (uint j = 0; j < size; ++j)
|
||||
A[j][i] = (j == i + 1);
|
||||
A[j][i] = (j == i + 1);
|
||||
for (uint i = 0; i < size; ++i)
|
||||
A[i][size - 1] = -a1[size - i];
|
||||
for (uint i = 0; i < size; ++i)
|
||||
@@ -132,11 +144,17 @@ void PIMathSolver::solveEyler2(double u, double h) {
|
||||
|
||||
void PIMathSolver::solveRK4(double u, double h) {
|
||||
td = X[0] - F[0][0];
|
||||
k1 = A * X + d * u; xx = k1 * h / 2.; XX = X + xx;
|
||||
k2 = A * (XX + k1 * h / 2.) + d * (u + td/3.); xx = k2 * h / 2.; XX += xx;
|
||||
k3 = A * (XX + k2 * h / 2.) + d * (u + td*2./3.); xx = k3 * h; XX += xx;
|
||||
k1 = A * X + d * u;
|
||||
xx = k1 * h / 2.;
|
||||
XX = X + xx;
|
||||
k2 = A * (XX + k1 * h / 2.) + d * (u + td / 3.);
|
||||
xx = k2 * h / 2.;
|
||||
XX += xx;
|
||||
k3 = A * (XX + k2 * h / 2.) + d * (u + td * 2. / 3.);
|
||||
xx = k3 * h;
|
||||
XX += xx;
|
||||
k4 = A * (XX + k3 * h) + d * (u + td);
|
||||
//cout << k1 << k2 << k3 << k4 << endl;
|
||||
// cout << k1 << k2 << k3 << k4 << endl;
|
||||
X += (k1 + k2 * 2. + k3 * 2. + k4) * h / 6.;
|
||||
F[0] = X;
|
||||
}
|
||||
@@ -144,7 +162,7 @@ void PIMathSolver::solveRK4(double u, double h) {
|
||||
|
||||
void PIMathSolver::solveABM2(double u, double h) {
|
||||
F[0] = A * X + d * u;
|
||||
XX = X + (F[0] * 3. - F[1]) * (h / 2.);
|
||||
XX = X + (F[0] * 3. - F[1]) * (h / 2.);
|
||||
F[1] = A * XX + d * u;
|
||||
X += (F[1] + F[0]) * (h / 2.);
|
||||
moveF();
|
||||
@@ -153,7 +171,7 @@ void PIMathSolver::solveABM2(double u, double h) {
|
||||
|
||||
void PIMathSolver::solveABM3(double u, double h) {
|
||||
F[0] = A * X + d * u;
|
||||
XX = X + (F[0] * 23. - F[1] * 16. + F[2] * 5.) * (h / 12.);
|
||||
XX = X + (F[0] * 23. - F[1] * 16. + F[2] * 5.) * (h / 12.);
|
||||
F[2] = A * XX + d * u;
|
||||
X += (F[2] * 5. + F[0] * 8. - F[1]) * (h / 12.);
|
||||
moveF();
|
||||
@@ -162,7 +180,7 @@ void PIMathSolver::solveABM3(double u, double h) {
|
||||
|
||||
void PIMathSolver::solveABM4(double u, double h) {
|
||||
F[0] = A * X + d * u;
|
||||
XX = X + (F[0] * 55. - F[1] * 59. + F[2] * 37. - F[3] * 9.) * (h / 24.);
|
||||
XX = X + (F[0] * 55. - F[1] * 59. + F[2] * 37. - F[3] * 9.) * (h / 24.);
|
||||
F[3] = A * XX + d * u;
|
||||
X += (F[3] * 9. + F[0] * 19. - F[1] * 5. + F[2]) * (h / 24.);
|
||||
moveF();
|
||||
@@ -187,9 +205,9 @@ void PIMathSolver::solvePA(double u, double h, uint deg) {
|
||||
for (uint i = 0; i < deg; ++i)
|
||||
Y[i] = F[i][k];
|
||||
/// find polynom
|
||||
//if (step == 1) cout << M << endl << Y << endl;
|
||||
// if (step == 1) cout << M << endl << Y << endl;
|
||||
M.invert(&ok, &Y);
|
||||
//if (step == 1) cout << Y << endl;
|
||||
// if (step == 1) cout << Y << endl;
|
||||
if (!ok) {
|
||||
solveEyler2(u, h);
|
||||
break;
|
||||
@@ -197,7 +215,7 @@ void PIMathSolver::solvePA(double u, double h, uint deg) {
|
||||
// calc last piece
|
||||
x0 = 0.;
|
||||
td = 1.;
|
||||
t = times[0];
|
||||
t = times[0];
|
||||
for (uint i = 0; i < deg; ++i) {
|
||||
x0 += Y[i] * td / (i + 1.);
|
||||
td *= t;
|
||||
@@ -206,7 +224,7 @@ void PIMathSolver::solvePA(double u, double h, uint deg) {
|
||||
|
||||
x1 = 0.;
|
||||
td = 1.;
|
||||
t = times[1];
|
||||
t = times[1];
|
||||
for (uint i = 0; i < deg; ++i) {
|
||||
x1 += Y[i] * td / (i + 1.);
|
||||
td *= t;
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/*! \file pimathsolver.h
|
||||
* \brief PIMathSolver
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathSolver
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathSolver
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIMATHSOLVER_H
|
||||
@@ -31,29 +31,35 @@ struct PIP_EXPORT TransferFunction {
|
||||
PIVector<double> vector_Bm, vector_An;
|
||||
};
|
||||
|
||||
class PIP_EXPORT PIMathSolver
|
||||
{
|
||||
class PIP_EXPORT PIMathSolver {
|
||||
public:
|
||||
enum Method {Global = -1,
|
||||
Eyler_1 = 01,
|
||||
Eyler_2 = 02,
|
||||
EylerKoshi = 03,
|
||||
RungeKutta_4 = 14,
|
||||
AdamsBashfortMoulton_2 = 22,
|
||||
AdamsBashfortMoulton_3 = 23,
|
||||
AdamsBashfortMoulton_4 = 24,
|
||||
PolynomialApproximation_2 = 32,
|
||||
PolynomialApproximation_3 = 33,
|
||||
PolynomialApproximation_4 = 34,
|
||||
PolynomialApproximation_5 = 35
|
||||
};
|
||||
enum Method {
|
||||
Global = -1,
|
||||
Eyler_1 = 01,
|
||||
Eyler_2 = 02,
|
||||
EylerKoshi = 03,
|
||||
RungeKutta_4 = 14,
|
||||
AdamsBashfortMoulton_2 = 22,
|
||||
AdamsBashfortMoulton_3 = 23,
|
||||
AdamsBashfortMoulton_4 = 24,
|
||||
PolynomialApproximation_2 = 32,
|
||||
PolynomialApproximation_3 = 33,
|
||||
PolynomialApproximation_4 = 34,
|
||||
PolynomialApproximation_5 = 35
|
||||
};
|
||||
|
||||
PIMathSolver() {times.resize(4); step = 0;}
|
||||
PIMathSolver() {
|
||||
times.resize(4);
|
||||
step = 0;
|
||||
}
|
||||
|
||||
void solve(double u, double h);
|
||||
void fromTF(const TransferFunction & TF);
|
||||
void setMethod(Method m) {method = m;}
|
||||
void setTime(double time) {times.pop_back(); times.push_front(time);}
|
||||
void setMethod(Method m) { method = m; }
|
||||
void setTime(double time) {
|
||||
times.pop_back();
|
||||
times.push_front(time);
|
||||
}
|
||||
|
||||
void solveEyler1(double u, double h);
|
||||
void solveEyler2(double u, double h);
|
||||
@@ -62,17 +68,40 @@ public:
|
||||
void solveABM3(double u, double h);
|
||||
void solveABM4(double u, double h);
|
||||
void solvePA(double u, double h, uint deg);
|
||||
void solvePA2(double u, double h) {if (step > 0) solvePA(u, h, 2); else solveEyler1(u, h);}
|
||||
void solvePA3(double u, double h) {if (step > 1) solvePA(u, h, 3); else solvePA2(u, h);}
|
||||
void solvePA4(double u, double h) {if (step > 2) solvePA(u, h, 4); else solvePA3(u, h);}
|
||||
void solvePA5(double u, double h) {if (step > 3) solvePA(u, h, 5); else solvePA4(u, h);}
|
||||
void solvePA2(double u, double h) {
|
||||
if (step > 0)
|
||||
solvePA(u, h, 2);
|
||||
else
|
||||
solveEyler1(u, h);
|
||||
}
|
||||
void solvePA3(double u, double h) {
|
||||
if (step > 1)
|
||||
solvePA(u, h, 3);
|
||||
else
|
||||
solvePA2(u, h);
|
||||
}
|
||||
void solvePA4(double u, double h) {
|
||||
if (step > 2)
|
||||
solvePA(u, h, 4);
|
||||
else
|
||||
solvePA3(u, h);
|
||||
}
|
||||
void solvePA5(double u, double h) {
|
||||
if (step > 3)
|
||||
solvePA(u, h, 5);
|
||||
else
|
||||
solvePA4(u, h);
|
||||
}
|
||||
|
||||
PIMathVectord X;
|
||||
static Method method_global;
|
||||
static const char methods_desc[];
|
||||
|
||||
private:
|
||||
void moveF() {for (uint i = F.size() - 1; i > 0; --i) F[i] = F[i - 1];}
|
||||
void moveF() {
|
||||
for (uint i = F.size() - 1; i > 0; --i)
|
||||
F[i] = F[i - 1];
|
||||
}
|
||||
|
||||
PIMathMatrixd A, M;
|
||||
PIMathVectord d, a1, b1;
|
||||
|
||||
@@ -5,22 +5,22 @@
|
||||
* \~russian Математический вектор
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathVector
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
PIMathVector
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIMATHVECTOR_H
|
||||
@@ -37,15 +37,16 @@ class PIMathMatrixT;
|
||||
|
||||
/// Vector templated
|
||||
|
||||
#define PIMV_FOR for (uint i = 0; i < Size; ++i)
|
||||
#define PIMV_FOR for (uint i = 0; i < Size; ++i)
|
||||
|
||||
template<uint Size, typename Type = double>
|
||||
class PIP_EXPORT PIMathVectorT {
|
||||
typedef PIMathVectorT<Size, Type> _CVector;
|
||||
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
|
||||
static_assert(Size > 0, "Size must be > 0");
|
||||
|
||||
public:
|
||||
PIMathVectorT(const Type & v = Type()) {PIMV_FOR c[i] = v;}
|
||||
PIMathVectorT(const Type & v = Type()) { PIMV_FOR c[i] = v; }
|
||||
PIMathVectorT(const PIVector<Type> & val) {
|
||||
assert(Size == val.size());
|
||||
PIMV_FOR c[i] = val[i];
|
||||
@@ -60,10 +61,19 @@ public:
|
||||
return tv;
|
||||
}
|
||||
|
||||
constexpr uint size() const {return Size;}
|
||||
_CVector & fill(const Type & v) {PIMV_FOR c[i] = v; return *this;}
|
||||
_CVector & move(const Type & v) {PIMV_FOR c[i] += v; return *this;}
|
||||
_CVector & move(const _CVector & v) {PIMV_FOR c[i] += v[i]; return *this;}
|
||||
constexpr uint size() const { return Size; }
|
||||
_CVector & fill(const Type & v) {
|
||||
PIMV_FOR c[i] = v;
|
||||
return *this;
|
||||
}
|
||||
_CVector & move(const Type & v) {
|
||||
PIMV_FOR c[i] += v;
|
||||
return *this;
|
||||
}
|
||||
_CVector & move(const _CVector & v) {
|
||||
PIMV_FOR c[i] += v[i];
|
||||
return *this;
|
||||
}
|
||||
_CVector & swapElements(uint f, uint s) {
|
||||
piSwap<Type>(c[f], c[s]);
|
||||
return *this;
|
||||
@@ -73,7 +83,7 @@ public:
|
||||
PIMV_FOR tv += c[i] * c[i];
|
||||
return tv;
|
||||
}
|
||||
Type length() const {return std::sqrt(lengthSqr());}
|
||||
Type length() const { return std::sqrt(lengthSqr()); }
|
||||
Type manhattanLength() const {
|
||||
Type tv(0);
|
||||
PIMV_FOR tv += piAbs<Type>(c[i]);
|
||||
@@ -88,9 +98,9 @@ public:
|
||||
Type tv = angleCos(v);
|
||||
return std::sqrt(Type(1) - tv * tv);
|
||||
}
|
||||
Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));}
|
||||
Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));}
|
||||
Type angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);}
|
||||
Type angleRad(const _CVector & v) const { return std::acos(angleCos(v)); }
|
||||
Type angleDeg(const _CVector & v) const { return toDeg(angleRad(v)); }
|
||||
Type angleElevation(const _CVector & v) const { return 90.0 - angleDeg(v - *this); }
|
||||
_CVector projection(const _CVector & v) {
|
||||
Type tv = v.length();
|
||||
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
|
||||
@@ -103,47 +113,60 @@ public:
|
||||
PIMV_FOR c[i] /= tv;
|
||||
return *this;
|
||||
}
|
||||
_CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;}
|
||||
bool isNull() const {PIMV_FOR if (c[i] != Type(0)) return false; return true;}
|
||||
bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);}
|
||||
_CVector normalized() {
|
||||
_CVector tv(*this);
|
||||
tv.normalize();
|
||||
return tv;
|
||||
}
|
||||
bool isNull() const {
|
||||
PIMV_FOR if (c[i] != Type(0)) return false;
|
||||
return true;
|
||||
}
|
||||
bool isOrtho(const _CVector & v) const { return ((*this) ^ v) == Type(0); }
|
||||
|
||||
Type & operator [](uint index) {return c[index];}
|
||||
const Type & operator [](uint index) const {return c[index];}
|
||||
Type at(uint index) const {return c[index];}
|
||||
Type & operator[](uint index) { return c[index]; }
|
||||
const Type & operator[](uint index) const { return c[index]; }
|
||||
Type at(uint index) const { return c[index]; }
|
||||
|
||||
_CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;}
|
||||
_CVector & operator=(const Type & v) {
|
||||
PIMV_FOR c[i] = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator ==(const _CVector & v) const {PIMV_FOR if (c[i] != v[i]) return false; return true;}
|
||||
bool operator !=(const _CVector & v) const {return !(*this == c);}
|
||||
bool operator==(const _CVector & v) const {
|
||||
PIMV_FOR if (c[i] != v[i]) return false;
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const _CVector & v) const { return !(*this == c); }
|
||||
|
||||
void operator +=(const _CVector & v) {PIMV_FOR c[i] += v[i];}
|
||||
void operator -=(const _CVector & v) {PIMV_FOR c[i] -= v[i];}
|
||||
void operator *=(const Type & v) {PIMV_FOR c[i] *= v;}
|
||||
void operator /=(const Type & v) {
|
||||
void operator+=(const _CVector & v) { PIMV_FOR c[i] += v[i]; }
|
||||
void operator-=(const _CVector & v) { PIMV_FOR c[i] -= v[i]; }
|
||||
void operator*=(const Type & v) { PIMV_FOR c[i] *= v; }
|
||||
void operator/=(const Type & v) {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
PIMV_FOR c[i] /= v;
|
||||
}
|
||||
_CVector operator -() const {
|
||||
_CVector operator-() const {
|
||||
_CVector tv;
|
||||
PIMV_FOR tv[i] = -c[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector operator +(const _CVector & v) const {
|
||||
_CVector operator+(const _CVector & v) const {
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR tv[i] += v[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector operator -(const _CVector & v) const {
|
||||
_CVector operator-(const _CVector & v) const {
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR tv[i] -= v[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector operator *(const Type & v) const {
|
||||
_CVector operator*(const Type & v) const {
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR tv[i] *= v;
|
||||
return tv;
|
||||
}
|
||||
_CVector operator /(const Type & v) const {
|
||||
_CVector operator/(const Type & v) const {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
_CVector tv = _CVector(*this);
|
||||
PIMV_FOR tv[i] /= v;
|
||||
@@ -153,9 +176,9 @@ public:
|
||||
_CVector cross(const _CVector & v) const {
|
||||
static_assert(Size == 3, "cross product avalible only for 3D vectors");
|
||||
_CVector tv;
|
||||
tv[0] = c[1]*v[2] - v[1]*c[2];
|
||||
tv[1] = v[0]*c[2] - c[0]*v[2];
|
||||
tv[2] = c[0]*v[1] - v[0]*c[1];
|
||||
tv[0] = c[1] * v[2] - v[1] * c[2];
|
||||
tv[1] = v[0] * c[2] - c[0] * v[2];
|
||||
tv[2] = c[0] * v[1] - v[0] * c[1];
|
||||
return tv;
|
||||
}
|
||||
Type dot(const _CVector & v) const {
|
||||
@@ -168,9 +191,7 @@ public:
|
||||
PIMV_FOR tv[i] *= v[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector mul(const Type & v) const {
|
||||
return (*this) * v;
|
||||
}
|
||||
_CVector mul(const Type & v) const { return (*this) * v; }
|
||||
_CVector div(const _CVector & v) const {
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR {
|
||||
@@ -179,9 +200,7 @@ public:
|
||||
}
|
||||
return tv;
|
||||
}
|
||||
_CVector div(const Type & v) const {
|
||||
return (*this) / v;
|
||||
}
|
||||
_CVector div(const Type & v) const { return (*this) / v; }
|
||||
|
||||
PIMathMatrixT<1, Size, Type> transposed() const {
|
||||
PIMathMatrixT<1, Size, Type> ret;
|
||||
@@ -194,51 +213,37 @@ public:
|
||||
Type tv = a.length();
|
||||
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
|
||||
_CVector b(lp0, *this);
|
||||
return piAbs<Type>(a[0]*b[1] - a[1]*b[0]) / tv;
|
||||
return piAbs<Type>(a[0] * b[1] - a[1] * b[0]) / tv;
|
||||
}
|
||||
|
||||
template<uint Size1, typename Type1> /// vector {Size, Type} to vector {Size1, Type1}
|
||||
PIMathVectorT<Size1, Type1> turnTo() const {
|
||||
PIMathVectorT<Size1, Type1> tv;
|
||||
uint sz = piMin<uint>(Size, Size1);
|
||||
for (uint i = 0; i < sz; ++i) tv[i] = c[i];
|
||||
for (uint i = 0; i < sz; ++i)
|
||||
tv[i] = c[i];
|
||||
return tv;
|
||||
}
|
||||
|
||||
static _CVector cross(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.cross(v2);
|
||||
}
|
||||
static _CVector dot(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.dot(v2);
|
||||
}
|
||||
static _CVector mul(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.mul(v2);
|
||||
}
|
||||
static _CVector mul(const Type & v1, const _CVector & v2) {
|
||||
return v2 * v1;
|
||||
}
|
||||
static _CVector mul(const _CVector & v1, const Type & v2) {
|
||||
return v1 * v2;
|
||||
}
|
||||
static _CVector div(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.div(v2);
|
||||
}
|
||||
static _CVector div(const _CVector & v1, const Type & v2) {
|
||||
return v1 / v2;
|
||||
}
|
||||
static _CVector cross(const _CVector & v1, const _CVector & v2) { return v1.cross(v2); }
|
||||
static _CVector dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); }
|
||||
static _CVector mul(const _CVector & v1, const _CVector & v2) { return v1.mul(v2); }
|
||||
static _CVector mul(const Type & v1, const _CVector & v2) { return v2 * v1; }
|
||||
static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; }
|
||||
static _CVector div(const _CVector & v1, const _CVector & v2) { return v1.div(v2); }
|
||||
static _CVector div(const _CVector & v1, const Type & v2) { return v1 / v2; }
|
||||
|
||||
private:
|
||||
Type c[Size];
|
||||
|
||||
};
|
||||
|
||||
template<uint Size, typename Type>
|
||||
inline PIMathVectorT<Size, Type> operator *(const Type & x, const PIMathVectorT<Size, Type> & v) {
|
||||
inline PIMathVectorT<Size, Type> operator*(const Type & x, const PIMathVectorT<Size, Type> & v) {
|
||||
return v * x;
|
||||
}
|
||||
|
||||
template<uint Size, typename Type>
|
||||
inline PICout operator <<(PICout s, const PIMathVectorT<Size, Type> & v) {
|
||||
inline PICout operator<<(PICout s, const PIMathVectorT<Size, Type> & v) {
|
||||
s << "Vector{";
|
||||
PIMV_FOR {
|
||||
s << v[i];
|
||||
@@ -266,34 +271,40 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d;
|
||||
template<typename Type>
|
||||
class PIP_EXPORT PIMathVector {
|
||||
typedef PIMathVector<Type> _CVector;
|
||||
template <typename P, typename Type1>
|
||||
friend PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMathVector<Type1> & v);
|
||||
template <typename P, typename Type1>
|
||||
friend PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMathVector<Type1> & v);
|
||||
template<typename P, typename Type1>
|
||||
friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMathVector<Type1> & v);
|
||||
template<typename P, typename Type1>
|
||||
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMathVector<Type1> & v);
|
||||
|
||||
public:
|
||||
PIMathVector(const uint size = 0, const Type & new_value = Type()) {c.resize(size, new_value);}
|
||||
PIMathVector(const PIVector<Type> & val) {c = val;}
|
||||
PIMathVector(PIVector<Type> && val) : c(std::move(val)) {}
|
||||
PIMathVector(std::initializer_list<Type> init_list) {c = PIVector<Type>(init_list);}
|
||||
PIMathVector(const uint size = 0, const Type & new_value = Type()) { c.resize(size, new_value); }
|
||||
PIMathVector(const PIVector<Type> & val) { c = val; }
|
||||
PIMathVector(PIVector<Type> && val): c(std::move(val)) {}
|
||||
PIMathVector(std::initializer_list<Type> init_list) { c = PIVector<Type>(init_list); }
|
||||
|
||||
template<uint Size>
|
||||
PIMathVector(const PIMathVectorT<Size, Type> & val) {c.resize(Size); PIMV_FOR c[i] = val[i];}
|
||||
PIMathVector(const PIMathVectorT<Size, Type> & val) {
|
||||
c.resize(Size);
|
||||
PIMV_FOR c[i] = val[i];
|
||||
}
|
||||
|
||||
static PIMathVector fromTwoPoints(const _CVector & st, const _CVector & fn) {
|
||||
assert(st.size() == fn.size());
|
||||
_CVector v(st.size());
|
||||
for (uint i = 0; i < v.size(); ++i) v.c[i] = fn[i] - st[i];
|
||||
for (uint i = 0; i < v.size(); ++i)
|
||||
v.c[i] = fn[i] - st[i];
|
||||
}
|
||||
|
||||
static PIMathVector zeros(const uint size) {return PIMathVector(size, Type());}
|
||||
static PIMathVector ones(const uint size) {return PIMathVector(size, Type(1));}
|
||||
static PIMathVector zeros(const uint size) { return PIMathVector(size, Type()); }
|
||||
static PIMathVector ones(const uint size) { return PIMathVector(size, Type(1)); }
|
||||
static PIMathVector arange(const Type start, const Type stop, const Type step = Type(1)) {
|
||||
PIVector<Type> v;
|
||||
for (Type i = start; i < stop; i+= step) v << i;
|
||||
for (Type i = start; i < stop; i += step)
|
||||
v << i;
|
||||
return PIMathVector(std::move(v));
|
||||
}
|
||||
|
||||
uint size() const {return c.size();}
|
||||
uint size() const { return c.size(); }
|
||||
_CVector & resize(uint size, const Type & new_value = Type()) {
|
||||
c.resize(size, new_value);
|
||||
return *this;
|
||||
@@ -325,7 +336,7 @@ public:
|
||||
PIMV_FOR tv += c[i] * c[i];
|
||||
return tv;
|
||||
}
|
||||
Type length() const {return std::sqrt(lengthSqr());}
|
||||
Type length() const { return std::sqrt(lengthSqr()); }
|
||||
Type manhattanLength() const {
|
||||
Type tv(0);
|
||||
PIMV_FOR tv += piAbs<Type>(c[i]);
|
||||
@@ -342,8 +353,8 @@ public:
|
||||
Type tv = angleCos(v);
|
||||
return std::sqrt(Type(1) - tv * tv);
|
||||
}
|
||||
Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));}
|
||||
Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));}
|
||||
Type angleRad(const _CVector & v) const { return std::acos(angleCos(v)); }
|
||||
Type angleDeg(const _CVector & v) const { return toDeg(angleRad(v)); }
|
||||
_CVector projection(const _CVector & v) {
|
||||
assert(c.size() == v.size());
|
||||
Type tv = v.length();
|
||||
@@ -366,54 +377,57 @@ public:
|
||||
PIMV_FOR if (c[i] != Type(0)) return false;
|
||||
return true;
|
||||
}
|
||||
bool isValid() const {return !c.isEmpty();}
|
||||
bool isOrtho(const _CVector & v) const {return dot(v) == Type(0);}
|
||||
bool isValid() const { return !c.isEmpty(); }
|
||||
bool isOrtho(const _CVector & v) const { return dot(v) == Type(0); }
|
||||
|
||||
Type & operator [](uint index) {return c[index];}
|
||||
const Type & operator [](uint index) const {return c[index];}
|
||||
Type at(uint index) const {return c[index];}
|
||||
Type & operator[](uint index) { return c[index]; }
|
||||
const Type & operator[](uint index) const { return c[index]; }
|
||||
Type at(uint index) const { return c[index]; }
|
||||
|
||||
_CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;}
|
||||
_CVector & operator=(const Type & v) {
|
||||
PIMV_FOR c[i] = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator ==(const _CVector & v) const {return c == v.c;}
|
||||
bool operator !=(const _CVector & v) const {return c != v.c;}
|
||||
bool operator==(const _CVector & v) const { return c == v.c; }
|
||||
bool operator!=(const _CVector & v) const { return c != v.c; }
|
||||
|
||||
void operator +=(const _CVector & v) {
|
||||
void operator+=(const _CVector & v) {
|
||||
assert(c.size() == v.size());
|
||||
PIMV_FOR c[i] += v[i];
|
||||
}
|
||||
void operator -=(const _CVector & v) {
|
||||
void operator-=(const _CVector & v) {
|
||||
assert(c.size() == v.size());
|
||||
PIMV_FOR c[i] -= v[i];
|
||||
}
|
||||
void operator *=(const Type & v) {PIMV_FOR c[i] *= v;}
|
||||
void operator /=(const Type & v) {
|
||||
void operator*=(const Type & v) { PIMV_FOR c[i] *= v; }
|
||||
void operator/=(const Type & v) {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
PIMV_FOR c[i] /= v;
|
||||
}
|
||||
_CVector operator -() const {
|
||||
_CVector operator-() const {
|
||||
_CVector tv(c.size());
|
||||
PIMV_FOR tv[i] = -c[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector operator +(const _CVector & v) const {
|
||||
_CVector operator+(const _CVector & v) const {
|
||||
assert(c.size() == v.size());
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR tv[i] += v[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector operator -(const _CVector & v) const {
|
||||
_CVector operator-(const _CVector & v) const {
|
||||
assert(c.size() == v.size());
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR tv[i] -= v[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector operator *(const Type & v) const {
|
||||
_CVector operator*(const Type & v) const {
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR tv[i] *= v;
|
||||
return tv;
|
||||
}
|
||||
_CVector operator /(const Type & v) const {
|
||||
_CVector operator/(const Type & v) const {
|
||||
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
|
||||
_CVector tv(*this);
|
||||
PIMV_FOR tv[i] /= v;
|
||||
@@ -423,9 +437,9 @@ public:
|
||||
assert(c.size() == 3);
|
||||
assert(v.size() == 3);
|
||||
_CVector tv(3);
|
||||
tv[0] = c[1]*v[2] - v[1]*c[2];
|
||||
tv[1] = c[2]*v[0] - v[2]*c[0];
|
||||
tv[2] = c[0]*v[1] - v[0]*c[1];
|
||||
tv[0] = c[1] * v[2] - v[1] * c[2];
|
||||
tv[1] = c[2] * v[0] - v[2] * c[0];
|
||||
tv[2] = c[0] * v[1] - v[0] * c[1];
|
||||
return tv;
|
||||
}
|
||||
Type dot(const _CVector & v) const {
|
||||
@@ -440,9 +454,7 @@ public:
|
||||
PIMV_FOR tv[i] *= v[i];
|
||||
return tv;
|
||||
}
|
||||
_CVector mul(const Type & v) const {
|
||||
return (*this) * v;
|
||||
}
|
||||
_CVector mul(const Type & v) const { return (*this) * v; }
|
||||
_CVector div(const _CVector & v) const {
|
||||
assert(c.size() == v.size());
|
||||
_CVector tv(*this);
|
||||
@@ -452,61 +464,44 @@ public:
|
||||
}
|
||||
return tv;
|
||||
}
|
||||
_CVector div(const Type & v) const {
|
||||
return (*this) / v;
|
||||
}
|
||||
_CVector div(const Type & v) const { return (*this) / v; }
|
||||
|
||||
Type distToLine(const _CVector & lp0, const _CVector & lp1) {
|
||||
assert(c.size() == lp0.size());
|
||||
assert(c.size() == lp1.size());
|
||||
_CVector a = _CVector::fromTwoPoints(lp0, lp1);
|
||||
Type tv = a.length();
|
||||
Type tv = a.length();
|
||||
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
|
||||
_CVector b = _CVector::fromTwoPoints(lp0, *this);
|
||||
return piAbs<Type>(a[0]*b[1] - a[1]*b[0]) / tv;
|
||||
return piAbs<Type>(a[0] * b[1] - a[1] * b[0]) / tv;
|
||||
}
|
||||
|
||||
PIVector<Type> toVector() const {return c;}
|
||||
PIVector<Type> toVector() const { return c; }
|
||||
|
||||
void forEach(std::function<void(const Type &)> f) const {
|
||||
c.forEach(f);
|
||||
}
|
||||
void forEach(std::function<void(const Type &)> f) const { c.forEach(f); }
|
||||
_CVector & forEach(std::function<void(Type &)> f) {
|
||||
c.forEach(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Type * data() {return c.data();}
|
||||
inline const Type * data() const {return c.data();}
|
||||
inline Type * data() { return c.data(); }
|
||||
inline const Type * data() const { return c.data(); }
|
||||
|
||||
|
||||
static _CVector cross(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.cross(v2);
|
||||
}
|
||||
static _CVector dot(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.dot(v2);
|
||||
}
|
||||
static _CVector mul(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.mul(v2);
|
||||
}
|
||||
static _CVector mul(const Type & v1, const _CVector & v2) {
|
||||
return v2 * v1;
|
||||
}
|
||||
static _CVector mul(const _CVector & v1, const Type & v2) {
|
||||
return v1 * v2;
|
||||
}
|
||||
static _CVector div(const _CVector & v1, const _CVector & v2) {
|
||||
return v1.div(v2);
|
||||
}
|
||||
static _CVector div(const _CVector & v1, const Type & v2) {
|
||||
return v1 / v2;
|
||||
}
|
||||
static _CVector cross(const _CVector & v1, const _CVector & v2) { return v1.cross(v2); }
|
||||
static _CVector dot(const _CVector & v1, const _CVector & v2) { return v1.dot(v2); }
|
||||
static _CVector mul(const _CVector & v1, const _CVector & v2) { return v1.mul(v2); }
|
||||
static _CVector mul(const Type & v1, const _CVector & v2) { return v2 * v1; }
|
||||
static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; }
|
||||
static _CVector div(const _CVector & v1, const _CVector & v2) { return v1.div(v2); }
|
||||
static _CVector div(const _CVector & v1, const Type & v2) { return v1 / v2; }
|
||||
|
||||
private:
|
||||
PIVector<Type> c;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
inline PIMathVector<Type> operator *(const Type & x, const PIMathVector<Type> & v) {
|
||||
inline PIMathVector<Type> operator*(const Type & x, const PIMathVector<Type> & v) {
|
||||
return v * x;
|
||||
}
|
||||
|
||||
@@ -514,11 +509,19 @@ inline PIMathVector<Type> operator *(const Type & x, const PIMathVector<Type> &
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
template<typename Type>
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIMathVector<Type> & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
||||
inline std::ostream & operator<<(std::ostream & s, const PIMathVector<Type> & v) {
|
||||
s << "{";
|
||||
for (uint i = 0; i < v.size(); ++i) {
|
||||
s << v[i];
|
||||
if (i < v.size() - 1) s << ", ";
|
||||
}
|
||||
s << "}";
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename Type>
|
||||
inline PICout operator <<(PICout s, const PIMathVector<Type> & v) {
|
||||
inline PICout operator<<(PICout s, const PIMathVector<Type> & v) {
|
||||
s << "Vector{";
|
||||
for (uint i = 0; i < v.size(); ++i) {
|
||||
s << v[i];
|
||||
@@ -528,10 +531,16 @@ inline PICout operator <<(PICout s, const PIMathVector<Type> & v) {
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator <<(PIBinaryStream<P> & s, const PIMathVector<T> & v) {s << v.c; return s;}
|
||||
template <typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator >>(PIBinaryStream<P> & s, PIMathVector<T> & v) {s >> v.c; return s;}
|
||||
template<typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const PIMathVector<T> & v) {
|
||||
s << v.c;
|
||||
return s;
|
||||
}
|
||||
template<typename P, typename T>
|
||||
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMathVector<T> & v) {
|
||||
s >> v.c;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
typedef PIMathVector<int> PIMathVectori;
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
//! \~english Two-dimensional point class
|
||||
//! \~russian Класс двумерной точки
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Two-dimensional point class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
PIP - Platform Independent Primitives
|
||||
Two-dimensional point class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PIPOINT_H
|
||||
#define PIPOINT_H
|
||||
@@ -28,22 +28,23 @@
|
||||
//! \~english Two-dimensional point class
|
||||
//! \~russian Класс двумерной точки
|
||||
//! \details
|
||||
//! Данный класс позволяет хранить и работать с двумерными точками.
|
||||
//! Данный класс позволяет хранить и работать с двумерными точками.
|
||||
//! Для работы с объектами реализованы операторы сложения, вычитания и проверки на ревенство и неравенство.
|
||||
//! Также доступны методы для перемещения точек \a translate(), \a translated(), \a move(), \a moved()
|
||||
//! Также доступны методы для перемещения точек \a translate(), \a translated(), \a move(), \a moved()
|
||||
//! и перевода из декартовой системы координат в полярную \a toPolar() и обратно \a fromPolar().
|
||||
template<typename Type>
|
||||
class PIP_EXPORT PIPoint {
|
||||
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
|
||||
|
||||
public:
|
||||
Type x;
|
||||
Type y;
|
||||
|
||||
//! \~russian Создает новую точку.
|
||||
PIPoint() {x = y = Type();}
|
||||
PIPoint() { x = y = Type(); }
|
||||
|
||||
//! \~russian Создает новую точку с заданными координатами.
|
||||
PIPoint(Type x_, Type y_) {set(x_, y_);}
|
||||
PIPoint(Type x_, Type y_) { set(x_, y_); }
|
||||
|
||||
//! \~russian Задать новые координаты точке.
|
||||
PIPoint<Type> & set(Type x_, Type y_) {
|
||||
@@ -89,11 +90,11 @@ public:
|
||||
|
||||
//! \~russian Переместить точку.
|
||||
//! \details Является копией метода \a translate().
|
||||
PIPoint<Type> & move(Type x_, Type y_) {return translate(x_, y_);}
|
||||
PIPoint<Type> & move(Type x_, Type y_) { return translate(x_, y_); }
|
||||
|
||||
//! \~russian Переместить точку.
|
||||
//! \details Является копией метода \a translate().
|
||||
PIPoint<Type> & move(const PIPoint<Type> & p) {return translate(p);}
|
||||
PIPoint<Type> & move(const PIPoint<Type> & p) { return translate(p); }
|
||||
|
||||
//! \~russian Создать копию точки и переместить её.
|
||||
//! \details Является копией метода \a translated().
|
||||
@@ -112,47 +113,47 @@ public:
|
||||
}
|
||||
|
||||
//! \~russian Посчитать угол(радианы) в поолярной системе координат.
|
||||
double angleRad() const {return atan2(y, x);}
|
||||
double angleRad() const { return atan2(y, x); }
|
||||
|
||||
//! \~russian Посчитать угол(градусы) в поолярной системе координат.
|
||||
double angleDeg() const {return toDeg(atan2(y, x));}
|
||||
double angleDeg() const { return toDeg(atan2(y, x)); }
|
||||
|
||||
//! \~russian Перевести копию точки в полярную систему координат.
|
||||
PIPoint<Type> toPolar(bool isDeg = false) const {return PIPoint<Type>(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());}
|
||||
PIPoint<Type> toPolar(bool isDeg = false) const { return PIPoint<Type>(sqrt(x * x + y * y), isDeg ? angleDeg() : angleRad()); }
|
||||
|
||||
//! \~russian Перевести копию точки из полярной системы координат в декартовую.
|
||||
static PIPoint<Type> fromPolar(const PIPoint<Type> & p) {return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x));}
|
||||
static PIPoint<Type> fromPolar(const PIPoint<Type> & p) { return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x)); }
|
||||
|
||||
//! \~russian
|
||||
//! \~russian
|
||||
//! Прибавить координаты второй точки и сохранить.
|
||||
//! \details Является копией метода \a translate().
|
||||
void operator +=(const PIPoint<Type> & p) {translate(p);}
|
||||
void operator+=(const PIPoint<Type> & p) { translate(p); }
|
||||
|
||||
//! \~russian Сложить координаты двух точек.
|
||||
PIPoint<Type> operator +(const PIPoint<Type> & p) {return PIPoint<Type>(x + p.x, y + p.y);}
|
||||
PIPoint<Type> operator+(const PIPoint<Type> & p) { return PIPoint<Type>(x + p.x, y + p.y); }
|
||||
|
||||
//! \~russian Прибавить к координатам одинаковое значение.
|
||||
PIPoint<Type> operator +(const Type & p) {return PIPoint<Type>(x + p, y + p);}
|
||||
PIPoint<Type> operator+(const Type & p) { return PIPoint<Type>(x + p, y + p); }
|
||||
|
||||
//! \~russian Вычесть из координат координаты второй точки - найти смещение.
|
||||
PIPoint<Type> operator -(const PIPoint<Type> & p) {return PIPoint<Type>(x - p.x, y - p.y);}
|
||||
PIPoint<Type> operator-(const PIPoint<Type> & p) { return PIPoint<Type>(x - p.x, y - p.y); }
|
||||
|
||||
//! \~russian Вычесть из координат одинаковое значение.
|
||||
PIPoint<Type> operator -(const Type & p) {return PIPoint<Type>(x - p, y - p);}
|
||||
PIPoint<Type> operator-(const Type & p) { return PIPoint<Type>(x - p, y - p); }
|
||||
|
||||
//! \~russian Инвертировать координаты точки.
|
||||
PIPoint<Type> operator -() {return PIPoint<Type>(-x, -y);}
|
||||
PIPoint<Type> operator-() { return PIPoint<Type>(-x, -y); }
|
||||
|
||||
//! \~russian Проверить равенство координат двух точек.
|
||||
bool operator ==(const PIPoint<Type> & p) const {return (x == p.x && y == p.y);}
|
||||
bool operator==(const PIPoint<Type> & p) const { return (x == p.x && y == p.y); }
|
||||
|
||||
//! \~russian Проверить неравенство координат двух точек.
|
||||
bool operator !=(const PIPoint<Type> & p) const {return (x != p.x || y != p.y);}
|
||||
bool operator!=(const PIPoint<Type> & p) const { return (x != p.x || y != p.y); }
|
||||
};
|
||||
|
||||
//! \~russian Перегруженный оператор для вывода координат в \a PICout.
|
||||
template<typename Type>
|
||||
PICout operator <<(PICout & s, const PIPoint<Type> & v) {
|
||||
PICout operator<<(PICout & s, const PIPoint<Type> & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "Point{" << v.x << ", " << v.y << "}";
|
||||
s.restoreControls();
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Class for quaternions
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Class for quaternions
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "piquaternion.h"
|
||||
@@ -30,8 +30,8 @@ PIQuaternion::PIQuaternion(const PIMathVectorT3d & u, double a) {
|
||||
|
||||
PIMathVectorT3d PIQuaternion::eyler() const {
|
||||
PIMathMatrixT33d rmat = rotationMatrix();
|
||||
double angle_y = asin(rmat[0][2]), angle_x, angle_z;
|
||||
double c = cos(angle_y);
|
||||
double angle_y = asin(rmat[0][2]), angle_x, angle_z;
|
||||
double c = cos(angle_y);
|
||||
if (fabs(c) < 1.E-5) {
|
||||
angle_x = 0;
|
||||
angle_z = atan2(rmat[1][0], rmat[1][1]);
|
||||
@@ -39,8 +39,8 @@ PIMathVectorT3d PIQuaternion::eyler() const {
|
||||
angle_x = -atan2(-rmat[1][2] / c, rmat[2][2] / c);
|
||||
angle_z = atan2(-rmat[0][1] / c, rmat[0][0] / c);
|
||||
}
|
||||
if (angle_z < 0) angle_z = 2*M_PI + angle_z;
|
||||
return PIMathVectorT3d({angle_x,angle_y,angle_z});
|
||||
if (angle_z < 0) angle_z = 2 * M_PI + angle_z;
|
||||
return PIMathVectorT3d({angle_x, angle_y, angle_z});
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,6 @@ PIMathMatrixT33d PIQuaternion::rotationMatrix() const {
|
||||
void PIQuaternion::axis(PIMathVectorT3d * ret) const {
|
||||
if (!ret) return;
|
||||
ret[0] = vector();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +88,7 @@ void PIQuaternion::rotate(const PIMathVectorT3d & u, double a) {
|
||||
|
||||
|
||||
void PIQuaternion::normalize() {
|
||||
double d = sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
|
||||
double d = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
|
||||
if (d != 0.)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
q[i] /= d;
|
||||
@@ -105,35 +104,35 @@ PIQuaternion PIQuaternion::fromEyler(double ax, double ay, double az) {
|
||||
q_heading.q[1] = 0;
|
||||
q_heading.q[2] = sin(ax / 2);
|
||||
q_heading.q[3] = -cos(ax / 2);
|
||||
q_pinch.q[0] = 0;
|
||||
q_pinch.q[1] = sin(ay / 2);
|
||||
q_pinch.q[2] = 0;
|
||||
q_pinch.q[3] = -cos(ay / 2);
|
||||
az = M_PI - az;
|
||||
q_bank.q[0] = sin(az / 2);
|
||||
q_bank.q[1] = 0;
|
||||
q_bank.q[2] = 0;
|
||||
q_bank.q[3] = cos(az / 2);
|
||||
q_tmp = q_heading * q_pinch;
|
||||
q_tmp = q_tmp * q_bank;
|
||||
q_pinch.q[0] = 0;
|
||||
q_pinch.q[1] = sin(ay / 2);
|
||||
q_pinch.q[2] = 0;
|
||||
q_pinch.q[3] = -cos(ay / 2);
|
||||
az = M_PI - az;
|
||||
q_bank.q[0] = sin(az / 2);
|
||||
q_bank.q[1] = 0;
|
||||
q_bank.q[2] = 0;
|
||||
q_bank.q[3] = cos(az / 2);
|
||||
q_tmp = q_heading * q_pinch;
|
||||
q_tmp = q_tmp * q_bank;
|
||||
q_tmp.normalize();
|
||||
return q_tmp;
|
||||
}
|
||||
|
||||
|
||||
PIQuaternion PIQuaternion::fromAngles(double ax, double ay, double az) {
|
||||
double c1 = cos(ay/2);
|
||||
double s1 = sin(ay/2);
|
||||
double c2 = cos(az/2);
|
||||
double s2 = sin(az/2);
|
||||
double c3 = cos(ax/2);
|
||||
double s3 = sin(ax/2);
|
||||
double c1c2 = c1*c2;
|
||||
double s1s2 = s1*s2;
|
||||
double a = c1c2*c3 - s1s2*s3;
|
||||
double x = c1c2*s3 + s1s2*c3;
|
||||
double y = s1*c2*c3 + c1*s2*s3;
|
||||
double z = c1*s2*c3 - s1*c2*s3;
|
||||
double c1 = cos(ay / 2);
|
||||
double s1 = sin(ay / 2);
|
||||
double c2 = cos(az / 2);
|
||||
double s2 = sin(az / 2);
|
||||
double c3 = cos(ax / 2);
|
||||
double s3 = sin(ax / 2);
|
||||
double c1c2 = c1 * c2;
|
||||
double s1s2 = s1 * s2;
|
||||
double a = c1c2 * c3 - s1s2 * s3;
|
||||
double x = c1c2 * s3 + s1s2 * c3;
|
||||
double y = s1 * c2 * c3 + c1 * s2 * s3;
|
||||
double z = c1 * s2 * c3 - s1 * c2 * s3;
|
||||
PIQuaternion res;
|
||||
res.q[0] = a;
|
||||
res.q[1] = x;
|
||||
@@ -143,13 +142,13 @@ PIQuaternion PIQuaternion::fromAngles(double ax, double ay, double az) {
|
||||
}
|
||||
|
||||
PIQuaternion PIQuaternion::fromAngles2(double ax, double ay, double az) {
|
||||
double om = PIMathVectorT3d({ax,ay,az}).length();
|
||||
double om = PIMathVectorT3d({ax, ay, az}).length();
|
||||
if (om == 0.) return PIQuaternion(PIMathVectorT3d(), 1.);
|
||||
PIQuaternion res;
|
||||
res.q[0] = cos(om/2);
|
||||
res.q[1] = ax/om * sin(om/2);
|
||||
res.q[2] = ay/om * sin(om/2);
|
||||
res.q[3] = az/om * sin(om/2);
|
||||
res.q[0] = cos(om / 2);
|
||||
res.q[1] = ax / om * sin(om / 2);
|
||||
res.q[2] = ay / om * sin(om / 2);
|
||||
res.q[3] = az / om * sin(om / 2);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -189,8 +188,8 @@ PIQuaternion PIQuaternion::fromRotationMatrix(const PIMathMatrixT33d & m) {
|
||||
|
||||
PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1) {
|
||||
PIMathVectorT3d v0(q0.vector()), v1(q1.vector());
|
||||
double r0 = q0.q[0] * q1.q[0] - v0.dot(v1);
|
||||
PIMathVectorT3d qv = v1*q0.q[0] + v0*q1.q[0] + v0.cross(v1);
|
||||
double r0 = q0.q[0] * q1.q[0] - v0.dot(v1);
|
||||
PIMathVectorT3d qv = v1 * q0.q[0] + v0 * q1.q[0] + v0.cross(v1);
|
||||
PIQuaternion ret;
|
||||
ret.q[0] = r0;
|
||||
ret.q[1] = qv[0];
|
||||
@@ -200,7 +199,7 @@ PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1) {
|
||||
}
|
||||
|
||||
|
||||
PIQuaternion operator *(const double &a, const PIQuaternion &q1) {
|
||||
PIQuaternion operator*(const double & a, const PIQuaternion & q1) {
|
||||
PIQuaternion ret(q1);
|
||||
ret.q[0] *= a;
|
||||
ret.q[1] *= a;
|
||||
@@ -208,4 +207,3 @@ PIQuaternion operator *(const double &a, const PIQuaternion &q1) {
|
||||
ret.q[3] *= a;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,22 +5,22 @@
|
||||
* \~russian Кватернион
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Class for quaternions
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Class for quaternions
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQUATERNION_H
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
//! \~english Rect class
|
||||
//! \~russian Класс прямоугольника
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Rect class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Rect class
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef PIRECT_H
|
||||
#define PIRECT_H
|
||||
@@ -36,6 +36,7 @@
|
||||
template<typename Type>
|
||||
class PIP_EXPORT PIRect {
|
||||
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
|
||||
|
||||
public:
|
||||
//!
|
||||
PIRect() {}
|
||||
@@ -55,10 +56,10 @@ public:
|
||||
normalize();
|
||||
}
|
||||
|
||||
// PIRect(const PIPoint<Type> & p0, const PIPoint<Type> & p1, const PIPoint<Type> & p2) {
|
||||
// set(piMin<Type>(p0.x, p1.x, p2.x), piMin<Type>(p0.y, p1.y, p2.y),
|
||||
// piMax<Type>(p0.x, p1.x, p2.x), piMax<Type>(p0.y, p1.y, p2.y));
|
||||
// }
|
||||
// PIRect(const PIPoint<Type> & p0, const PIPoint<Type> & p1, const PIPoint<Type> & p2) {
|
||||
// set(piMin<Type>(p0.x, p1.x, p2.x), piMin<Type>(p0.y, p1.y, p2.y),
|
||||
// piMax<Type>(p0.x, p1.x, p2.x), piMax<Type>(p0.y, p1.y, p2.y));
|
||||
// }
|
||||
|
||||
//!
|
||||
PIRect<Type> & set(Type left_, Type bottom_, Type width_, Type height_) {
|
||||
@@ -76,20 +77,14 @@ public:
|
||||
|
||||
//! \brief
|
||||
//! \~russian Возвращает true если точка с указанными координатами принадлежит прямоугольнику
|
||||
bool pointIn(Type x, Type y) const {
|
||||
return (x <= bl.x && x >= tr.x && y <= bl.y && y >= tr.y);
|
||||
}
|
||||
bool pointIn(Type x, Type y) const { return (x <= bl.x && x >= tr.x && y <= bl.y && y >= tr.y); }
|
||||
|
||||
//! \brief
|
||||
//! \~russian Возвращает true если точка с указанными координатами принадлежит прямоугольнику
|
||||
bool pointIn(const PIPoint<Type> & p) const {
|
||||
return pointIn(p.x, p.y);
|
||||
}
|
||||
bool pointIn(const PIPoint<Type> & p) const { return pointIn(p.x, p.y); }
|
||||
|
||||
//!
|
||||
bool isEmpty() const {
|
||||
return (width() == 0 && height() == 0);
|
||||
}
|
||||
bool isEmpty() const { return (width() == 0 && height() == 0); }
|
||||
|
||||
//!
|
||||
PIRect<Type> & translate(Type x, Type y) {
|
||||
@@ -120,10 +115,10 @@ public:
|
||||
}
|
||||
|
||||
//!
|
||||
PIRect<Type> & move(Type x, Type y) {return translate(x, y);}
|
||||
PIRect<Type> & move(Type x, Type y) { return translate(x, y); }
|
||||
|
||||
//!
|
||||
PIRect<Type> & move(const PIPoint<Type> & p) {return translate(p);}
|
||||
PIRect<Type> & move(const PIPoint<Type> & p) { return translate(p); }
|
||||
|
||||
//!
|
||||
PIRect<Type> moved(Type x, Type y) const {
|
||||
@@ -147,10 +142,10 @@ public:
|
||||
}
|
||||
|
||||
//!
|
||||
PIRect<Type> & scale(Type s) {return scale(s, s);}
|
||||
PIRect<Type> & scale(Type s) { return scale(s, s); }
|
||||
|
||||
//!
|
||||
PIRect<Type> & scale(const PIPoint<Type> & p) {return scale(p.x, p.y);}
|
||||
PIRect<Type> & scale(const PIPoint<Type> & p) { return scale(p.x, p.y); }
|
||||
|
||||
//!
|
||||
PIRect<Type> scaled(Type x, Type y) const {
|
||||
@@ -221,74 +216,98 @@ public:
|
||||
}
|
||||
|
||||
//!
|
||||
Type top() const {return tr.y;}
|
||||
Type top() const { return tr.y; }
|
||||
|
||||
//!
|
||||
Type left() const {return bl.x;}
|
||||
Type left() const { return bl.x; }
|
||||
|
||||
//!
|
||||
Type right() const {return tr.x;}
|
||||
Type right() const { return tr.x; }
|
||||
|
||||
//!
|
||||
Type bottom() const {return bl.y;}
|
||||
Type bottom() const { return bl.y; }
|
||||
|
||||
//!
|
||||
Type width() const {return tr.x - bl.x;}
|
||||
Type width() const { return tr.x - bl.x; }
|
||||
|
||||
//!
|
||||
Type height() const {return tr.y - bl.y;}
|
||||
Type height() const { return tr.y - bl.y; }
|
||||
|
||||
//!
|
||||
PIPoint<Type> topLeft() const {return PIPoint<Type>(bl.x, tr.y);}
|
||||
PIPoint<Type> topLeft() const { return PIPoint<Type>(bl.x, tr.y); }
|
||||
|
||||
//!
|
||||
PIPoint<Type> topRigth() const {return tr;}
|
||||
PIPoint<Type> topRigth() const { return tr; }
|
||||
|
||||
//!
|
||||
PIPoint<Type> bottomLeft() const {return bl;}
|
||||
PIPoint<Type> bottomLeft() const { return bl; }
|
||||
|
||||
//!
|
||||
PIPoint<Type> bottomRight() const {return PIPoint<Type>(tr.x, bl.y);}
|
||||
PIPoint<Type> bottomRight() const { return PIPoint<Type>(tr.x, bl.y); }
|
||||
|
||||
//!
|
||||
PIPoint<Type> center() const {return bl.moved(width()/2, height()/2);}
|
||||
PIPoint<Type> center() const { return bl.moved(width() / 2, height() / 2); }
|
||||
|
||||
//!
|
||||
void setTop(Type v) {tr.y = v; normalize();}
|
||||
void setTop(Type v) {
|
||||
tr.y = v;
|
||||
normalize();
|
||||
}
|
||||
|
||||
//!
|
||||
void setLeft(Type v) {bl.x = v; normalize();}
|
||||
void setLeft(Type v) {
|
||||
bl.x = v;
|
||||
normalize();
|
||||
}
|
||||
|
||||
//!
|
||||
void setRigth(Type v) {tr.x = v; normalize();}
|
||||
void setRigth(Type v) {
|
||||
tr.x = v;
|
||||
normalize();
|
||||
}
|
||||
|
||||
//!
|
||||
void setBottom(Type v) {bl.y = v; normalize();}
|
||||
void setBottom(Type v) {
|
||||
bl.y = v;
|
||||
normalize();
|
||||
}
|
||||
|
||||
//!
|
||||
void setWidth(Type v) {setTop(bl.x + v);}
|
||||
void setWidth(Type v) { setTop(bl.x + v); }
|
||||
|
||||
//!
|
||||
void setHeight(Type v) {setRigth(bl.y + v);}
|
||||
void setHeight(Type v) { setRigth(bl.y + v); }
|
||||
|
||||
//!
|
||||
void setTopLeft(const PIPoint<Type> & p) {setLeft(p.x); setTop(p.y);}
|
||||
void setTopLeft(const PIPoint<Type> & p) {
|
||||
setLeft(p.x);
|
||||
setTop(p.y);
|
||||
}
|
||||
|
||||
//!
|
||||
void setBottomRight(const PIPoint<Type> & p) {setRigth(p.x); setBottom(p.y);}
|
||||
void setBottomRight(const PIPoint<Type> & p) {
|
||||
setRigth(p.x);
|
||||
setBottom(p.y);
|
||||
}
|
||||
|
||||
//!
|
||||
void setBottomLeft(const PIPoint<Type> & p) {bl = p; normalize();}
|
||||
void setBottomLeft(const PIPoint<Type> & p) {
|
||||
bl = p;
|
||||
normalize();
|
||||
}
|
||||
|
||||
//!
|
||||
void setTopRigth(const PIPoint<Type> & p) {tr = p; normalize();}
|
||||
void setTopRigth(const PIPoint<Type> & p) {
|
||||
tr = p;
|
||||
normalize();
|
||||
}
|
||||
|
||||
//!
|
||||
void setCenter(const PIPoint<Type> & p) {
|
||||
Type w = width();
|
||||
Type h = height();
|
||||
bl = p.translated(-w/2, -h/2);
|
||||
tr = PIPoint<Type>(bl.x + w, bl.y + h);
|
||||
bl = p.translated(-w / 2, -h / 2);
|
||||
tr = PIPoint<Type>(bl.x + w, bl.y + h);
|
||||
}
|
||||
|
||||
//!
|
||||
@@ -298,40 +317,40 @@ public:
|
||||
}
|
||||
|
||||
//!
|
||||
void operator +=(Type x) {translate(x, x);}
|
||||
void operator+=(Type x) { translate(x, x); }
|
||||
|
||||
//!
|
||||
void operator +=(const PIPoint<Type> & p) {translate(p);}
|
||||
void operator+=(const PIPoint<Type> & p) { translate(p); }
|
||||
|
||||
//!
|
||||
void operator -=(Type x) {translate(-x, -x);}
|
||||
void operator-=(Type x) { translate(-x, -x); }
|
||||
|
||||
//!
|
||||
void operator -=(const PIPoint<Type> & p) {translate(-p);}
|
||||
void operator-=(const PIPoint<Type> & p) { translate(-p); }
|
||||
|
||||
//!
|
||||
void operator |=(const PIRect<Type> & r) {unite(r);}
|
||||
void operator|=(const PIRect<Type> & r) { unite(r); }
|
||||
|
||||
//!
|
||||
void operator &=(const PIRect<Type> & r) {intersect(r);}
|
||||
void operator&=(const PIRect<Type> & r) { intersect(r); }
|
||||
|
||||
//!
|
||||
PIRect<Type> operator +(const PIPoint<Type> & p) {return translated(p);}
|
||||
PIRect<Type> operator+(const PIPoint<Type> & p) { return translated(p); }
|
||||
|
||||
//!
|
||||
PIRect<Type> operator -(const PIPoint<Type> & p) {return translated(-p);}
|
||||
PIRect<Type> operator-(const PIPoint<Type> & p) { return translated(-p); }
|
||||
|
||||
//!
|
||||
PIRect<Type> operator |(const PIRect<Type> & r) {return united(r);}
|
||||
PIRect<Type> operator|(const PIRect<Type> & r) { return united(r); }
|
||||
|
||||
//!
|
||||
PIRect<Type> operator &(const PIRect<Type> & r) {return intersected(r);}
|
||||
PIRect<Type> operator&(const PIRect<Type> & r) { return intersected(r); }
|
||||
|
||||
//!
|
||||
bool operator ==(const PIRect<Type> & r) const {return (bl == r.bl && tr == r.tr);}
|
||||
bool operator==(const PIRect<Type> & r) const { return (bl == r.bl && tr == r.tr); }
|
||||
|
||||
//!
|
||||
bool operator !=(const PIRect<Type> & r) const {return (bl != r.bl || tr != r.tr);}
|
||||
bool operator!=(const PIRect<Type> & r) const { return (bl != r.bl || tr != r.tr); }
|
||||
|
||||
private:
|
||||
PIPoint<Type> bl;
|
||||
@@ -340,7 +359,7 @@ private:
|
||||
|
||||
|
||||
template<typename Type>
|
||||
PICout operator <<(PICout & s, const PIRect<Type> & v) {
|
||||
PICout operator<<(PICout & s, const PIRect<Type> & v) {
|
||||
s.saveAndSetControls(0);
|
||||
s << "Rect{" << v.bottomLeft() << ":" << v.width() << "x" << v.height() << "}";
|
||||
s.restoreControls();
|
||||
|
||||
@@ -5,22 +5,22 @@
|
||||
* \~russian Вычисление математической статистики у массива чисел
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Class for calculacing math statistic in values array
|
||||
Andrey Bychkov work.a.b@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Class for calculacing math statistic in values array
|
||||
Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 Lesser General Public License for more details.
|
||||
This program 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PISTATISTIC_H
|
||||
@@ -28,17 +28,17 @@
|
||||
|
||||
#include "pimathbase.h"
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
class PIStatistic {
|
||||
static_assert(std::is_arithmetic<T>::value, "Type must be arithmetic");
|
||||
|
||||
public:
|
||||
PIStatistic() {mean = variance = skewness = kurtosis = T();}
|
||||
|
||||
PIStatistic() { mean = variance = skewness = kurtosis = T(); }
|
||||
|
||||
static T calculateMean(const PIVector<T> & val) {
|
||||
T ret = T();
|
||||
int n = val.size();
|
||||
if (n < 1)
|
||||
return ret;
|
||||
if (n < 1) return ret;
|
||||
for (int i = 0; i < n; i++)
|
||||
ret += val[i];
|
||||
return ret / n;
|
||||
@@ -46,26 +46,24 @@ public:
|
||||
bool calculate(const PIVector<T> & val, const T & given_mean) {
|
||||
T v = T(), v1 = T(), v2 = T(), stddev = T(), var = T();
|
||||
int i, n = val.size();
|
||||
if (n < 2)
|
||||
return false;
|
||||
mean = given_mean;
|
||||
if (n < 2) return false;
|
||||
mean = given_mean;
|
||||
variance = skewness = kurtosis = T();
|
||||
// Variance (using corrected two-pass algorithm)
|
||||
for (i = 0; i < n; i++)
|
||||
v1 += sqr(val[i] - mean);
|
||||
for (i = 0; i < n; i++)
|
||||
v2 += val[i] - mean;
|
||||
v2 = sqr(v2) / n;
|
||||
v2 = sqr(v2) / n;
|
||||
variance = v1 / n;
|
||||
var = (v1 / n - v2) / (n - 1);
|
||||
if (var < T())
|
||||
var = T();
|
||||
var = (v1 / n - v2) / (n - 1);
|
||||
if (var < T()) var = T();
|
||||
stddev = sqrt(var);
|
||||
// Skewness and kurtosis
|
||||
if (stddev != T()) {
|
||||
for (i = 0; i < n; i++) {
|
||||
v = (val[i] - mean) / stddev;
|
||||
v2 = sqr(v);
|
||||
v = (val[i] - mean) / stddev;
|
||||
v2 = sqr(v);
|
||||
skewness = skewness + v2 * v;
|
||||
kurtosis = kurtosis + sqr(v2);
|
||||
}
|
||||
@@ -74,8 +72,8 @@ public:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool calculate(const PIVector<T> & val) {return calculate(val, calculateMean(val));}
|
||||
|
||||
bool calculate(const PIVector<T> & val) { return calculate(val, calculateMean(val)); }
|
||||
|
||||
T mean;
|
||||
T variance;
|
||||
T skewness;
|
||||
|
||||
Reference in New Issue
Block a user