/
weibull_est.py
62 lines (47 loc) · 1.69 KB
/
weibull_est.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# -*- coding: utf-8 -*-
'''
Weibull Estimators
-------
A small library of tools for fitting weibull pdfs to data
'''
from __future__ import division
import scipy.optimize as spyopt
from scipy.special import gamma
import numpy as np
#Least Squares
def least_sq(data, x):
'''Least squares fitting of parameters via data fitting to the
distribution
'''
def residuals(p, y, x):
'''Least squares residual errors'''
A, k = p
err = y-k/A*(x/A)**(k-1)*np.exp(-(x/A)**k)
return err
param_init = [10, 2]
plsq = spyopt.leastsq(residuals, param_init, args=(data, x))
return plsq[0]
def euro_atlas(ws_data):
'''European Wind Atlas approach for calculating weibull parameters.
This approach specifies the following contraints:
- The total wind energy in the fitted weibull distribution must be equal
to that of the observed distribution
-The frequency of occurence of the wind speeds higher than the observed
average speeds are the same for the two distributions
These details can be found on pages 168-169 in the EMD WindPro manual:
http://www.emd.dk/files/windpro2.8/WindPRO28_Manual.pdf
'''
#Statistical 3rd order moment
a3 = np.sum(ws_data**3)/len(ws_data)
#Probability of exceeding mean value
exceed = ws_data.where(ws_data > ws_data.mean(), None)
prob_exceed = exceed.count()/len(ws_data)
def k_eq(x, ws_mean, a3, prob):
'''Equation for k'''
return np.exp(-(ws_mean/(a3/gamma(1+3/x))**(1/3))**x)-prob
#Solve for k
soln = spyopt.fsolve(k_eq, x0=[2], args=(ws_data.mean(), a3, prob_exceed))
k = soln[0]
#Solve for A
A = (a3/gamma(1+3/k))**(1/3)
return A, k