题
我在寻找一个java库或一些帮助编写我自己的插值的功能。这就是我的两个阵列双它们可能大小不同,但都以订购。我需要能够作出一个估计数的中间值,并插入以使这两个阵成为大小相同。事实上的总点数中出现的插值的总和2列大小减1。范围内的每个阵列必须停留相同的然而,所以没有推需要。
例如。a1= [1, 4, 9, 16, 25, 36] 和a2= [6, 9, 14, 30]
结果可能是,例如。
a1= [1, 2.25, 4, 6.25, 9, 12.25, 16, 25, 36] 和 a2= [6, 6.5625, 7.25, 9, 10.0625, 11.25, 14, 25.25, 30]
这些例子都是 f(x) = x^2 and g(x) = x^2 + 5
, 然而可能很容易被任何多项式的一点是能够估计/似的功能,从数据集以及足以提供足够体面的插值。这里的x值仅仅是指输入阵列。在输出的仅y值是重要的。
解决方案
其他的答案给你的线性插值--这些不是真的工作复杂、非线性的数据。 你想要一个 花键配合,(键条内插法),我相信。
花键符合描述地区的数据使用一套控制点的数据,然后应用多项式之间的插值的控制点。更多的控制点给你个更精确的配合,小的更大配合。花键是更精确的比线性适合,更快地使用于一般的回归配合,更好比一个高了多项式,因为它不做疯狂的事情之间的控制点。
我不记得名字掉我的头顶,但也有一些优秀的拟图书馆在Java-我建议你找一个的,而不是写你自己的功能。
**编辑:库可能是有用的:**
- JMSL
- JSpline+
- Curfitting库 (希望你可以读德国)
**论/代码这可能是有用的:**
其他提示
设计用于一维数据阵列
import java.util.ArrayList;
public class Interpolator {
public static Float CosineInterpolate(Float y1,Float y2,Float mu)
{
double mu2;
mu2 = (1.0f-Math.cos(mu*Math.PI))/2.0f;
Float f_mu2 = new Float(mu2);
return(y1*(1.0f-f_mu2)+y2*f_mu2);
}
public static Float LinearInterpolate(Float y1,Float y2,Float mu)
{
return(y1*(1-mu)+y2*mu);
}
public static Float[] Interpolate(Float[] a, String mode) {
// Check that have at least the very first and very last values non-null
if (!(a[0] != null && a[a.length-1] != null)) return null;
ArrayList<Integer> non_null_idx = new ArrayList<Integer>();
ArrayList<Integer> steps = new ArrayList<Integer>();
int step_cnt = 0;
for (int i=0; i<a.length; i++)
{
if (a[i] != null)
{
non_null_idx.add(i);
if (step_cnt != 0) {
steps.add(step_cnt);
System.err.println("aDDed step >> " + step_cnt);
}
step_cnt = 0;
}
else
{
step_cnt++;
}
}
Float f_start = null;
Float f_end = null;
Float f_step = null;
Float f_mu = null;
int i = 0;
while (i < a.length - 1) // Don't do anything for the very last element (which should never be null)
{
if (a[i] != null && non_null_idx.size() > 1 && steps.size() > 0)
{
f_start = a[non_null_idx.get(0)];
f_end = a[non_null_idx.get(1)];
f_step = new Float(1.0) / new Float(steps.get(0) + 1);
f_mu = f_step;
non_null_idx.remove(0);
steps.remove(0);
}
else if (a[i] == null)
{
if (mode.equalsIgnoreCase("cosine"))
a[i] = CosineInterpolate(f_start, f_end, f_mu);
else
a[i] = LinearInterpolate(f_start, f_end, f_mu);
f_mu += f_step;
}
i++;
}
return a;
}
}
不知道是否有帮助? 这是非常快编码,因此,如果任何人有一个更好/更表演的方式做同样的,感谢贡献。
用法:
input : Float[] a = {1.0f, null, null, 2.0f, null, null, null, 15.0f};
call : Interpolator.Interpolate(a, "Linear");
output : 1.0|1.3333333|1.6666667|2.0|5.25|8.5|11.75|15.0
我知道这是一个古老的答案,但它是针对Java插值搜索时第一个谷歌的打击。该接受的答案提供了一些有用的链接,但JMSL必须购买,而JSpline +网站看起来粗略。
Apache的百科全书数学具有看似简单,功能和值得信赖的线性和样条内插的实施方式。
简单的线性内插可以使用类似计算:
Point2D interp1_lin(Point2D p1, Point2D p2, double x) {
//Pre conditions
assert p1.x<x;
assert x<p2.x;
//Calculate slope from p1 to p2
double m = (p2.x-p1.x)/(p2.y-p1.y);
//Calculate y position of x
double y = (x-p1.x)*m+p1.y;
//create new point
return new Point2D.Double(x,y);
}
这是否帮助?
您需要获得对应于y值x值。否则没有算法将能够确定是否[1,16,81]为x ^ 2为[1,4,9]或x ^ 4为[1,2,3]。你插值六个值或没有?
然后,当你给出的x值,可以使用某种内插方法的(直链的,花键kubic,你的名字)来近似缺失的数值。
轻量版本的一维数组线性内插的:
public static float[] interpolate(float[] data) {
int startIdx = -1;
float startValue = 0f;
float element;
for (int i = 0; i < data.length - 1; i++) {
element = data[i];
if (element != 0f) {
if (startIdx != -1) {
doInterpolate(startValue, element, startIdx + 1, i - startIdx - 1, data);
}
startValue = element;
startIdx = i;
}
}
return data;
}
private static void doInterpolate(float start, float end, int startIdx, int count, float[] data) {
float delta = (end - start) / (count + 1);
for (int i = startIdx; i < startIdx + count; i++) {
data[i] = start + delta * (i - startIdx + 1);
}
}
非常小心花键配合与多项式拟合。这两个可以给无意义的行为可以破坏的(什么被认为是的表示)的数据的多种用途。
数据的使用衍生物(斜率)任何可完全出轨。
你可以做最好的事情是图中的数据,明白它在做什么,然后才适合(线性,多项式,双对数)的回归;一旦你这样做,你应该画出你适合在原始数据,并确保你看到合理的协议。跳过该比较步骤是一个好主意。
某些数据集将不屈服于多项式拟合,数 - 对数等。;如果您的数据点被适当地分布在数据范围内没有什么错分段插值(线性或多项式等)。击败死马,如果使用分段插值避免任何使用您的分段插值的衍生物/斜坡,因为这将有不连续性,将导致东西表现不好。
你可以使用 apache共用数学 插 功能, 如 SplineInterpolator