ADF IN JAVA
1.测试数据
一串时间序列
2.将原始的数据进行差分处理。
//difflist 差分数列
List<Double> difflist = Diff.diffArr(arr);
3.通过最大窗口值,处理差分后的数据。获得double[][]数组后,将第一列的数据替换为原始数组队应位置,同时在替换完的数组前加一列常数列 1。
//计算最大窗口大小 windowSize
int windowSize =(int) Math.ceil(Math.pow(arr.length / 100.0 ,1.0/4) * 12.0) + 1;
//slidingWindowLists 最大滑动窗口
List<List<Double>> maxslidingsindowLists = SlidingWindow.SlidingWindow(difflist , windowSize);
// 输出代替后的最大窗口数组
double[][] maxreplacewindow = Replace.replace(arr,maxslidingsindowLists);
//在第一列增加常数项
double[][] maxfullRHS = add.add2(maxreplacewindow);
4,通过最大窗口数组,找到最佳的滑动窗口大小。具体做法是,从0开始到最大窗口数组长度,依次计算每个数组的残差值,通过计算找到最小的比较值,输出此时的窗口大小,即为最佳的最佳窗口长度大小。
//找到最佳的滑动窗口大小
int bestWindowSize = BestWindow.bestwindow(d , maxfullRHS) + 1;
System.out.println("bestWindowSize = " + bestWindowSize);
5.找到最佳窗口长度以后,通过此值得到最佳窗口double[][]数组,并将第一列替换为原始数组的队应值,同时在最后加一列常数列 1。
//返回最佳窗口list
List<List<Double>> bestslidingsindowLists = SlidingWindow.SlidingWindow(difflist,bestWindowSize);
// 输出代替后的最佳窗口数组
double[][] bestreplacewindow = Replace.replace(arr,bestslidingsindowLists);
//在最后一列增加常数项
double[][] bestresult = add.add1(bestreplacewindow);
6.对最佳窗口数组进行OLS运算,求出相关系数beta ,残差和标准差std。
Matrix matrixa = new Matrix(d2);
Matrix matrixb = new Matrix(bestresult);
OLS ols = new OLS();
//计算beta
Matrix tempbetas = ols.Regress(matrixb, matrixa, false);
double beta = tempbetas.getValue(0,0);
System.out.println("beta = " + beta);
//计算残差
Matrix res = ols.getResiduals();
double residual = 0;
double[][] ressum = res.getData();
for(int i = 0 ; i < ressum.length ;i++)
for (int j = 0; j < ressum[0].length; j++)
residual = ressum[i][j] * ressum[i][j] + residual;
System.out.println("residual = " + residual);
//计算标准差
Matrix sse = ols.getStandartErrorsOfParameters();
double std = sse.getValue(0,0);
System.out.println("std = " + std);
7.计算t_value
ouble t_value = beta / std;
System.out.println("t_value = " + t_value);
8.计算得到p。我们在这里将公式简化。
double p = Mackinnonp.calc(Mackinnonp.calMackinnonp(t_value));
System.out.println("p = " + p);
ADF检验相关类:
Add:
package ADF;
public class add {
public static double[][] add1(double[][] replacewindow){
double[][] result = new double[replacewindow.length][replacewindow[0].length + 1];
for(int i = 0 ; i < replacewindow.length ; i++){
for(int j = 0 ; j< replacewindow[0].length ;j++)
result[i][j] = replacewindow[i][j];
result[i][replacewindow[0].length] = 1;
}
return result;
}
public static double[][] add2(double[][] replacewindow){
double[][] result = new double[replacewindow.length][replacewindow[0].length + 1];
for(int i = 0 ; i < replacewindow.length ; i++){
for(int j = 0, k = 1 ; j< replacewindow[0].length ;j++ , k++)
result[i][k] = replacewindow[i][j];
result[i][0] = 1;
}
return result;
}
}
ADFCheck:
package ADF;
import org.apache.commons.math3.linear.RealVector;
import java.util.List;
public class ADFCheck {
public static double ADFCheck(double[] arr){
//difflist 差分数列
List<Double> difflist = Diff.diffArr(arr);
//计算最大窗口大小 windowSize
int windowSize =(int) Math.ceil(Math.pow(arr.length / 100.0 ,1.0/4) * 12.0) + 1;
//slidingWindowLists 最大滑动窗口
List<List<Double>> maxslidingsindowLists = SlidingWindow.SlidingWindow(difflist , windowSize);
// 输出代替后的最大窗口数组
double[][] maxreplacewindow = Replace.replace(arr,maxslidingsindowLists);
//在第一列增加常数项
double[][] maxfullRHS = add.add2(maxreplacewindow);
//将差分的list转换为数组
int length = maxfullRHS[0].length - 2;
double[] d = new double[difflist.size() - length];
for (int j = 0 ,i = length ; i < difflist.size() ;j++, i++) {
d[j] = difflist.get(i);
}
//找到最佳的滑动窗口大小
int bestWindowSize = BestWindow.bestwindow(d , maxfullRHS) + 1;
System.out.println("bestWindowSize = " + bestWindowSize);
//返回最佳窗口list
List<List<Double>> bestslidingsindowLists = SlidingWindow.SlidingWindow(difflist,bestWindowSize);
// 输出代替后的最佳窗口数组
double[][] bestreplacewindow = Replace.replace(arr,bestslidingsindowLists);
//在最后一列增加常数项
double[][] bestresult = add.add1(bestreplacewindow);
//将差分的list转换为数组
int length2 = bestresult[0].length - 2;
double[] d2 = new double[difflist.size() - length2];
for (int j = 0 ,i = length2 ; i < difflist.size() ;j++, i++) {
d2[j] = difflist.get(i);
}
Matrix matrixa = new Matrix(d2);
Matrix matrixb = new Matrix(bestresult);
OLS ols = new OLS();
//计算beta
Matrix tempbetas = ols.Regress(matrixb, matrixa, false);
double beta = tempbetas.getValue(0,0);
System.out.println("beta = " + beta);
//计算残差
Matrix res = ols.getResiduals();
double residual = 0;
double[][] ressum = res.getData();
for(int i = 0 ; i < ressum.length ;i++)
for (int j = 0; j < ressum[0].length; j++)
residual = ressum[i][j] * ressum[i][j] + residual;
System.out.println("residual = " + residual);
//计算标准差
Matrix sse = ols.getStandartErrorsOfParameters();
double std = sse.getValue(0,0);
System.out.println("std = " + std);
double t_value = beta / std;
System.out.println("t_value = " + t_value);
double p = Mackinnonp.calc(Mackinnonp.calMackinnonp(t_value));
System.out.println("p = " + p);
return p;
}
}
BestWindow:
package ADF;
public class BestWindow {
public static int bestwindow(double[] diff ,double[][] fullRHS){
double[] residualarr = new double[fullRHS[0].length];
int size = 1;
for(int i = 1 ; i < fullRHS[0].length ; i++){
double[][] window = new double[fullRHS.length][i + 1];
for(int j = 0 ; j < fullRHS.length ; j++)
for (int k = 0; k < i + 1; k++)
window[j][k] = fullRHS[j][k];
Matrix matrixa = new Matrix(diff);
Matrix matrixb = new Matrix(window);
OLS ols = new OLS();
//计算beta
Matrix tempbetas = ols.Regress(matrixb, matrixa, false);
double beta = tempbetas.getValue(1,0);
Matrix res = ols.getResiduals();
double residual = 0;
double[][] ressum = res.getData();
for(int k = 0 ; k < ressum.length ;k++)
for (int t = 0; t < ressum[0].length; t++)
residual = ressum[k][t] * ressum[k][t] + residual;
double num = 2 * window[0].length + window.length * Math.log(residual / window.length);
residualarr[i] = num;
}
double bestWindow = residualarr[1];
for(int i = 1 ; i < residualarr.length ; i++){
if(Double.compare(bestWindow, residualarr[i]) > 0) {
bestWindow = residualarr[i];
size = i;
}
}
return (size - 1);
}
}
Diff:
package ADF;
import java.util.ArrayList;
import java.util.List;
public class Diff {
public static List<Double> diffArr(double[] arr){
List<Double> list = new ArrayList();
for(int i = 1 ; i < arr.length ; i++){
list.add(arr[i] - arr[i - 1]);
}
return list;
}
}
Mackinnop:
package ADF;
public class Mackinnonp {
public static double calMackinnonp(double num){
if(num > 2.74)
return 1;
if(num < -18.83)
return 0;
if(num < -1.61)
return 0.038269 * Math.pow(num,2) + 1.4412 * num + 2.1659;
else
return -0.010368 * Math.pow(num,3) - 0.12745 * Math.pow(num,2) + 0.93202 * num + 1.7339;
}
public static double calc(double u){
double y = Math.abs(u);
double y2 = y*y;
double z = Math.exp(-0.5 * y2) * 0.398942280401432678;
double p = 0;
int k = 28;
double s = -1;
double fj = k;
if(y > 3){
for(int i = 1 ; i <= k ; i++){
p = fj / (y + p);
fj = fj - 1.0;
}
p = z / (y + p);
}else{
for(int i = 1 ; i <= k ; i++){
p = fj * y2 / (2.0*fj +1.0 + s * p);
s = -s;
fj = fj - 1.0;
}
p = 0.5 - z * y / ( 1 - p );
}
if(u>0) p = 1.0 - p;
return p;
}
}
Matrix:
package ADF;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.StringTokenizer;
public class Matrix
{
public double myData[][];
public int n;
public int m;
public Matrix()
{
}
public Matrix(int n, int m)
{
this.n = n;
this.m = m;
try
{
myData = new double[n][m];
}
catch(Exception _ex)
{
System.out.println("Matrix(n,m) can't create");
}
}
public Matrix(double data[][])
{
n = data.length;
m = data[0].length;
myData = data;
}
public Matrix(double data[]) {
n = data.length;
m = 1;
double[][] a = new double[n][1];
for(int i = 0 ; i < n ; i++)
a[i][0] = data[i];
myData = a;
}
public double Det()
{
if(n != m)
return 0.0D;
double mydet = 1.0D;
Matrix temp1 = new Matrix(myData);
double temp2[][] = temp1.Eshelon().getData();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
if(i == j)
mydet *= temp2[i][j];
}
temp2 = null;
temp1 = null;
return mydet;
}
public Matrix Diff(Matrix A)
{
Matrix mynew = new Matrix(A.n, A.m);
for(int i = 0; i < A.n; i++)
{
for(int j = 0; j < A.m; j++)
mynew.setValue(i, j, myData[i][j] - A.getValue(i, j));
}
return mynew;
}
public Matrix Eshelon()
{
double pivot = 0.0D;
Matrix t = new Matrix(myData);
double temp[][] = new double[t.n][t.m];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
temp[i][j] = t.getValue(i, j);
}
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
pivot = -temp[j][i] / temp[i][i];
for(int k = 0; k < m; k++)
temp[j][k] = temp[i][k] * pivot + temp[j][k];
}
}
t = null;
return new Matrix(temp);
}
public Matrix Inverse()
{
if(this.n != this.m || Det() == 0.0D)
return new Matrix(this.n, this.m);
Matrix temp = new Matrix(myData);
int n = temp.n;
int m = temp.m;
Matrix Cofactor = new Matrix(n, m);
for(int j = 0; j < m; j++)
{
for(int i = 0; i < n; i++)
{
Matrix Mintemp = temp.Minor(i, j);
double tempdet = Mintemp.Det();
Cofactor.setValue(i, j, tempdet);
}
}
Cofactor = Cofactor.Transpose();
double det = temp.Det();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
Cofactor.setValue(i, j, (Cofactor.getValue(i, j) * Math.pow(-1D, i + j + 2)) / det);
}
return Cofactor;
}
public Matrix Minor(int x, int y)
{
Matrix temp = new Matrix(myData);
Matrix newmat = new Matrix(temp.n - 1, temp.m - 1);
int n = temp.n;
int m = temp.m;
int cnt = 0;
double myArr[] = new double[(n - 1) * (m - 1)];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
if(i != x && j != y)
{
myArr[cnt] = temp.getValue(i, j);
cnt++;
}
}
cnt = 0;
for(int i = 0; i < n - 1; i++)
{
for(int j = 0; j < m - 1; j++)
{
newmat.setValue(i, j, myArr[cnt]);
cnt++;
}
}
return newmat;
}
public Matrix Mult(Matrix A)
{
double c[][] = new double[n][A.m];
double tempdata[][] = A.getData();
for(int i = 0; i < n; i++)
{
for(int j = 0; j < A.m; j++)
{
for(int y = 0; y < m; y++)
c[i][j] = c[i][j] + myData[i][y] * tempdata[y][j];
}
}
return new Matrix(c);
}
public Matrix Transpose()
{
Matrix temp = new Matrix(myData);
int n = temp.n;
int m = temp.m;
Matrix newmat = new Matrix(m, n);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
newmat.setValue(j, i, temp.getValue(i, j));
}
return newmat;
}
public double[][] getData()
{
double temp[][] = myData;
return temp;
}
public double getValue(int x, int y)
{
return myData[x][y];
}
public void setValue(int x, int y, double value)
{
myData[x][y] = value;
}
}
OLS:
package ADF;
// Referenced classes of package Statistics:
// Matrix
public class OLS
{
public Matrix betas;
public Matrix x;
public Matrix y;
boolean intercept;
public OLS()
{
}
public Matrix Regress(Matrix x, Matrix y, boolean intercept)
{
this.intercept=intercept;
betas = new Matrix();
this.x = x;
this.y = y;
if(!intercept) {
//Transpose 转置 Mult相乘 inverse 求逆
betas = x.Transpose().Mult(x).Inverse().Mult(x.Transpose()).Mult(y);
} else {
int n = x.n;
int m = x.m;
Matrix design = new Matrix(n, m + 1);
for(int i = 0; i < n; i++)
design.setValue(i, 0, 1.0D);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
design.setValue(i, j + 1, x.getValue(i, j));
}
betas = design.Transpose().Mult(design).Inverse().Mult(design.Transpose()).Mult(y);
this.x =new Matrix(design.myData);
}
return betas;
}
public Matrix getResiduals()
{
Matrix temp = y.Diff(x.Mult(betas));
return temp;
}
public double getEstimatedVariance(){
Matrix temp=new Matrix(x.n,1);
temp.myData=getResiduals().myData;
double temp1=0;
for (int i=0;i<x.n;i++){
temp1+= Math.pow(temp.getValue(i,0),2.0);
}
return (temp1/(x.n-x.m));
}
public Matrix getCovarianceMatrixOfParameters(){
Matrix temp=(x.Transpose().Mult(x)).Inverse();
double std=getEstimatedVariance();
for (int i=0;i<x.m;i++){
temp.myData[i][i]=temp.myData[i][i]*std;
}
return (temp);
}
public Matrix getStandartErrorsOfParameters() {
Matrix temp=getCovarianceMatrixOfParameters();
for (int i=0;i<x.m;i++){
temp.myData[i][i]= Math.sqrt(temp.myData[i][i]);
}
return (temp);
}
}
Replace:
package ADF;
import java.util.List;
public class Replace {
public static double[][] replace(double[] arr , List<List<Double>> lists){
double[][] arrs = new double[lists.size()][lists.get(0).size()];
for (int i = 0; i < lists.size(); i++) {
List<Double> temp = lists.get(i);
for (int j = 0; j < temp.size(); j++) {
arrs[i][j] = temp.get(j);
}
}
for(int i = arrs.length - 1 , j = arr.length -1 ; i >= 0 ; i-- ,j --)
arrs[i][0] = arr[j - 1];
return arrs;
}
}
SlidingWindow:
package ADF;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SlidingWindow {
public static List SlidingWindow(List rawlist, int size){
List<List<Double>> list = new ArrayList<>();
for(int i = 0 ; i < rawlist.size() - size + 1 ; i++){
List<Double> lists = new ArrayList<>();
for(int j = 0 ; j <size ; j++)
lists.add((Double) rawlist.get(i + j));
Collections.reverse(lists);
list.add(lists);
}
for(int i = 0 ; i < rawlist.size() - size + 1 ; i++){
List<Double> lists = new ArrayList<>();
lists = list.get(i);
}
return list;
}
}