QR decomposition implementation in maple - maple

The QR algorithm should converge to the Eigenvalues of the input matrix A, after several iterations, but in my case it doesn't. I want to use the Eigenvalues to find singular values, hence the input. I want to do this, without any built in functions.
restart:
with(LinearAlgebra):
B := RandomMatrix(3);
B := BidiagonalForm(B);
A := evalf(Matrix([[Matrix(3),Transpose(B)],[B,Matrix(3)]]));
C := A;
t0 := time():
for k from 1 to 300 do
Q, R := QRDecomposition(A);
A:=R.Q;
end do:
time() - t0;
Diagonal(A);
sort(%);
abs(Eigenvalues(C));
The last line is to check the solution. Thanks in advance.

Related

Identify powers in an algebraic expression for a Buckingham Pi calculation in MatLab

This is a continuation of an earlier question I asked here.
If I create a symbolic expression in MatLab
syms L M T
F = M*L/T^2
I want to identify the powers of each dimension M, L, or T. In this case, the answer should be
for M, 1
for L, 1
for T, -2
There is a relatively easy way to do this if the expression F were a polynomial in MatLab employing the coeffs function. However, my expression is clearly not a polynomial as far as MatLab is concerned.
In the end, I will be working with at least two parameters so I will put them in a cell array since I anticipate cellfun will be useful.
V = L/T
param = {F,V};
The final output should be a table where the rows correspond to each dimension, L M and T and the columns are for each parameter F and V.
syms L M T
F = M*L/T^2
[C,T] = coeffs(expand(log(F),'IgnoreAnalyticConstraints',true))
[exp(T).' C.']
It returns the table:

LDLt factorization using SciPy's Python bindings to LAPACK

I am trying to get the LDLt factorization of a given symmetric matrix with SciPy's Python bindings to LAPACK using the dsysv routine which actually solves linear systems using this matrix factorization.
I have tried the following:
import numpy as np
from scipy.linalg.lapack import dsysv
A = np.random.randint(1, 1000, size=(5, 5))
A = (A + A.T)
b = np.random.randn(5)
lult, piv, x, _ = dsysv(A, b, lower=1)
Where x would be the solution for the above linear system and lult and piv contain information about the factorization.
How can I reconstruct LDLt from it? Sometimes negative values are contained in piv and from the docs I was not able to understand their meaning.
LAPACK's sytrf actually computes this factorization (without solving any linear system) but it does not seem available via SciPy.
There is an example here with the output I am interested in (see eq. 3-23).
All the required information is found in the documentation of systrf. But admittedly, it is a somewhat verbose.
So just give me the code:
import numpy as np
from scipy.linalg.lapack import dsysv
def swapped(i, k, n):
"""identity matrix where ith row and column are swappend with kth row and column"""
P = np.eye(n)
P[i, i] = 0
P[k, k] = 0
P[i, k] = 1
P[k, i] = 1
return P
# example
n = 5
A = np.random.rand(n, n)
A = (A + A.T)
b = np.random.randn(n)
lult, piv, x, _ = dsysv(A, b, lower=1)
# reconstruct L and D
D = np.zeros_like(A, dtype=float)
L = np.eye(n)
k = 0
while k < n:
i = piv[k]
if i < 0:
s = 2
else:
s = 1
if s == 1:
i = i - 1
D[k, k] = lult[k, k] # D(k) overwrites A(k,k)
Pk = swapped(k, i, n)
v = lult[k+1:n, k] # v overwrites A(k+1:n,k)
Lk = np.eye(n)
Lk[k+1:n, k] = v
else:
m = -i - 1
D[k:k+2, k:k+2] = lult[k:k+2, k:k+2] # the lower triangle of D(k) overwrites A(k,k), A(k+1,k), and A(k+1,k+1)
D[k, k+1] = D[k+1, k] # D is symmeric
Pk = swapped(k+1, m, n)
v = lult[k+2:n, k:k+2] # v overwrites A(k+2:n,k:k+1)
Lk = np.eye(n)
Lk[k+2:n, k:k+2] = v
L = L.dot(Pk).dot(Lk)
if s == 1:
k += 1
else:
k += 2
print(np.max(np.abs(A - L.dot(D).dot(L.T)))) # should be close to 0
The snipped above reconstructs L and D from the decomposition (it would need to be adapted to reconstruct U from an UDUt decomposition). I will try to explain below. First a quote from the documentation:
... additional row interchanges are required to recover U or L explicitly (which is seldom necessary).
Reconstructing L (or U) requires a number of iterations with row exchanging operations and matrix multiplication. This is not very efficient (less so when done in Python) but luckily this reconstruction is seldom necessary. So make sure you really have to do this!
We reconstruct L from L = P(1)*L(1)* ... *P(k)*L(k)*...,. (Fortran indices are 1-based). So we need to iterate k from 0 to n, obtain K and L in each step and multiply them.
P is a permutation matrix, defined by piv. A positive value of piv is straight-forward (i = piv[k]). It means that the ith and kth row/column were swapped in A before performing the operation. In this case the kth diagonal element of lult corresponds to the kth diagonal element of D. L(k) contains the kth column of the lower diagonal matrix - after the swapping.
A negative value of piv means that the corresponding element of D is a 2x2 block instead of just one element, and L(k) corresponds to two columns of the lower diagonal matrix.
Now for each step in k we obtain L(k), apply the swapping operation P(k), and combine it with the existing L. We also obtain the 1x1 or 2x2 block of D and correspondingly increase k by 1 or 2 for the next step.
I won't blame anyone for not comprehending my explanation. I simply wrote it down as I figured it out... Hopefully, the combination of the code snippet, the description, and the original documentation prove useful :)
dsysv is the linear system solver and it does all the magic internally including calls to dsytrf. So for the factorization it is not needed. As kazemakase mentioned this is now available in SciPy (PR 7941 and will appear officially in version 1.1) and you can just use the scipy.linalg.ldl() to get the factorization and the permutation information of the outer factors. Actually this was the reason why ?sytrf and ?hetrf was added.
You can look at its source code to see how ipiv is sanitized.
With SciPy v.1.1 built with OpenBlas on Windows 10 machine vs. matlab using mkl, the performance is given below
Adding extra JIT-compilers on top of it probably would bring it to matlab speed. Since the ipiv handling and the factorization construction is done in pure numpy/python. Or better cythonize it if performance is the utmost importance.
Updating scipy to version >= 1.0.0 should do the trick.
A wrapper to sytrf has been added to the master branch in mid-September, just before the 1.0.0 Beta release.
You can find the relevant pull-request and commit on Github.

computational derivatives and integrals

how can we take the derivative of something then use it in an expression like
g := t->diff(f(t),t);
this fails because maple does not first take the derivative then apply t, but applies the value of t then tries to differentiate with respect to that value symbolically.
To solve this I usually have to precompute the differential, then copy and paste it. The problem with this method is that any time the original function changes, everything needs to be redone, which can be time consuming.
Is there a better way?
Using the D operator you can assign the "derivative" of the operator f to g, without having first assigned anything to f.
You can subsequently assign and reassign different operators to f, after which g can be called. Calling g in the example below will not cause f to be called with any symbolic argument.
restart;
g := D(f);
g := D(f)
f := x->sin(x)+x^2:
g(x);
cos(x) + 2 x
g(2);
cos(2) + 4
f := x->tan(x)+x^3:
g(x);
2 2
1 + tan(x) + 3 x
g(2);
2
13 + tan(2)
Another way to do it is as follows. Note that with this methodology every call to g will cause Maple to call diff on the symbolic local T. If -- after assigning to f -- you call g many times then that will be more expensive (even if just for the overhead of checking a memoized result and making the extra function call to diff). Also, your f may be something which is not even set up to return appropriately for a non-numeric argument, so the call to f(T) might be problematic.
restart;
g := proc(t) local T; eval(diff(f(T),T),T=t); end proc:
f := x->sin(x)+x^2:
g(x);
cos(x) + 2 x
g(2);
cos(2) + 4
f := x->tan(x)+x^3:
g(x);
2 2
1 + tan(x) + 3 x
g(2);
2
13 + tan(2)
The D operator is pretty useful. You could check out its help page.

Why do people use hash(k) = c * k with a prime c

Given an integer m, a hash function defined on T is a map T -> {0, 1, 2, ..., m - 1}. If k is an element of T and m is a positive integer, we denote hash(k, m) its hashed value.
For simplicity, most hash functions are of the form hash(k, m) = f(k) % m where f is a map from T to the set of integers.
In the case where m = 2^p (which is often used to the modulo m operation is cheap) and T is a set of integers, I have seen many people using f(k) = c * k with c being a prime number.
I understand if you want to choose a function of the form f(k) = c * k, you need to have gcd(c, m) = 1 for every hash table size m. Even though using a prime number fits the bill, c = 1 is also good.
So my question is the following: why do people still use f(k) = prime * k as their hash function? What kind of nice property does it have?
You don't need it to be prime. One of the most efficient hash functions with provable collision resistance just multiplies with a random number: https://en.wikipedia.org/wiki/Universal_hashing#Avoiding_modular_arithmetic. You do however need it to be odd.

MATLAB: How to make the Hermitean matrix from specific complex vectors?

Is given:
stationary mass ms=1;
Eta-constant eta=0.45;
variable number of repetitions, e.g. N=5;
omega OM=sqrt(ks/ms);
angular frequency om=eta*OM;
time period T=2*pi/om;
upper bound TTT=1.5;
variable for creating function t=0:0.001:TTT;
I made a function like that:
kt=zeros(size(t));
for j=1:2*N+1
n= j-(N+1);
if n==0
k(j)=ks/2;
else
k(j)=i/pi/n;
end
kt=kt+k(j)*exp(i*n*om*t);
end
It’s a Sawtooth wave and there is my problem. From the complex vector kt with value 1x1501 double I have to make the Hermitean matrix for variable N. This means that N can be 5, can be 50, 100, etc. The matrix should look like (picture):
Where k1 is k for N=1, k0 is k for N=0 or k-1 is k for N=-1. Size of matrix is 2*N+1 and 2*N+1.
Thank you for your help and responding!
That's a Toeplitz matrix, you can use the toeplitz command to generate the matrix above. In the general case, this would have been written as:
H = toeplitz(kt(N:end), kt(1:N + 1))
where the first N values in kt correspond to k-N, ... k-1, and the last N + 1 values are k0, ... kN. However, since H is Hermitian, this can be simplified to:
H = toeplitz(kt(N:end));
Try this code:
k=[1 2+i 3+i 4+i 5+i];
N=7;
M=diag(k(1)*ones(N,1));
for j=1:length(k)-1
M=M+diag(k(j+1)*ones(N-j,1),j)+diag(conj(k(j+1))*ones(N-j,1),-j)
end;
Here N should be equal or greater than the length of k array