Matlab's `mdwtdec()` Vs Python's `wavedec()` - wavelet

I am trying to convert a Matlab code into Python. To do a Multisignal 1-D wavelet decomposition I use mdwtdec() in Matlab. The closest function I found in python is in pywt lib, wavedec().
While the matlab function take 4 arguments mdwtdec(DIRDEC,X,LEV,WNAME): here X is the signal, LEV is the level, WNAME is the wavelet name and DIRDEC is Direction indicator: r (row) or c (column).
mdwtdec(DIRDEC,X,LEV,WNAME) returns the wavelet decomposition at level LEV of each row (if DIRDEC = r) or each column (if DIRDEC = c) of matrix X, using the wavelet WNAME.
In pywavelets, wavedec(X,LEV,WNAME) takes X, LEV and WNAME similar to Matlab. There is no option for the direction, so by default it is set to 'r'. I need 'c' as an option too, How do I achieve it in Python?

pywt's wavedec assumes that the signal is an array. If the signal isn't an array, then the results are less convincing (for square matrices the result appears to correspond to a rowwise operation, but the same cannot be said for non-square matrices).
Fortunately you can run wavedec for each row or column using numpy's apply_along_axis. With a little bit of extra wrapping, you can define a Matlab approximation (Matlab's version probably has better error handling) to mdwtdec such as:
import pywt
import numpy as np
def mdwtdec(dirdec,x,lev,wavelet):
"""
Multisignal 1D Discrete Wavelet decomposition.
Parameters
----------
dirdec : char
Direction indicator: 'r' (row) or 'c' (column)
x : matrix
Input matrix
wavelet : Wavelet object or name string
Wavelet to use
lev : int
Decomposition level (must be >= 0). If level is None then it
will be calculated using the ``dwt_max_level`` function.
"""
return np.apply_along_axis(
lambda y: np.concatenate(pywt.wavedec(y, wavelet, level=lev)),
axis={'c':0, 'r':1}[dirdec], arr=x)
in which I've used:
np.concatenate to keep the approximation and details coefficients as a tight row/column vector
a lambda expression to specify the executed function along with the mapping of input arguments

Related

How to use eigen to rewrite numpy's array comparing function

I have a piece of numpy code.
distance = np.ones((N,)) * 1e10
mask = dist < distance
distance[mask] = dist[mask]
l think the distance and dist is a array.through comparing the value of distance and dist,I want to find a smaller value and store that in distance.
In c++,I can only do this with a for loop.Does eigen have a function to implement this operation.thanks!!
I can only do this with a for loop. I hope to find a function of eigen to implement this operation.

Extract first N columns of Q from `ColPivHouseholderQR`

I am trying to implement canonical correlation analysis in C++ using the Eigen linear algebra library.
Part of the algorithm involves QR decomposition using the column pivot method. For that piece I am using the ColPivHouseholderQR class. This class contains an object of type HouseholderSequenceType which I would like to use to extract only the first N columns of the matrix rather than the entire Q matrix.
The full Q matrix has as many columns as rows and quickly fills memory for even modest dataset sizes. Furthermore, I don't need the full matrix, but just a subset of the first N columns.
How can I extract only the first N columns from this object?
My code:
// Set up the class and compute the QR decomposition
Eigen::ColPivHouseholderQR< Eigen::MatrixXd > qr;
qr.setThreshold(threshold);
qr.compute(mat);
int rk = qr.rank();
Eigen::ColPivHouseholderQR< Eigen::MatrixXd >::HouseholderSequenceType seq = qr.householderQ();
seq.setLength(rk);
// return the matrix
return (Eigen::MatrixXd) seq;

sparse sparse product A^T*A optim in Eigen lib

In the case of multiple of same matrix matA, like
matA.transpose()*matA,
You don't have to compute all result product, because the result matrix is symmetric(so only if the m>n), in my specific case is always symmetric! square.
So its enough the compute only for. ex. lower triangular part and rest only copy..... because the results of the multiple 2nd and 3rd row, resp.col, is the same like 3rd and 2nd.....And etc....
So my question is , exist way how to tell Eigen, to compute only lower part. and optionally save to only lower trinaguler part the product?
DATA = SparseMatrix<double>((SparseMatrix<double>(matA.transpose()) * matA).pruned()).toDense();
According to the documentation, you can evaluate the lower triangle of a matrix with:
m1.triangularView<Eigen::Lower>() = m2 + m3;
or in your case:
m1.triangularView<Eigen::Lower>() = matA.transpose()*matA;
(where it says "Writing to a specific triangular part: (only the referenced triangular part is evaluated)"). Otherwise, in the line you've written
Eigen will calculate the entire sparse matrix matA.transpose()*matA.
Regarding saving the resulting m1 matrix, it is the same as saving whatever type of matrix it is (Eigen::MatrixXt or Eigen::SparseMatrix<t>). If m1 is sparse, then it will be only half the size of a straightforward matA.transpose()*matA. If m1 is dense, then it will be the full square matrix.
https://eigen.tuxfamily.org/dox/classEigen_1_1SparseSelfAdjointView.html
The symmetric rank update is defined as:
B = B + alpha * A * A^T
where alpha is a scalar. In your case, you are doing A^T * A, so you should pass the transposed matrix instead. The resulting matrix will only store the upper or lower portion of the matrix, whichever you prefer. For example:
SparseMatrix<double> B;
B.selfadjointView<Lower>().rankUpdate(A.transpose());

