MFCC: What are the frequency ranges of the 20 filter banks in Librosa MFCC? - frequency

In Librosa library, When we use librosa.feature.mfcc(y, sr), it returns a (20, ?) numpy array.
How do I check the frequency range of the 20 filter-banks that are returned?

MFCC does not return filterbank values, it transforms them with DCT, so you do not have frequency range for every value, it is more an abstract coefficient.
If you want to print filterbank frequencies during MFCC calculation you can easily use debugger or additional print statements inside librosa code, it is scripting language, so you will see the result right away.

Related

2d filter that do not cross a line

I want to preform some kind of smoothing filtering with numpy or scipy(or any other python package) on my 2d data set(2d median filter for example) but I don't want the filtering kernel to cross some arbitrary line in my data set.
A Toy example for the data set will look something like:
Essentially I don't want the filter to mix between the positive and negative values across the black line in the toy example. In the general problem the data can contain multiple lines and the lines can have any orientation or length.
I would appreciate any solution or suggestions

numpy: Different results between diff and gradient for finite differences

I want to calculate the numerical derivative of two arrays a and b.
If I do
c = diff(a) / diff(b)
I get what I want, but I loose the edge (the last point) so c.shape ~= a.shape.
If I do
c = gradient(a, b)
then c.shape = a.shape, but I get a completely different result.
I have read how gradient is calculated in numpy and I guess it does a completely different thing, although I dont understand quite well the difference yet. But is there a way or another function to calculate the differential which also gives the values at the edges?
And why is the result so different between gradient and diff?
These functions, although related, do different actions.
np.diff simply takes the differences of matrix slices along a given axis, and used for n-th difference returns a matrix smaller by n along the given axis (what you observed in the n=1 case). Please see: https://docs.scipy.org/doc/numpy/reference/generated/numpy.diff.html
np.gradient produces a set of gradients of an array along all its dimensions while preserving its shape https://docs.scipy.org/doc/numpy/reference/generated/numpy.gradient.html Please also observe that np.gradient should be executed for one input array, your second argument b does not make sense here (was interpreted as first non-keyword argument from *varargs which is meant to describe spacings between the values of the first argument), hence the results that don't match your intuition.
I would simply use c = diff(a) / diff(b) and append values to c if you really need to have c.shape match a.shape. For instance, you might append zeros if you expect the gradient to vanish close to the edges of your window.

Create data bins in LabVIEW

I've got the following task: there are two outputs from DAQ, namely speed and the raw data acquired along with this speed. I'd like to use speed as a parameter to define certain number of bins, and fit the raw data which corresponds to the speed into the specific bin. I am not sure how to do this in LabVIEW - because when I check the histogram function, it seems that it only requires one input (1D array of values).
Many thanks, any help is much appreciated. Aileen
The Histogram VI takes an array of data and the number of bins you want, and determines the boundaries of the bins automatically. It sounds like that's the one you're looking at.
The General Histogram VI allows you to specify the bins yourself. If you can't find it, perhaps you only have the LabVIEW Base Package development system, as it's only present in the Full Development System and above.
If you don't have General Histogram and you need to create a histogram using your own bin boundaries, it wouldn't be too hard to create. Without writing the code for you, you could do something like:
Create a 1D array containing your bin boundaries in ascending order.
Use a For loop to index through the array of bin boundaries
In the loop, use (e.g.) >, <=, and And functions to get a Boolean array which contains True for each value in the data array that should be in the current bin
Use Boolean to (0,1) and Add Array Elements to count the number of True values.
If any of that's unclear, please edit your question with more details and perhaps an example of some input data and what you want the output to be.
This is an implementation of nekomatic's description.
The first SubVi just creates the 1D array containing your bin boundaries.
X_in and Y_in are the independent and dependent input datasets. Both have to be of equal length but must not be sorted. In the inner For loop it will be checked if X_in fits into the current bin. If so, X_in and the corresponding Y_in value are stored in a temporary arrays which are averaged afterwards.
Maybe it is not the most efficient code but at least it seems to be not slower than the General Histogram VI

How to specify the number of knot points when using scipy.splprep

