原创|计算分段采样区间中的平均值,标准差,中位数,积分值等的类
SampleFits.java
package org.eso.fits;
import java.util.Arrays;
public class SampleFits {
/*本类完成的功能:对输入的的初始样本lamda, flux,根据整个采样区间的边界值如[3900 9000]以及采样间隔50进行分段,
* 在例子中,lambda和flux的长度应该从小到大有序而且一致,并且lambda的区间范围应该包括边界值[3900 9000];
对于每段,可以计算每段flux对应的平均值,标准差,中位数,积分值等方法。*/
//错误定义
private final int ERROR_NOTFOUND = 0;
private final int ERROR_BOUND = 1;
private final int ERROR_LENGTH = 2;
private final int ERROR_SAMPLESIZE = 3;
//类成员变量
private double sampleSize;
//采样间隔
private double sampleLowArea;
//整个采样区间的左边界
private double sampleUpArea;
//整个采样区间的右边界
private double[] lambda;
//初始数据X
private double[] flux;
//初始数据Y //初始化类成员变量
public SampleFits(double[] dataX, double[] dataY) {sampleSize = 50;
sampleLowArea = 3900;
sampleUpArea = 9000;
lambda = new double[dataX.length];
flux = new double[dataY.length];
System.arraycopy(dataX, 0, lambda, 0, dataX.length);
System.arraycopy(dataY, 0, flux, 0, dataY.length);
if (ErrorCheck() != ERROR_NOTFOUND) {
System.out.println("Please take care of the argvs!");
}
} public SampleFits(int sampleSize, int sampleLowArea, int sampleUpArea, double[] dataX, double[] dataY) {
this.sampleSize = sampleSize;
this.sampleLowArea = sampleLowArea;
this.sampleUpArea = sampleUpArea;
lambda = new double[dataX.length];
flux = new double[dataY.length];
System.arraycopy(dataX, 0, lambda, 0, dataX.length);
System.arraycopy(dataY, 0, flux, 0, dataY.length);
if (ErrorCheck() != ERROR_NOTFOUND) {
System.out.println("Please take care of the argvs!");
}
} //获取相关成员变量的值
public double GetSampleSize(){
return sampleSize;
}
public double GetsampleLowArea(){
return sampleLowArea;
}
public double GetsampleUpArea(){
return sampleUpArea;
}
//通过整个采样区间以及采样间隔,计算划分的区间个数
public int GetRangNum() {
double n = (double) (sampleUpArea - sampleLowArea) / (double) sampleSize;
return (int) Math.floor(n);
}//获取整个采样区间中每段的平均值
public void GetMeanValue(double[] meanValue) {
int rangNum = GetRangNum();
int[] pointNums = new int[rangNum];
CalcPointNums(pointNums);
int start_pos = CalcPos(sampleLowArea);
for (int i = 0;
i < rangNum;
i++) {
double sum = 0;
if (pointNums[i] != 0) {
for (int j = 0;
j < pointNums[i];
j++) {
sum += flux[start_pos++];
}
meanValue[i] = sum / pointNums[i];
} else {
meanValue[i] = 0;
}}
} //获取整个采样区间中每段的标准差
public void GetStdValue(double[] stdValue) {
int rangNum = GetRangNum();
int[] pointNums = new int[rangNum];
CalcPointNums(pointNums);
int start_pos = CalcPos(sampleLowArea);
double[] meanValue = https://www.it610.com/article/new double[rangNum];
GetMeanValue(meanValue);
for (int i = 0;
i < rangNum;
i++) {
double sum = 0;
if (pointNums[i] != 0) {
for (int j = 0;
j < pointNums[i];
j++) {
sum += Math.pow((flux[start_pos++] - meanValue[i]), 2);
}
stdValue[i] = (double) Math.sqrt(sum / pointNums[i]);
} else {
stdValue[i] = 0;
}
}
}
//获取整个采样区间中每段的中位数
public void GetMedianValue(double[] midValue) {int rangNum = GetRangNum();
int[] pointNums = new int[rangNum];
CalcPointNums(pointNums);
int start_pos = CalcPos(sampleLowArea);
int srcPos = start_pos;
for (int i = 0;
i < rangNum;
i++) {
double[] flux_rang = new double[pointNums[i]];
System.arraycopy(flux, srcPos, flux_rang, 0, pointNums[i]);
midValue[i] = CalcMedian(flux_rang);
srcPos += pointNums[i];
}
}//获取整个采样区间的积分值
public double GetRangIntergral(double[] area){
int left_pos = CalcPos(area[0]);
int right_pos = CalcPos(area[1]);
int len = right_pos - left_pos;
double[] lambda_Rang = new double[len];
double[] flux_Rang = new double[len];
System.arraycopy(lambda, left_pos, lambda_Rang, 0, len);
System.arraycopy(flux, left_pos, flux_Rang, 0, len);
return CalcIntergral(lambda_Rang, flux_Rang);
}//对于给定的arrX和对应的arrY,计算积分值,在x轴上方为正,下方为负进行累加。每一小段通过梯形(或三角形)的面积计算
private double CalcIntergral(double[] arrX, double[] arrY){double sum = 0;
for (int i = 0;
i < arrX.length-1;
i++) {
if (arrY[i] * arrY[i+1]>= 0) {
sum += (arrY[i+1] + arrY[i]) * (arrX[i+1] - arrX[i]) / 2;
}
else {
double k = (arrY[i+1] - arrY[i]) / (arrX[i+1] - arrX[i]);
double x_0 = arrX[i] - (arrY[i] / k);
sum += (arrY[i] * (x_0 - arrX[i]) / 2);
sum += (arrY[i+1] * (arrX[i+1] - x_0) / 2);
}}
return sum;
}
//错误检测,主要是边界,x,y的长度是否一致,采样间隔设置是否有问题
private int ErrorCheck() {
double leftBound = lambda[0];
double rightBound = lambda[lambda.length - 1];
if (sampleLowArea < leftBound || sampleUpArea > rightBound) {
System.out.println("The bound is error!");
return ERROR_BOUND;
}
else if (lambda.length != flux.length) {
System.out.println("The length of lambda and flux is error!");
return ERROR_LENGTH;
}
else if (0 == sampleSize || GetRangNum() < 1) {
System.out.println("sampleSize is too large!");
return ERROR_SAMPLESIZE;
}
return ERROR_NOTFOUND;
} //计算整个采样区间中每段的点的个数
private void CalcPointNums(int[] pointNums) {
for (int i = 0;
i < pointNums.length;
i++) {
int startPos = CalcPos(sampleLowArea + i * sampleSize);
int endPos = CalcPos(sampleLowArea + (i + 1) * sampleSize);
pointNums[i] = endPos - startPos;
} } //计算某个x坐标的值val在整个全区间中的位置,这里注意的是位置索引是第一个大于val的值的下标
private int CalcPos(double val) {
int pos = 0;
for (int i = 0;
i < lambda.length;
i++) {
if (val < lambda[i]) {
pos = i;
break;
}
}
return pos;
}
//对于数组arrY,求中位数,这里是用先排序的方法求中位数
private double CalcMedian(double[] arrY) {
double[] b = new double[arrY.length];
System.arraycopy(arrY, 0, b, 0, b.length);
Arrays.sort(b);
if (arrY.length % 2 == 0) {
return (b[(b.length / 2) - 1] + b[b.length / 2]) / 2.0;
} else {
return b[b.length / 2];
}
}}
Test
//-----------------------------Test SampleFits----------------------------
double[] xx = {1, 2.1, 3.3, 5.4, 7, 9.4, 10, 12.3, 14, 16.5, 17.3, 20};
double[] yy = {3, 3, 4, -4, -5, -5, 6, 6, 7, 7, 8, 8};
SampleFits testFits = new SampleFits(4, 2, 18, xx, yy);
int num = testFits.GetRangNum();
System.out.println("num--"+num);
double[] mv = new double[num];
testFits.GetMeanValue(mv);
double[] std = new double[num];
testFits.GetStdValue(std);
double[] mid = new double[num];
testFits.GetMedianValue(mid);
double[] area = {4, 15};
double intergal = testFits.GetRangIntergral(area);
for (int i = 0;
i < std.length;
i++) {
System.out.println("mean--"+mv[i]);
System.out.println("std--"+std[i]);
System.out.println("mid--"+mid[i]);
System.out.println("intergal--"+intergal);
}
//-----------------------------------------------------------------------
System.out.println("----end ---");
Output:
num--4
mean--1.0
std--3.559026084010437
mid--3.0
intergal--5.949999999999994
mean---1.3333333333333333
std--5.185449728701348
mid---5.0
intergal--5.949999999999994
mean--6.5
std--0.5
mid--6.5
intergal--5.949999999999994
mean--7.5
std--0.5
mid--7.5
intergal--5.949999999999994
----end ---
【原创|计算分段采样区间中的平均值,标准差,中位数,积分值等的类】
推荐阅读
- 绘本讲师训练营【24期】14/21阅读原创《小黑鱼》
- 绘本讲师训练营7期9/21阅读原创《蜗牛屋|绘本讲师训练营7期9/21阅读原创《蜗牛屋 》
- 【原创】君子之心,常怀敬畏
- 使用协程爬取网页,计算网页数据大小
- 《偶得》
- ACSL|ACSL 美国计算机科学联赛 2016-2017 R4 摩天大楼-Skyscraper 题解
- 绘本讲师训练营【28期】15/21阅读原创《活了100万次的猫》
- 你命令我爱你吧(原创)
- [原创]能见沂山一棵树,胜读十年无用书!
- 【原创】岫奕诗文《南乡子|【原创】岫奕诗文《南乡子 宴饮席间赠高君》(词林正韵)