首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >首先正确读取数组中的C++元素,然后在没有更改的情况下给出一个NaN,这怎么可能?

首先正确读取数组中的C++元素,然后在没有更改的情况下给出一个NaN,这怎么可能?
EN

Stack Overflow用户
提问于 2013-10-15 07:24:37
回答 2查看 843关注 0票数 1

我正经历着我编程生涯中最奇怪的问题。我正在执行一个图像分析,一个大约800x800x600元素的三维体积,从每个像素中提取一个建立在灰度上的恒河矩阵,然后计算一些代数(使用本征)来检测体积中所描述的纤维的排列。

要构建卷,我使用从nhdr+raw文件读取的doublexz数组。到目前为止,对于域问题的介绍还是不错的。

我执行的分析除以子卷中的大容量(总体执行时间约为14小时,但这是预期的,就像科学分析软件一样)。在某一点上,当我在数组的x=(max-2) (在边框之前停止分析2个像素)索引时,对于两个元素(79276和79256,但在这些元素之后可能还有其他元素,可能还有x=max ),我的特征函数突然失效。

Debuggin我发现,为了构造Hessian矩阵的偏导数,我访问了元素x+2z,得到了它的NaN,因此在对它进行运算时,显然本征发疯了。

最奇怪的是,如果在软件开始时(在加载卷之后),如果我打印这个确切元素的值,它就存在,而且它也有一个有意义的值。怎么可能??我运行了几次这个软件,对于相同的两个像素,同一个位置上的相同的错误,所以甚至猜测它可能是一个RAM错误,它不应该因为我的PC上发生的其他事情而波动和改变位置吗?

我做了更深入的测试。我在子卷上循环,在那里一切都很好(我一直在跟踪固定的volume[]元素的值,故障就是在这个元素上显示出来的)像素值在以下函数之外保持不变,该像素一个像素一个像素地分析子卷。正如我所知道的,我感兴趣的像素的值是51941 (在进入给出的subvolum的下面的函数之前),当值发生变化时,我会对其进行防范。

这里发生了什么>子卷开始时的像素值:51941元素:5982;636,260,62;循环中的像素值: 1.65031e-22

在5982个循环之后(对于整个子卷大约需要300万次),值就会发生变化,在下面的代码中,我会触摸它!是什么导致了这样的事情?

代码语言:javascript
复制
Matrix3d HesseAnalysis(int subX, int subY, int subZ, int maxX, int maxY, int maxZ){

//int maxX = subX+deltaX;
//int maxY = subY+deltaY;
//int maxZ = subZ+deltaZ;

int counter=0;

for (int x=subX;x<(maxX-2);x++){
    for (int y=subY;y<(maxY-2);y++){
        for (int z=subZ;z<(maxZ-2);z++){


            if(volume[792][247][76]!=51941){
                cout << "Element :" << counter << "; " << x << "," << y << "," << z << ";" << endl;
                cout << "Pixel value in loop: " << volume[792][247][76]<< endl;
                exit(0);
            }

            fxx=((volume[x+2][y][z]-volume[x][y][z])/2-(volume[x][y][z]-volume[x-2][y][z])/2)/2;
            fyy=((volume[x][y+2][z]-volume[x][y][z])/2-(volume[x][y][z]-volume[x][y-2][z])/2)/2;
            fzz=((volume[x][y][z+2]-volume[x][y][z])/2-(volume[x][y][z]-volume[x][y][z-2])/2)/2;
            fxy=((volume[x+1][y+1][z]-volume[x+1][y-1][z])-(volume[x-1][y+1][z]-volume[x-1][y-1][z]));
            fxz=((volume[x+1][y][z+1]-volume[x+1][y][z-1])-(volume[x-1][y][z+1]-volume[x-1][y][z-1]));
            fyz=((volume[x][y+1][z+1]-volume[x][y+1][z-1])-(volume[x][y-1][z+1]-volume[x][y-1][z-1]));

            //compose hessian matrix for the pixel, remember that  
 hessian <<     fxx, fxy, fxz,
    fxy, fyy, fyz,
    fxz, fyz, fzz;

//extract eigenvalues and choose the eigenvector related to the smallest eigenvalue,
//and do the outer product of it with itself

EigenSolver<Matrix3d> solver(hessian);
int minorEigen = minorEigenvalue(solver.eigenvalues().real());
Vector3d v3 =solver.eigenvectors().col(minorEigen).real();
V3outerV3 = v3*v3.transpose();
OuterProducts[(x-subX)-2][(y-subY)-2][(z-subZ)-2]= V3outerV3;

counter++;

            }
        }
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-16 15:02:06

我找到了。我仍然没有时间去探究真正的原因,但这取决于艾根的一个可能的缺陷。

这一行是造成混乱的原因:

=solver.eigenvectors().col(minorEigen).real();Vector3d v3

由于某种原因,在某一点上,它决定入侵已分配给我的卷数组的内存,这是最奇怪的部分,我用来测试的像素volume79276值根据变量minorEigen的值而改变(即只返回函数中最小特征值的索引)。

例如,当minorEigen =0时,像素变为1.65031e-22,minorEigen =1时,像素变为2.1402e+5.我猜是个假指针或者类似的虫子。我将调查本征错误报告,检查更新版本,或以其他方式为矩阵实现我自己的本机。

票数 1
EN

Stack Overflow用户

发布于 2013-10-15 11:05:57

通常C/C++使用基于0的索引。如果您不希望您的x超出范围,您是否应该停在x=max-3,以便索引可以保持在从0max-1的范围内?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19375445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档