mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
ScatterDraw: Some improvements in FFT
git-svn-id: svn://ultimatepp.org/upp/trunk@10145 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
d6c3e2336f
commit
0818a3d81c
3 changed files with 74 additions and 16 deletions
|
|
@ -169,10 +169,12 @@ Vector<Pointf> DataSource::MovingAverage(Getdatafun getdataY, Getdatafun getdata
|
|||
for (j = i+1; j < GetCount(); ++j) {
|
||||
double ynext = Membercall(getdataY)(j);
|
||||
double xnext = Membercall(getdataX)(j);
|
||||
if (IsNull(xnext) || IsNull(ynext))
|
||||
if (IsNull(xnext))
|
||||
continue;
|
||||
if ((xnext - x) > width_2)
|
||||
if ((xnext - x) > width_2)
|
||||
break;
|
||||
if (IsNull(ynext))
|
||||
continue;
|
||||
sum += ynext;
|
||||
numAvg++;
|
||||
}
|
||||
|
|
@ -183,6 +185,42 @@ Vector<Pointf> DataSource::MovingAverage(Getdatafun getdataY, Getdatafun getdata
|
|||
return ret;
|
||||
}
|
||||
|
||||
Vector<Pointf> DataSource::SectorAverage(Getdatafun getdataY, Getdatafun getdataX, double width) {
|
||||
Vector<Pointf> ret;
|
||||
|
||||
for (int i = 0; i < GetCount();) {
|
||||
double y = Membercall(getdataY)(i);
|
||||
double x = Membercall(getdataX)(i);
|
||||
if (IsNull(x) || IsNull(y))
|
||||
continue;
|
||||
|
||||
int numAvg = 1;
|
||||
double sum = y;
|
||||
double sumX = x;
|
||||
int j;
|
||||
for (j = i+1; j < GetCount(); ++j) {
|
||||
double ynext = Membercall(getdataY)(j);
|
||||
double xnext = Membercall(getdataX)(j);
|
||||
if (IsNull(xnext))
|
||||
continue;
|
||||
if ((xnext - x) > width) {
|
||||
--j;
|
||||
break;
|
||||
}
|
||||
if (IsNull(ynext))
|
||||
continue;
|
||||
sumX += xnext;
|
||||
sum += ynext;
|
||||
numAvg++;
|
||||
}
|
||||
ret << Pointf(sumX/numAvg, sum/numAvg);
|
||||
if (j == GetCount())
|
||||
break;
|
||||
i = j+1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DataSource::ZeroCrossing(Getdatafun getdataY, Getdatafun getdataX, bool ascending, bool descending,
|
||||
Vector<double> &zeros, Vector<int64> &ids) {
|
||||
zeros.Clear();
|
||||
|
|
@ -270,7 +308,7 @@ double CArray::znFixed(int n, int64 id) {
|
|||
}
|
||||
|
||||
|
||||
Vector<Pointf> DataSource::FFT(Getdatafun getdata, double tSample, bool frequency, bool phase) {
|
||||
Vector<Pointf> DataSource::FFT(Getdatafun getdata, double tSample, bool frequency, int type, bool window) {
|
||||
int numData = int(GetCount());
|
||||
VectorXd timebuf(numData);
|
||||
int num = 0;
|
||||
|
|
@ -286,6 +324,16 @@ Vector<Pointf> DataSource::FFT(Getdatafun getdata, double tSample, bool frequenc
|
|||
return res;
|
||||
timebuf.resize(num);
|
||||
|
||||
double windowSum = 0;
|
||||
if (window) {
|
||||
for (int i = 0; i < numData; ++i) {
|
||||
double windowDat = 0.54 - 0.46*cos(2*M_PI*i/numData);
|
||||
windowSum += windowDat;
|
||||
timebuf[i] *= windowDat; // Hamming window
|
||||
}
|
||||
} else
|
||||
windowSum = numData;
|
||||
|
||||
VectorXcd freqbuf;
|
||||
try {
|
||||
Eigen::FFT<double> fft;
|
||||
|
|
@ -298,19 +346,21 @@ Vector<Pointf> DataSource::FFT(Getdatafun getdata, double tSample, bool frequenc
|
|||
for (int i = 0; i < int(freqbuf.size()); ++i) {
|
||||
double xdata = i/(tSample*numData);
|
||||
|
||||
if (phase)
|
||||
res << Pointf(xdata, std::arg(freqbuf[i]));
|
||||
else
|
||||
res << Pointf(xdata, 2*std::abs(freqbuf[i])/numData);
|
||||
switch (type) {
|
||||
case T_PHASE: res << Pointf(xdata, std::arg(freqbuf[i])); break;
|
||||
case T_FFT: res << Pointf(xdata, 2*std::abs(freqbuf[i])/windowSum); break;
|
||||
case T_PSD: res << Pointf(xdata, 2*sqr(std::abs(freqbuf[i]))/(windowSum/tSample));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = int(freqbuf.size()); i > 0; --i) {
|
||||
for (int i = int(freqbuf.size()) - 1; i > 0; --i) {
|
||||
double xdata = (tSample*numData)/i;
|
||||
|
||||
if (phase)
|
||||
res << Pointf(xdata, std::arg(freqbuf[i]));
|
||||
else
|
||||
res << Pointf(xdata, 2*std::abs(freqbuf[i])/numData);
|
||||
switch (type) {
|
||||
case T_PHASE: res << Pointf(xdata, std::arg(freqbuf[i])); break;
|
||||
case T_FFT: res << Pointf(xdata, 2*std::abs(freqbuf[i])/windowSum); break;
|
||||
case T_PSD: res << Pointf(xdata, 2*sqr(std::abs(freqbuf[i]))/(windowSum/tSample));
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -48,11 +48,14 @@ public:
|
|||
virtual Vector<int64> UpperEnvelopeY(double width) {return UpperEnvelope(&DataSource::y, &DataSource::x, width);}
|
||||
virtual Vector<int64> LowerEnvelopeY(double width) {return LowerEnvelope(&DataSource::y, &DataSource::x, width);}
|
||||
virtual Vector<Pointf> MovingAverageY(double width) {return MovingAverage(&DataSource::y, &DataSource::x, width);}
|
||||
virtual Vector<Pointf> SectorAverageY(double width) {return SectorAverage(&DataSource::y, &DataSource::x, width);}
|
||||
virtual void ZeroCrossingY(bool ascending, bool descending, Vector<double> &zeros, Vector<int64> &ids) {
|
||||
return ZeroCrossing(&DataSource::y, &DataSource::x, ascending, descending, zeros, ids);}
|
||||
|
||||
Upp::Vector<Pointf> FFTY(double tSample, bool frequency = false, bool phase = false) {
|
||||
return FFT(&DataSource::y, tSample, frequency, phase);}
|
||||
|
||||
enum FFT_TYPE {T_FFT = 0, T_PHASE, T_PSD};
|
||||
|
||||
Upp::Vector<Pointf> FFTY(double tSample, bool frequency = false, int type = FFT_TYPE::T_FFT, bool window = false) {
|
||||
return FFT(&DataSource::y, tSample, frequency, type, window);}
|
||||
|
||||
double Min(Getdatafun getdata, int64& id);
|
||||
double Max(Getdatafun getdata, int64& id);
|
||||
|
|
@ -63,11 +66,13 @@ public:
|
|||
Vector<int64> UpperEnvelope(Getdatafun getdataY, Getdatafun getdataX, double width);
|
||||
Vector<int64> LowerEnvelope(Getdatafun getdataY, Getdatafun getdataX, double width);
|
||||
Vector<Pointf> MovingAverage(Getdatafun getdataY, Getdatafun getdataX, double width);
|
||||
Vector<Pointf> SectorAverage(Getdatafun getdataY, Getdatafun getdataX, double width);
|
||||
void ZeroCrossing(Getdatafun getdataY, Getdatafun getdataX, bool ascending, bool descending,
|
||||
Vector<double> &zeros, Vector<int64> &ids);
|
||||
double SinEstim_Amplitude(double avg = Null);
|
||||
bool SinEstim_FreqPhase(double &frequency, double &phase, double avg = Null);
|
||||
Vector<Pointf> FFT(Getdatafun getdata, double tSample, bool frequency = false, bool phase = false);
|
||||
Vector<Pointf> FFT(Getdatafun getdata, double tSample, bool frequency = false,
|
||||
int type = FFT_TYPE::T_FFT, bool window = false);
|
||||
|
||||
protected:
|
||||
bool isParam, isExplicit;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,9 @@ EvalExpr::EvalExpr() {
|
|||
functions.Add("sinh", sinh);
|
||||
functions.Add("cosh", cosh);
|
||||
functions.Add("tanh", tanh);
|
||||
functions.Add("log", log);
|
||||
functions.Add("log10", log10);
|
||||
functions.Add("exp", exp);
|
||||
functions.Add("degToRad", degToRad);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue