so I am using this python based ldpc package https://hichamjanati.github.io/pyldpc/ In this package for some constraints of my project I cannot use the SNR values. I can only apply bit flips with certain probabilities to the entire encoded message. But with this package, it seems SNR value is a must.
from pyldpc import make_ldpc, encode, decode, get_message
n = 15
d_v = 4
d_c = 5
snr = 20
H, G = make_ldpc(n, d_v, d_c, systematic=True, sparse=True)
k = G.shape[1]
print('K:', k)
v = np.random.randint(2, size=k)
print('V:', v)
y = encode(G, v, snr)
print('Encode:', y)
if y[1] == 1:
y[1] = 0
else:
y[1] = 1
print('Corrupted:', y)
d = decode(H, y, snr)
print('Decode:', y)
x = get_message(G, d)
print('Get message:', x)
(ignore the snr variable I turned it off in a way).
When I went ahead and forcibly turned off the SNR argument and applied bit-flip errors on my own the decoder was not able to correct it, giving a message
UserWarning: Decoding stopped before convergence. You may want to increase maxiter
warnings.warn("Decoding stopped before convergence.")
Is there a proper way to implement simple bit flips in this package? Thanks in advance.
Bitflip almost equal to inverse of sign of soft data after
encode(G, v, snr)
I think you've made too much errors and decoder can't decode it.
p.s. mention that this package use SP-decoding, which very sensitive to correctness of SNR estimation (and constructed to work only with gaussian noise, not with channel with erasures or inversions of analog input data).
Better to try using of MS-decoder which not sensitive to snr estimation.
Related
I’m new to PyMC and am trying to model a situation where you are rolling marbles at a wall and trying to find the block. The data is only for the values where the marble hits the block.
I’m first sampling an x location and size and then calculating a point from those with a uniform, but I’m getting an error.
import pymc3 as pm
import theano.tensor as tt
basic_model = pm.Model()
with basic_model:
# We are assuming independence of these.
x = pm.Uniform("x", lower=1, upper=30)
l = pm.Uniform("l", lower=1, upper=30)
lower = pm.Deterministic('lower', x-0.5*l)
upper = pm.Deterministic('upper', x+0.5*l)
point_x = pm.Uniform('point_x', lower=lower, upper=upper, observed=x_vals)
pm.sample()
With the error:
SamplingError: Initial evaluation of model at starting point failed!
Starting values:
{'x_interval__': array(0.), 'l_interval__': array(0.)}
Initial evaluation results:
x_interval__ -1.39
l_interval__ -1.39
point_x -inf
Name: Log-probability of test_point, dtype: float64
Clearly the issue is with point_x. I’m guessing the error has to do with the fact that the observed data may potentially fall outside the lower-upper range depending on the value of x and l sampled. But how might I fix this?
The sampler doesn't know how to handle starting off in an invalid region of the parameter space. A quick and dirty fix is to provide testval arguments that ensure the sampling begins in a logically valid solution. For example, we know the minimum block must have:
l_0 = np.max(x_vals) - np.min(x_vals)
x_0 = np.min(x_vals) + 0.5*l_0
and could use those:
x = pm.Uniform("x", lower=1, upper=30, testval=x_0)
l = pm.Uniform("l", lower=1, upper=30, testval=l_0)
Also, the nature of this model leads to many rejections due to impossibility, so you may want to use Metropolis for sampling, which almost always needs more steps and tuning
pm.sample(tune=10000, draws=10000, step=pm.Metropolis())
Alternative Models
Otherwise, consider reparameterizing so that only valid solutions are in the parameter space. One approach would be to sample l and then use that to constrain x. Something like:
other_model = pm.Model()
x_min = np.min(x_vals)
x_max = np.max(x_vals)
l_0 = x_max - x_min
with other_model:
# these have logical constraints from the data
l = pm.Uniform("l", lower=l_0, upper=30)
x = pm.Uniform("x", lower=x_max - 0.5*l, upper=x_min + 0.5*l)
lower = pm.Deterministic('lower', x - 0.5*l)
upper = pm.Deterministic('upper', x + 0.5*l)
point_x = pm.Uniform('point_x', lower=lower, upper=upper, observed=x_vals)
res = pm.sample(step=pm.NUTS(), return_inferencedata=True)
Another approach would be to sample lower and upper directly, and compute the x and l as deterministic variables from those.
In the following code I am trying to implement the following
write a function naturalSpline that implements cubic spline interpolation with natural boundary conditions
Use a tridiagonal solver to solve the arising tridiagonal system for the first derivatives.
The prototype of the function should read yy=naturalSpline(x,y,xx) where (x,y) are the input points and data, and xx are the points where the data should be interpolated.
I figured first I would start with the second bullet point, creating the tridiagonal solver. So this is just the Thomas algorithm. I spent some time to create this part of the code and I have formatted it below. But now I am trying to finish the first and third bullet points but I am not sure how to use what I have done already to finish those. Looking for some help with this! Thanks in advance.
import numpy as np
def TDMA(a,b,c,d):
n = len(d)
w= np.zeros(n-1,float)
g= np.zeros(n, float)
p = np.zeros(n,float)
w[0] = c[0]/b[0]
g[0] = d[0]/b[0]
for i in range(1,n-1):
w[i] = c[i]/(b[i] - a[i-1]*w[i-1])
for i in range(1,n):
g[i] = (d[i] - a[i-1]*g[i-1])/(b[i] - a[i-1]*w[i-1])
p[n-1] = g[n-1]
for i in range(n-1,0,-1):
p[i-1] = g[i-1] - w[i-1]*p[i]
return p
A = np.array([[10,2,0,0],[3,10,4,0],[0,1,7,5], [0,0,3,4]],dtype=float)
a = np.array([3.,1,3])
b = np.array([10.,10.,7.,4.])
c = np.array([2.,4.,5.])
d = np.array([3,4,5,6.])
print (TDMA(a, b, c, d))
Which gives the correct output, I even tested it against np.linalg.solve(a,b,c,d) to make sure it was correct
[ 0.14877589 0.75612053 -1.00188324 2.25141243]
For each interval [x_k, x_(k+1)], you can solve the four equations
p_k(x_k) = f(x_k) = y_k
p_k'(x_k) = f'(x_k) = d_k
p_k(x_(k+1)) = f(x_(k+1)) = y_(k+1)
p_k'(x_(k+1)) = f'(x_(k+1)) = d_(k+1)
(without checking your code, I assume that this is what you did).
From this, you can construct a dict
{'polynomials': [ [a_0, ..., d_0], ..., [a_24, ..., d_24] ],
'knots': [x_0, ..., x_24]}
For each x of your 250 point, you check for which k the point x is in the interval [x_k, x_(k+1)] and evaluate p_k(x).
All of this is straight forward mathematics and python coding. If something is not clear, you are better of learning more about both fields, instead of getting specialized advise on this website.
i`m having a class called numerical methods, where we learn how to write programs for certain problems in physics. We had to write 4 programs which could solve ODEs (implicit/explicit euler, velocity-verlet, implicit midpoint rule), now we have to calculate the error by using |y_N - y(T)|. We already have a template which we need to fill out.
This is the code which we have to complete.
def ex2_d():
T = 0.2
y0 = np.array([0.3, 0.0])
all_methods = [explicit_euler, implicit_euler, implicit_mid_point, velocity_verlet]
all_rhs = 3*[pendulum_rhs] + [pendulum_verlet_rhs]
resolutions = 2**np.arange(4, 11)
_, y_exact = ode45(pendulum_rhs, (0.0, T), y0, reltol=1e-12)
for method, rhs in zip(all_methods, all_rhs):
error = np.empty(resolutions.size)
for k, N in enumerate(resolutions):
# TODO: Berechen Sie die Lösung und den Fehler
error[k] = np.absolute(methode())
rate = convergence_rate(error, resolutions)
print(method)
print("rate: " + str(rate) + "\n")
The only thing I need to fill out is the TODO part. But I don`t understand, the for loop, which is looping over k and N in enumerate(resolution), and why is the resolution array declared as it is anyways?
Thank you in advance for your help!
In numerically solving an ODE, you want to have doubling resolutions (halving step sizes), to find the convergence rate, using the standard method:
(u_h - u_(h/2))/(u_(h/2) - u_(h/4)) = 2^p + O(h)
with u_h the numerical solution at a step h, u_(h/2) the solution with a step h/2 (e.g. double resolution) and u_(h/4) the solution with a step h/4 (e.g. again double resolution). The order of the error is p, which gives a convergence rate of h^p
This is why the resolutions are declared as 2**np.arange(4,11), which gives[ 16, 32, 64, 128, 256, 512, 1024]`. (You can use other grid sizes, which will change the formula accordingly. For more information, see this.
To store the errors in a list, you need the corresponding indices of the resolutions, which is why enumerate is used:
enumerate(resolutions) -> [(0,16), (1,32), (2,64), (3,128), (4,256), (5,512), (6,1024)]
which is unpacked by the for loop:
iteration k N
1 0 16
2 1 32
etc.
The aim of this excercise is to compare different methods for solving the differential equation given by pendulum_rhs.
The quantity by which the comparison takes place is the convergence rate. In order to determine this rate you need to solve the DE with variing resolution (of the underlying grid) and compute the error for every resolution.
The resolutions to use are given: resolutions =[16, 32, 64, ...].
So for a given method method, you iterate over the resolutions:
for k in range(len(resolutions)):
N = resolutions[k]
# calculate the result using N
result = method(..., N, ...)
#store it in an array called
error[k] = np.abs(y_exact - result)
Here is my problem: I have experimental data to fit with a model. To do this, i used curve_fit from scipy. The script goes without any error or warning, but doesn't give a satisfying result (it gives me a quasi line instead of two Lorentzian shaped graph).
But the strangest part is that when I give a guessing array to the fitting function, none of the guessed parameters is modified, except for the third one (nevertheless it stay far from the expected value). However I pay attention to the order of the guessed parameters.
I give you the part of the code that does the fit.
X = 927.
Z = 88.
M = 5.e-15
O1 = 92975.
O2 = 93570.
bm = np.arctan2(Z,X)
P0 = 0.
T = np.pi/2.
TM = np.pi/3.
G = 20.
File ="Data.txt"
open(File, "rb")
dat = np.loadtxt(File)
O = dat[:,1]
D = np.sqrt(1./20. *10**(dat[:,7]/10.)*1/((X**2+Z**2)*10**(6)))
def model(W,o1,o2,p0,t,tm,g):
DB = np.abs((1./M)*(np.cos(bm-tm)*(p0*np.cos(t-tm)/(o1**2-W**2-1.j*g*W))+np.sin(bm-tm)*(p0*np.sin(t-tm)/((o2**2-W**2-1.j*g*W)))))
return DB
guess = np.array([O1,O2,P0,T,TM,G])
fit , pcov = curve_fit(model, O , D , guess)
I search an research during a complete month to find any error, but still noting. Is It possible that the function is to complex for curve_fit?
Thank you in advance for your help. Don't hesitate if you need further informations or data
Here is a plot of O v D. The red points are the experiment and the blue line is the function with the returned fit parameters (not modified, so they are the guessing values)
D = model(O)
it's very hard to tell what is going on with the mixture of constants and very long formulae. But a couple points to consider:
If variables are not changing from their initial values, you should be careful about scaling. Your (X**2+Z**2)*10**(6) will be around ~1e16, which might make it hard to make good numerical derivatives. You may need to modify the value of epsfcn sent to leastsq().
It looks like your model function calculates a complex array. I believe curve_fit() can handle only strictly real values.
You might find the lmfit module useful.
Well people, thank to you i finally found a solution!
instead of using curve_fit, i tried to use directly leastsq following this tutorial in order to see what would happend. It works better than expected since the fit did succeed and gives me the right positions of the peaks and there amplitudes. I give you the corrected code as it works for me.
X = 927.0
Z = 88.
M = 5.e-15
O1 = 92975.
O2 = 93570.
bm = np.arctan2(Z,X)
P0=1.e-12
T=np.pi/2.
TM=np.pi/3.
G=20.
File ="Data.csv"
open(File, "rb")
dat = np.loadtxt(File)
O = dat[:,1]
D = np.sqrt(1/1000. *10**(dat[:,7]/10.)*50.*1/((X**2+Z**2)*10**(6)))
def resid(p, y, W) :
o1,o2,p0,t,tm,g = p
err=y-(np.abs((1./M)*(np.cos(bm-tm)*(p0*np.cos(t-tm)/(o1**2-W**2-1.j*g*W))+np.sin(bm-tm)*(p0*np.sin(t-tm)/((o2**2-W**2-1.j*g*W))))))
return err
def peval(W,p) :
return np.abs((1./M)*(np.cos(bm-p[4])*(p[2]*np.cos(p[3]-p[4])/(p[0]**2-W**2-1.j*p[5]*W))+np.sin(bm-p[4])*(p[2]*np.sin(p[3]-p[4])/((p[1]**2-W**2-1.j*p[5]*W)))))
guess = np.array([O1,O2,P0,T,TM,G])
plsq = leastsq(resid,guess,args=(D,O))
print plsq[0]
plt.yscale('log')
Again, thank you for your attention
I am trying to implement Quantitative Mobility Spectrum Analysis (QMSA) in Python 2.7 + NumPy + MatPlotLib. QMSA is a tool for analysis of magnetic field-dependent Hall-effect measurements. In a semiconductor, more than one type of carrier (electron or hole) with different concentration and mobility can be found. QMSA can seperate the number of different types of carriers, their density, mobility, and sign. There are some versions of it like improved version i-QMSA. However, even the building the standart QMSA from zero is a hard work to do.
The job is highly know. There are alot of scientific articles about the subject. However, because of copyrights of each article is held by a publisher I can not share with you. Mostly, you can reach them with an university account. There are some thesis about it like:
1.) digital.library.txstate.edu/bitstream/handle/10877/4390/CUNNINGHAM-THESIS.pdf?sequence=1
2.) wrap.warwick.ac.uk/56132/1/WRAP_thesis_Kiatgamolchai_2000.pdf
3.) etd.lib.nsysu.edu.tw/ETD-db/ETD-search/getfile?URN=etd-0629104-152644&filename=etd-0629104-152644.pdf (I think it is in Chinese)
4.) fbetezbankasi.gazi.edu.tr/pdf-indir/22233741 (I think it is in Turkish. Equations which is given in QMSA manual is listed in thesis at pages 73-75)
Code will I am trying to do Successive-over-relaxation (SOR) iterative approach as originally done. Firstly, I prepare I simple code to produce artificial experimental data of magnetic field dependent conductivity tensor sigmaxx(B) and sigmaxy(B). With this experimental input and a predefine mobility values, code is running...
for i in range (0,n,1):
bxx[i] = data[i][1]
bxy[i] = data[i][2]
for j in range (0,m,1):
if data[i][0] == 0:
data[i][0] = 0.001
Axx[j,i]=1/(1+(mobin[j]**2)*(data[i][0]**2))
Axy[j,i]=(mobin[j]*data[i][0])/(1+(mobin[j]**2)*(data[i][0]**2))
Here, bxx, bxy, mobin and data[i][0] is experimental sigmaxx, experimental sigmaxy, predefined mobility values taken from a text file and experimental magnetic field points, respectively. Therefore we are trying to solve two equations with SOR in the form of Ax=b. For XX part of the problem A, x and b are renamed as Axx, solxx and bxx. For XY part of the problem A, x and b are renamed as Axy, solxy and bxy.
For the SOR, you need a parameter called omega. I found optimum omega values with GAuss-Seidel (here I am showing this for XX part of the conductivity. Same procedures are also done for XY):
print "Iterations for finding omega..."
for it_count in range(1,501):
for i in range(0,n,1):
s1xx = np.dot(Axx[i, :i], solxx_new[:i])
s2xx = np.dot(Axx[i, i + 1:], solxx[i + 1:])
solxx_new[i] = (bxx[i] - s1xx - s2xx) / Axx[i, i]
dx = sqrt(np.dot(solxx_new-solxx,solxx_new-solxx))
for i in range(0,n,1):
solxx[i] = solxx_new[i]
if it_count == k: dx1 = dx
if it_count == k + 1:
dx2 = dx
omegaxx = 2.0/(1.0 + sqrt(abs(1.0 - (dx2/dx1))))
break
print "I think best omega value for these XX calculations is ", omegaxx
This "finding optimum omega" procedure is taken from Kiusalaas, Jaan. Numerical methods in engineering with Python 3. Cambridge university press, 2013, page 83.
After finding omega, this time same iterations are done with SOR:
for it_count in range(ITERATION_LIMIT):
for i in range(0,n,1):
s1xx = np.dot(Axx[i, :i], solxx_new[:i])
s2xx = np.dot(Axx[i, i + 1:], solxx[i + 1:])
solxx_new[i] = (1-omegaxx)*solxx[i-1]+omegaxx*(bxx[i] - s1xx - s2xx) / Axx[i, i]
if np.allclose(solxx, solxx_new, rtol=1e-9):
break
print "Iteration:",it_count
for i in range(0,n,1):
solxx[i] = solxx_new[i]
Then, I calculated conductivity spectrum values for each mobility with:
for i in range (0,n,1):
if i == 0:
deltamob = 100
else:
deltamob = mobin[i] - mobin[i-1]
sn[i] = abs((solxx[i] - solxy[i]))/(2*deltamob*1.6e-19)
sp[i] = abs((solxx[i] + solxy[i]))/(2*deltamob*1.6e-19)
x[i] = mobin[i]
B[i] = data[i][0]
Then x vs sn and x vs sp must be your mobility spectrums. Only thing that I can get is a single Gaussian like peak. And even without any hole carrier, electron and hole spectrums are identical. Problem is solxx and solxy is getting larger values after each iteration. Problem may caused by the SOR code is written for Python 3. But I am using Python 2.7.
I can send files if necessary.
Thanks for any responses.