PHP中的插值

PHP中的插值,php,interpolation,Php,Interpolation,我正在寻找PHP中的一个函数,用于将一组不规则放置的数据(x,y,z)插值到网格数据集中,以便在JPGraph中的ContourPlot函数中使用它。我开发了一个基于simple的函数,但是它太慢了。我需要使用另一种方法,如“改良谢泼德法”或任何其他可能的更精确的方法,使其更快、更平滑 这是我目前的代码: for($i = 0, $ij = 0; $i < $gridX; $i ++) { for($j = 0; $j < $gridY; $j ++, $ij ++) {

我正在寻找PHP中的一个函数,用于将一组不规则放置的数据(x,y,z)插值到网格数据集中,以便在JPGraph中的ContourPlot函数中使用它。我开发了一个基于simple的函数,但是它太慢了。我需要使用另一种方法,如“改良谢泼德法”或任何其他可能的更精确的方法,使其更快、更平滑

这是我目前的代码:

for($i = 0, $ij = 0; $i < $gridX; $i ++) {
    for($j = 0; $j < $gridY; $j ++, $ij ++) {
        $x = $startP->x + ($deltaX * $i);
        $y = $startP->y + ($deltaY * $j);
        $g [$ij]->i = $i;
        $g [$ij]->j = $j;
        $g [$ij]->x = ( int ) $x;
        $g [$ij]->y = ( int ) $y;
        $g [$ij]->z = IDW_U ( $x, $y, $sampleData, $sampleSize, $p );
    }
}

function IDW_U($x, $y, $data, $size, $p) {
    $idw_sum = IDWeightSum ( $x, $y, $data, $size, $p );
    $idw_u = 0.0;
    for($k = 0; $k < $size; $k ++) {
        if ($x == $data [$k]->x && $y == $data [$k]->y)
            return $data [$k]->z;
        $idw_u += IDWeight ( $x, $y, $data [$k], $p ) * $data [$k]->z / $idw_sum;
    }
    return $idw_u;
}

function IDWeightSum($x, $y, $data, $size, $p) {
    $sum = 0.0;
    for($k = 0; $k < $size; $k ++)
        $sum += IDWeight ( $x, $y, $data [$k], $p );
    return $sum;
}

function IDWeight($x, $y, $d, $p) {
    if ($x == $d->x && $y == $d->y)
        return 1.0;
    $dx = $x - $d->x;
    $dy = $y - $d->y;
    $ret = 1.0 / pow ( sqrt ( pow ( $dx, 2 ) + pow ( $dy, 2 ) ), $p );
    return $ret;
}
for($i=0,$ij=0;$i<$gridX;$i++){
对于($j=0;$j<$gridY;$j++,$ij++){
$x=$startP->x+($deltaX*$i);
$y=$startP->y+($deltaY*$j);
$g[$ij]>i=$i;
$g[$ij]>j=$j;
$g[$ij]>x=(int)$x;
$g[$ij]>y=(int)$y;
$g[$ij]>z=IDW_($x,$y,$sampleData,$sampleSize,$p);
}
}
函数IDW_($x,$y,$data,$size,$p){
$idw_sum=IDWeightSum($x,$y,$data,$size,$p);
$idw_=0.0;
对于($k=0;$k<$size;$k++){
如果($x==$data[$k]->x&&$y==$data[$k]->y)
返回$data[$k]->z;
$idw_+=IDWeight($x,$y,$data[$k],$p)*$data[$k]>z/$idw_总和;
}
返回$idw_;
}
函数IDWeightSum($x,$y,$data,$size,$p){
$sum=0.0;
对于($k=0;$k<$size;$k++)
$sum+=IDWeight($x,$y,$data[$k],$p);
返回$sum;
}
函数IDWeight($x、$y、$d、$p){
如果($x==$d->x&&$y==$d->y)
返回1.0;
$dx=$x-$d->x;
$dy=$y-$d->y;
$ret=1.0/pow(sqrt(pow($dx,2)+pow($dy,2)),$p);
返回$ret;
}

有人知道有一个函数或库可用于此目的吗?

如果您不喜欢PHP,您应该考虑尽可能多地放弃它,以进行这种密集的处理。PHP是一种较慢的语言(上次我看的时候),一年前Python和Ruby都比它好,C、C++和java都很出色。 通过切换到离线图形工具(如注释中提到的GnUrPro),重新运行性能测试,如果需要,将算法切换到Python或Ruby脚本或编译的C或C++应用程序,则会获得性能提升。


但是,自2008年末/2009年初以来,与其他语言相比,我找不到任何关于PHP的最新性能数据-我的数据可能不再真实。

这可能有助于您通过引用传递数据:

 function IDW_U($x, $y, &$data, $size, $p) ...
 function IDWeightSum($x, $y, &$data, $size, $p) ...

我不确定PHP对于这样的数学密集型功能是否是一个好的选择。但是,有很多图形库,其中的代码已经过优化,放入DLL中,诸如此类


我们已经使用高级软件工程ChartDirector处理了一些相当复杂的图形,而且速度很快。我不确定它是否包含您感兴趣的算法,但它确实包含一些类似LOWESS的算法。我看到的主要问题是您处理的是X、Y和Z。处理三维并不是最常见的功能我不确定这个库是否真的支持…

据我所知,IDWeight经常被调用。通过这样计算IDW\U,您可以将调用次数减少一半:

function IDW_U($x, $y, $data, $size, $p) {
$idw_sum = 0.0;
$idw_u = 0.0;
for($k = 0; $k < $size; $k ++) {
    if ($x == $data [$k]->x && $y == $data [$k]->y)
        return $data [$k]->z;
    $iw = IDWeight ( $x, $y, $data [$k], $p )
    $idw_u += $iw * $data [$k]->z;
    $idw_sum += $iw;
}
return $idw_u / $idw_sum;
}
函数IDW_($x,$y,$data,$size,$p){
$idw_sum=0.0;
$idw_=0.0;
对于($k=0;$k<$size;$k++){
如果($x==$data[$k]->x&&$y==$data[$k]->y)
返回$data[$k]->z;
$iw=IDWeight($x,$y,$data[$k],$p)
$idw_+=$iw*$data[$k]->z;
$idw_sum+=$iw;
}
返回$idw_/$idw_总和;
}

我认为主要的问题是,对于一个像素的计算,所有的数据集都会被使用,而大多数数据集的影响都很小。你可以通过将数据分割成小区域并分别计算所有区域来提高性能。

发布你的代码太慢了。可能会有一些重大的优化…嗯,我认为
gnuplot
几乎可以插值并生成相同的质量(或更好)作为JPGraph。也许这是一个选择?虽然这是一个陡峭的学习曲线,但我可以有把握地说,我不知道gnuplot能做什么的2%。这种赏金可能会帮助你得到一些答案。这并不能解决真正的问题,但你可能对Facebook的HipHop感兴趣,它通过编译为本机代码来加速PHP。谢谢你的推荐。Alth虽然我必须有自己的代码,但我看了一下,并将其作为替代解决方案进行了测试。实际上,它工作得很好。它具有为散乱数据创建等高线图的功能,速度非常快。