I have the following piece of code. It generates the 3-D cubic spline of the given 3-D function given in parametric form. I pretty much adapted this to my case using the online documentation for splprep and splev.
But I have some things I don't understand. Here is the code:
%matplotlib inline
from numpy import arange, cos, linspace, pi, sin, random
from scipy.interpolate import splprep, splev
import matplotlib.pyplot as plt
# make ascending spiral in 3-space
t=linspace(0,1.75*2*pi,100)
x = sin(t)
y = cos(t)
z = t
# spline parameters
s=3.0 # smoothness parameter
k=3 # spline order
nest=-1 # estimate of number of knots needed (-1 = maximal)
# find the knot points
tck,u = splprep([x,y,z],s=s,k=k,nest=-1)
# evaluate spline, including interpolated points
xnew,ynew,znew = splev(linspace(0,1,400),tck)
I have a few questions regarding this implementation.
What exactly does the (t,c,k) tuple return in this case?. I read the documentation and it says it returns the knot points, the coefficients and the degree of the spline. Doesn't knot points have to be coordinates of the form (x, y, z)?. So we have to have "number of knots" such coordinate points. But that's not what gets returned. We simply get returned an array of length 11.
What does u return? (Documentation says it returns the values of the parameter. What does that mean?. The values of the parameter t?
When I use nest = -1 (This is the default) it uses the maximal number of knot points needed (in this case they use 11 knot points). But how do I specify my own number of knot points, let's say 50 or 80 etc?
I am completely misunderstanding the documentation here. Can someone enlighten me may be using examples?
Values of parameter, u
The idea is that your points [x,y,z] are values of some parameterized curve, the original parameter being t in your example. Knowing the values of the parameter t helps in figuring out how to interpolate between these points. For this reason, you are given an option to pass the values of parameter as optional argument u (it would be u=t in this example). But if you choose not to do so, the method will make a guess for the values of the parameter, based on the distances between given points (the parameter interval will be from 0 to 1). This guess is then returned to you as variable u, so you know how the data was interpreted. If you do pass u=t as the argument, the u you get back is exactly the same.
You don't really need this u to use the spline. However, if it is desirable to compare the location of original [x,y,z] points to the values of the spline, then you may want to pass u as an argument to splev. A shorter way to explain the meaning of u is: it's what splev would need to reproduce the [x,y,z] coordinates that you started with, with some deviations due to smoothing.
tck values
The knots of a spline, t, are the points in the parameter interval, not in the 3D space. Since in your example the parameter interval is [0,1], chosen by default, the values of t are in this range. A knot is a place on the parameter interval where some coefficients of the spline change. The endpoints 0 and 1 are technically multiple knots, so they are listed several times.
The 3D nature of the curve is expressed by coefficients c. You may notice it's a list of three arrays, one for each coordinate.
Number of knot points
With this interpolation routine, you have two choices:
tell it exactly what the knot points are (by giving task=-1 and providing t argument with the knots). To avoid confusion: this t is not necessarily the t from which you got the points [x,y,z]. One doesn't necessarily want every sample point to be a knot point.
leave the determination of the knots up to the routine, including their number.
However, the number of knots depends on the value of smoothness parameter s, so it can be influenced indirectly. For example, with your data there are 11 knots with s=3, but 12 knots with s=1 and 14 knots with s=0.1.

Numpy inaccurate matrix inverse

I have been getting seemingly unacceptably high inaccuracies when computing matrix inverses (solving a linear system) in numpy.
Is this a normal level of inaccuracy?
How can I improve the accuracy of this computation?
Also, is there a way to solve this system more efficiently in numpy or scipy (scipy.linalg.cho_solve seemed promising but does not do what I want)?
In the code below, cholM is a 128 x 128 matrix. The matrix data is too large to include here but is located on pastebin: cholM.txt.
Also, the original vector, ovec, is being randomly selected, so for different ovec's the accuracy varies, but, for most cases, the error still seems unacceptably high.
Edit Solving the system using the singular value decomposition produces significantly lower error than the other methods.
import numpy.random as rnd
import numpy.linalg as lin
import numpy as np
cholM=np.loadtxt('cholM.txt')
dims=len(cholM)
print 'Dimensions',dims
ovec=rnd.normal(size=dims)
rvec=np.dot(cholM.T,ovec)
invCholM=lin.inv(cholM.T)
svec=np.dot(invCholM,rvec)
svec1=lin.solve(cholM.T,rvec)
def back_substitute(M,v):
r=np.zeros(len(v))
k=len(v)-1
r[k]=v[k]/M[k,k]
for k in xrange(len(v)-2,-1,-1):
r[k]=(v[k]-np.dot(M[k,k+1:],r[k+1:]))/M[k,k]
return r
svec2=back_substitute(cholM.T,rvec)
u,s,v=lin.svd(cholM)
svec3=np.dot(u,np.dot(np.diag(1./s),np.dot(v,rvec)))
for k in xrange(dims):
print '%20.3f%20.3f%20.3f%20.3f'%(ovec[k]-svec[k],ovec[k]-svec1[k],ovec[k]-svec2[k],ovec[k]-svec3[k])
assert np.all( np.abs(ovec-svec)<1e-5 )
assert np.all( np.abs(ovec-svec1)<1e-5 )
As noted by #Craig J Copi and #pv, the condition number of the cholM matrix is high, around 10^16, indicating that to achieve higher accuracy in the inverse, much greater numerical precision may be required.
Condition number can be determined by the ratio of maximum singular value to minimum singular value. In this instance, this ratio is not the same as the ratio of eigenvalues.
http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html
We could find the solution vector using a matrix inverse:
...
However, it is better to use the linalg.solve command which can be faster and more numerically stable
edit - from Steve Lord at MATLAB
http://www.mathworks.com/matlabcentral/newsreader/view_thread/63130
Why are you inverting? If you're inverting to solve a system, don't --
generally you would want to use backslash instead.
However, for a system with a condition number around 1e17 (condition numbers
must be greater than or equal to 1, so I assume that the 1e-17 figure in
your post is the reciprocal condition number from RCOND) you're not going to
get a very accurate result in any case.