Python: Solving equation system (coefficients are arrays)

I can solve a system equation (using NumPY) like this:
>>> a = np.array([[3,1], [1,2]])
>>> b = np.array([9,8])
>>> y = np.linalg.solve(a, b)
>>> y
array([ 2., 3.])
But, if I got something like this:
>>> x = np.linspace(1,10)
>>> a = np.array([[3*x,1-x], [1/x,2]])
>>> b = np.array([x**2,8*x])
>>> y = np.linalg.solve(a, b)
It doesnt work, where the matrix's coefficients are arrays and I want calculate the array solution "y" for each element of the array "x". Also, I cant calculate
>>> det(a)
The question is: How can do that?
Check out the docs page. If you want to solve multiple systems of linear equations you can send in multiple arrays but they have to have shape (N,M,M). That will be considered a stack of N MxM arrays. A quote from the docs page below,
Several of the linear algebra routines listed above are able to compute results for several matrices at once, if they are stacked into the same array. This is indicated in the documentation via input parameter specifications such as a : (..., M, M) array_like. This means that if for instance given an input array a.shape == (N, M, M), it is interpreted as a “stack” of N matrices, each of size M-by-M. Similar specification applies to return values, for instance the determinant has det : (...) and will in this case return an array of shape det(a).shape == (N,). This generalizes to linear algebra operations on higher-dimensional arrays: the last 1 or 2 dimensions of a multidimensional array are interpreted as vectors or matrices, as appropriate for each operation.
When I run your code I get,
>>> a.shape
(2, 2)
>>> b.shape
(2, 50)
Not sure exactly what problem you're trying to solve, but you need to rethink your inputs. You want a to have shape (N,M,M) and b to have shape (N,M). You will then get back an array of shape (N,M) (i.e. N solution vectors).

Curvature Scale Space corner detection algorithm. Arc Length Parameter?

I'm studying about the CSS algorithm and I don't get the hang of the concept of 'Arc Length Parameter'.
According to the literature, planar curve Gamma(u)=(x(u),y(u)) and they say this u is the arc length parameter and apparently, Gaussian Kernel g is also parameterized by this u here.
Stop me if I got something wrong but, aren't x and y location of the pixel? How is it represented by another parameter?
I had no idea when I first saw it on the literature so, I looked up the code. and apparently, I got puzzled even more.
here is the portion of the code
void getGaussianDerivs(double sigma, int M, vector<double>& gaussian,
vector<double>& dg, vector<double>& d2g) {
int L = (M - 1) / 2;
double sigma_sq = sigma * sigma;
double sigma_quad = sigma_sq*sigma_sq;
dg.resize(M); d2g.resize(M); gaussian.resize(M);
Mat_<double> g = getGaussianKernel(M, sigma, CV_64F);
for (double i = -L; i < L+1.0; i += 1.0) {
int idx = (int)(i+L);
gaussian[idx] = g(idx);
// from http://www.cedar.buffalo.edu/~srihari/CSE555/Normal2.pdf
dg[idx] = (-i/sigma_sq) * g(idx);
d2g[idx] = (-sigma_sq + i*i)/sigma_quad * g(idx);
}
}
so, it seems the code uses simple 1D Gaussian Kernel Aperture size of M and it is trying to compute its 1st and 2nd derivatives. As far as I know, 1D Gaussian kernel has parameter of x which is a horizontal coordinate and sigma which is scale. it seems like that 'arc length parameter u' is equivalent to the variable of x. That doesn't make any sense because later in the code, it directly convolutes the set of x and y on the contour.
what is this u?
PS. since I replied to the fellow who tried to answer my question, I think I should modify my question, so, here we go.
What I'm confusing is, how is this parameter 'u' implemented in codes? I think I understood the full code above -of course, I inserted only a portion of the code- but the problem is, I have no idea about what it would be for the 'improved' version of the algorithm. It says it's using 'affine length parameter' instead of this 'arc length parameter' and I'm not so sure how I implement the concept into the code.
According to the literature, the main difference between arc length parameter and affine length parameter is it's sampling interval and arc length parameter uses 1 for the vertical and horizontal direction and root of 2 for the diagonal direction. It makes sense since the portion of the code above is using for loop to compute 1st and 2nd derivatives of the 1d Gaussian and it directly inserts the value of interval 1 but, how is it gonna be with different interval with different variable? Is it possible that I'm not able to use 'for loop' for it?