How can I rewrite MATLAB pmtm function in Mathematica or C# (.NET 4.0)?
I am using pmtm in this way:
[p,f] = pmtm(data,tapers,n,fs);
Alternatively written without pmtm using spectrum.mtm and psd.
Hs = spectrum.mtm(tapers,'adapt');
powerspectrum = psd(Hs,data,'Fs',fs,'NFFT',n);
p = powerspectrum.data;
f = powerspectrum.Frequencies;
Where data is a column vector with 2048 elements, fs = 40, tapers = 8 and n = 2^nextpow2(size(data,1)) = 2048;
Thanks.
The pmtm (multitaper method) is a non-parametric method for computing a power spectrum similar to the periodogram approach.
In this method a power spectrum is computed by windowing the data and computing a Fourier transform, taking the magnitude of the result and squaring it. The multitaper method averages a pre-determined number of periodograms each computed with a different window. This method works because the selected windows have two mathematical properties. First, the windows are orthogonal. This means that each one of the periodograms is uncorrelated so averaging multiple periodograms gives an estimate with a lower variance than using just one taper. Second, the windows have the best possible concentration in the frequency domain for a fixed signal length. This means that these windows perform the best possible with respect to leakage.
Mathematica has package for time series that contains funtions like PowerSpectralDensity.
If you have further problems ask your question in https://mathematica.stackexchange.com/
Related
I'll introduce my question using a concrete example. The actual question is at the bottom of this text.
Introduction
I'd like to extract some unaligned data from byte arrays where given are
the start bit position
the number of bits
whether the data is MSB-first (big endian) or LSB-first (little endian) format
For that I created a Bitpacker class that offers a static method
ulong ReadRaw(byte[] src, int startBit, int bitLength, Endianness endianness = Endianness.LSB_FIRST)
This method of course has to do some computation to get the desired bits out of the bytes using loops etc. which is slow. I need to evaluate the data on the order of multiple thousand times per second.
Because the arguments are compile-time known constants I could hard-code a fast variant by manually finding what bits to extract and how to shift them.
E.g. the following two assigments to raw do the same:
ulong raw;
// Manually extract bits
raw = ((ulong)(src[5] & 0xFC) >> 2) + ((ulong)(src[6] & 0x3) << 6);
// Use the slow generic implementation
raw = Bitpacker.ReadRaw(src,42,8, Endianness.LSB_FIRST);
Hard-coding of course makes it difficult to write correct code and significantly decreases code-maintainability. That's where I thought that source-generators could come into play.
The actual question
Is it possible to use the source generator feature to somehow generate different code for each call to ReadRaw based on the constant arguments or is it possible to replace the calls to ReadRaw altogether using source generators?
I've been using an int in my code to define a horizontal direction. This is so I could use it in my movement code (eg. position.x += speed * direction). Before this I had been using a bool, but that needed if statement to see if speed was a pos/neg value.
But I was just thinking, well this uses now a byte (or 4 in my instance, Unity int32) rather than just one bit.
I know you can cast a bool to int for example but is there a way to store my direction value and use it in the formula like above but only being one bit?
I am using Unity and C#. I realise this is not very important, but just trying to learn if this possible or not.
Note that modern machines fetch the data as a block of bytes called word, it may be 4 bytes or 8 bytes depending on the architecture.
You can store one bit of information by bit-wise operators but it can only be useful if you multiple bits to pack into one word or byte.
So, if you want to store the direction as a boolean (1 bit of information) then you will have to use if-else statements.
Otherwise, you can't represent the sign as well as the absolute value in just one bit!
I am using Cudafy to do some calculations on a NVIDIA GPU.
(Quadro K1100M capability 3.0, if it matters)
My question is, when I use the following
cudaGpu.Launch(new dim3(44,8,num), new dim(8, 8)).MyKernel...
why are my z indexes from the GThread instance always zero when I use this in my kernel?
int z = thread.blockIdx.z * thread.blockDim.z + thread.threadIdx.z;
Furthermore, if I have to do something like
cudaGpu.Launch(new dim3(44,8,num), new dim(8, 8, num)).MyKernel...
z does give different indexes as it should, but num can't be very large because of the restrictions on number of threads per block. Any surgestion on how to work around this?
Edit
Another way to phrase it. Can I use thread.z in my kernel (for anything useful) when block size is only 2D?
On all currently supported hardware, CUDA allows the use of both three dimensional grids and three dimensional blocks. On compute capability 1.x devices (which are no longer supported), grids were restricted to two dimensions.
However, CUDAfy currently uses a deprecated runtime API function to launch kernels, and silently uses only gridDim.x and gridDim.y, not taking gridDim.z in account :
_cuda.Launch(function, gridSize.x, gridSize.y);
As seen in the function DoLaunch() in CudaGPU.cs.
So while you can specify a three dimensional grid in CUDAfy, the third dimension is ignored during the kernel launch. Thanks to Florent for pointing this out !
I am VERY new in the world of DSP and filtering. Like I started a week ago. Anyway, I have been looking for ways to use filters (low-pass, high-pass, notch, etc.) on some data I am getting. The data comes in an array of doubles and I can get more than 1 million points in this array. I am trying to filter out sound given a certain cutoff frequency but cannot get any algorithm to work. I have been up and down the internet and tried a bunch of different libraries and methods but I can't get any results. I am partial to the NAudio library because it seems to have everything I need (FFT and filtering by the BiQuadFilter class). I am pretty sure my problem is my extreme lack of the knowledge and math to get the desired output. Judging from what I have read, here is how I believe the process should go:
Insert data into FFT to put data into frequency domain
Pass resulting data into a filter (low, high, notch)
Do IFFT from results in step 2 to get back into time domain
Play sound
Is this the right way to filter audio? Can I shove the entire array into the FFT or do I have to break it up in smaller chunks? What do I do with the complex numbers that I get in the FFT result (ie just use the real part and throw away the imaginary, or use the magnitude and phase)? I really have no idea what the "right way" is.
EDIT
I finally got it working! Here is what I did:
byte[] data = doubleArray.SelectMany(value => BitConverter.GetBytes(value)).ToArray();
wms = new WaveMemoryStream(data, sampleRate, (ushort)audioBitsPerSample, (ushort)channels);
WaveFileReader wfr = new WaveFileReader(wms);
SampleChannel sample = new SampleChannel(wfr, false);
LowPassSampleProvider sampleProvider = new LowPassSampleProvider(sample);
WaveOutEvent player = new WaveOutEvent();
player.Init(sampleProvider);
player.Play();
doubleArray is the array of my accelerometer data, which currently holds 1 million points with each one somewhere around 1.84...
WaveMemoryStream is a class I found on another post here
LowPassSampleProvider is a class I made that implements ISampleProvider and passes the samples to the BiQuadFilter.LowPassFilter function.
The BiQuadFilter in NAudio operates in the time domain. You don't need to use FFT with it. Pass each sample into the Transform method to get the output sample. Use two filters one for left and one for right if you have stereo audio.
I typically make an ISampleProvider implementation that in the Read method reads from a source ISampleProvider (such as an AudioFileReader) and passes the samples through the filter.
Typically you would run the time domain data through a time domain filter. Another method, which is equivalent, is to take the FFT of the data and the FFT of the filter, multiply it in the frequency domain, then take the inverse FFT. For small filters the time domain approach is generally faster. You would typically do this on frames of the data, say 8192 samples passed through a filter. Then repeat for subsequent frames. Without looking at your code I'm unable to provide more help. Also, take a look at these examples using Intel's IPP. There's both time and frequency domain implementations that should help to get you going.
I have a very large two dimensional array and I need to compute vector operations on this array. NTerms and NDocs are both very large integers.
var myMat = new double[NTerms, NDocs];
I need to to extract vector columns from this matrix. Currently, I'm using for loops.
col = 100;
for (int i = 0; i < NTerms; i++)
{
myVec[i] = myMat[i, col];
}
This operation is very slow. In Matlab I can extract the vector without the need for iteration, like so:
myVec = myMat[:,col];
Is there any way to do this in C#?
There are no such constructs in C# that will allow you to work with arrays as in Matlab. With the code you already have you can speed up process of vector creation using Task Parallel Library that was introduced in .NET Framework 4.0.
Parallel.For(0, NTerms, i => myVec[i] = myMat[i, col]);
If your CPU has more than one core then you will get some improvement in performance otherwise there will be no effect.
For more examples of how Task Parallel Library could be used with matrixes and arrays you can reffer to the MSDN article Matrix Decomposition.
But I doubt that C# is a good choice when it comes to some serious math calculations.
Some possible problems:
Could it be the way that elements are accessed for multi-dimensional arrays in C#. See this earlier article.
Another problem may be that you are accessing non-contiguous memory - so not much help from cache, and maybe you're even having to fetch from virtual memory (disk) if the array is very large.
What happens to your speed when you access a whole row at a time, instead of a column? If that's significantly faster, you can be 90% sure it's a contiguous-memory issue...