Home , Post

Least absolute deviations

Nikolai Shokhirev, http://www.numericalexpert.com/

In [1]:
import numpy as np 
In [2]:
def d1(c, x):
    return sum(abs(x-c))

Data points: \(x_{1},\, x_{2},\, x_{3},\,\ldots\,,\, x_{N}\)

In [3]:
def generate_nods(N):
    x = np.linspace(-1.0, 1.0, num=N)
    e = np.random.uniform(-0.1, 0.1, size=N) 
    #x.sort()
    return x+e
In [4]:
def generate_points(x, z, f):
    ''' ordinates for z '''
    d = np.zeros_like(z)
    for i in range(size(z)):
        d[i] = f(z[i], x)
    return d
In [5]:
N = 5
x = generate_nods(N)
print x    
d = generate_points(x, x, d1)
print d
[-0.96905703 -0.40652249  0.07371904  0.41039564  0.93449811]
[ 4.88831843  3.2007148   2.72047328  3.05714988  4.62945728]

Points for plotting

In [6]:
n = 481
z = np.linspace(-1.2, 1.2, num=n)
y = generate_points(x, z, d1)
In [7]:
plot(z, y)
plot(x, d, 'bo')
title('$d_{1}(x)$')
xlabel('$x$')
Out[7]:
<matplotlib.text.Text at 0x5231cf0>
In [8]:
def dd1(c, x):
    return sum(copysign(-1, x-c))
In [9]:
xx = np.zeros(N+2)
xx[0] = -1.2
xx[N+1] = 1.2
for i in range(N):
    xx[i+1] = x[i]
yy = -5
for i in range(1,N+1):
    plot([xx[i-1],xx[i]], [yy,yy],'b')
    yy += 2
plot([-1.2,1.2], [0,0],'r--') 
ylim(-6,6)
title('Derivative')
xlabel('$x$')
Out[9]:
<matplotlib.text.Text at 0x552ab70>

The \(abs\) function can be approximated by a smooth function:

And we have \[ \bar{d}_{1}(c)=\sum_{i=1}^{N}\varphi\left(x_{i}-c\right) \]

In [10]:
def de(c, x, eps=0.0):
    s = 0.0
    for a in x:
        s += sqrt((a-c)**2 + eps**2)
    return s
In [11]:
def generate_points2(x, z, f, e):
    ''' ordinates for z '''
    d = np.zeros_like(z)
    for i in range(size(z)):
        d[i] = f(z[i], x, e)
    return d
In [12]:
y2 = generate_points2(x, z, de, 0.05)
In [13]:
plot(z, y2)
title('Smoothed $d_{1}S')
xlabel('$x$')
Out[13]:
<matplotlib.text.Text at 0x53cc2b0>
In [14]:
def dde(c, x, eps=0.0):
    s = 0.0
    for a in x:
        s += (c-a)/sqrt((a-c)**2 + eps**2)
    return s    
In [15]:
dy2 = generate_points2(x, z, dde, 0.05)
plot(z, dy2)
plot([-1.2,1.2], [0,0],'r--')
title('Smoothed derivative')
xlabel('$x$')
Out[15]:
<matplotlib.text.Text at 0x55398b0>

 

Home , Post