- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我正在研究 Lanczos 算法的收敛。我用 C 语言实现它,首先计算与 Krylov 子空间相关的正交矩阵 V 和三对角对称矩阵 T,然后计算 T 的特征值和特征向量以及 Ritz vector 来定义如果未达到容差,则为即将到来的迭代初始化 vector 。
在 while 循环中,我在进行下一次迭代之前验证是否达到容差。该程序编译,但当我执行它时,我在 3 次迭代后得到一个段错误核心转储,我使用 -g 进行编译,gdb 告诉我,我在计算 Ritz 矩阵(或 Ritz vector )的循环中有一个核心转储是矩阵 A 特征向量):
for(int i = 0 ; i < N ; i++)
Ritz[i][k] = temp[i];
我认为我的程序编写正确,但我不知道问题出在哪里。我很感激你对这些人的帮助!PS:编译 gcc -g -Wall -std=c99 test.c -o test -llapacke -lm
代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <float.h>
#include <lapacke.h>
double Absolute_value(double numb)
{
if(numb < 0)
return (double)((-1)*(numb));
else
return numb;
}
double Forbenius_norm(double ** A, int N)
{
double forbenius_norm = 0.000000;
for(int i = 0 ; i < N ; i++)
{
for(int j = 0 ; j < N ; j++)
{
forbenius_norm += abs(A[i][j])*abs(A[i][j]);
}
}
forbenius_norm = sqrt(forbenius_norm);
return forbenius_norm;
}
double Norme_vector(double * v, int N)
{
double norme= 0.;
double somme = 0.;
int i;
for (i = 0; i < N; i++){
somme += (v[i] * v[i]);
}
norme = sqrt(somme);
return norme;
}
double * Prod_Scal_Vect(double * v, int t, double e)
{
double * prod =(double *) malloc ( t* sizeof( double));
int i;
for( i = 0; i < t ; i++){
prod[i] = e * v[i];
}
return prod;
}
double * Div_vect_scal(double * v, int t, double e)
{
double * prod =(double *) malloc ( t* sizeof( double));
int i;
for( i = 0; i < t ; i++){
prod[i] = v[i]/e;
}
return prod;
}
double Self_Dot_Prod(double *v,int t,double *w,int s)
{
double res = 0.;
int i;
if( t != s )
printf("Erreur : deux vecteurs non conformes au produit scalaire\n");
else
{
for( i = 0; i < t; i++)
{
res += v[i] * w[i];
}
//return res;
}
return res;
}
double * vect_Sub(double *v,int t,double *w,int s)
{
double * res = (double *) malloc ( s * sizeof(double));
int i;
if( t != s )
printf("Erreur : deux vecteurs non conformes à l'addition de vecteurs\n");
else
{
for( i = 0; i < t; i++)
{
res[i] = v[i] - w[i];
}
//return res;
}
return res;
}
double * Prod_Mat_Vect( double ** A, int nbl, int nbc, double * v, int t)
{
//double * res = calloc ( nbl, sizeof( double));
double * res =(double *) malloc ( nbl* sizeof( double));
double somme = 0.;
int i,j;
if(t != nbc)
{ perror(" erreur 4");
return NULL;
}
else
{
for( i = 0; i < nbl; i++)
{
somme = 0.;
for( j = 0; j < nbc; j++)
{
somme += v[j] * A[i][j];
}
res[i] = somme;
}
return res;
}
}
double * assign_vect(double * v, int n, double * w, int m)
{
if( n != m)
printf("Erreur: La taille des deux vecteurs doit être identique pour l'affectaion\n");
else
{
for(int i = 0 ; i < n ; i++)
v[i] = w[i];
//return v;
}
return v;
}
void print_matrix( double ** A , int m , int n) {
int i, j;
for( i = 0; i < m; i++ )
{
for( j = 0; j < n; j++ )
{
printf( " %lf", A[i][j] );
}
printf( "\n" );
}
}
int main (int argc , char ** argv)
{
int N=4;
int m = 2;
//int lda = m;
double ** A = (double **) malloc ( N * sizeof(double*) );
for( int i = 0 ; i < N ; i++ )
A[i] = (double*) malloc( N * sizeof(double) );
double ** T = (double **) malloc( m * sizeof(double*) );
for( int i = 0 ; i < m ; i++ )
T[i] = (double *) malloc ( m * sizeof(double) );
double ** Krylov = (double **) malloc (N * sizeof(double*) );
for( int i = 0 ; i < N ; i++ )
Krylov[i] = (double *) malloc( m * sizeof(double) );
double ** Ritz = calloc( N , sizeof(double*) );
for( int i = 0 ; i < N ; i++ )
Ritz[i] = calloc( m , sizeof(double*) );
double ** Eigenvect_matrix = calloc ( m , sizeof(double*));
for( int i = 0 ; i < m ; i++ )
Eigenvect_matrix[i] = calloc ( m , sizeof(double));
double * v = (double *) malloc(N * sizeof(double));
double * init = (double *) malloc (N * sizeof(double));
double * gamma = (double *) malloc(N * sizeof(double));
double * eigenvect = calloc(m,sizeof(double));
double * tab = calloc(m,sizeof(double));
double * temp = calloc(N,sizeof(double));
double * a = calloc(m*m,sizeof(double));
double * w = calloc(m,sizeof(double));
double beta = 0.000000;
double alpha = 0.000000;
int j=0;
int k=1;
int info = -1;
int n=m,lda=m;
int count = 0;
double test_tolerance = 999;
A[0][0]= 9; A[0][1]= 1;A[0][2]= -2;A[0][3]= 1;
A[1][0]= 1; A[1][1]= 8;A[1][2]= -3;A[1][3]= -2;
A[2][0]= -2;A[2][1]= -3;A[2][2]= 7;A[2][3]= -1;
A[3][0]= 1; A[3][1]= -2;A[3][2]= -1;A[3][3]= 6;
printf("\n\n\tOriginal Matrix A before Lanczos Algorithm\n\n");
for(int i = 0 ; i < N ; i++)
{
for(int j = 0 ; j < N ; j++)
{
printf("%lf\t",A[i][j]);
}
printf("\n");
}
v[0] = 1.000000;
for(int i = 0 ; i < N ; i++)
init[i] = 0.000000;
for(int i = 1 ; i < N ; i++)
v[i] = 0.000000;
for(int i = 0 ; i < N ; i++)
Krylov[i][0] = v[i];
while(test_tolerance > 0.00001 || count != 50)
{
printf("iteration: %d\n",count+1);
for(int l = 0 ; l < m-1 ; l++)
{
gamma = Prod_Mat_Vect(A, N, N, v, N);
alpha = Self_Dot_Prod(v, N, gamma, N);
gamma = vect_Sub(gamma,N,vect_Sub(Prod_Scal_Vect(v, N,alpha),N,Prod_Scal_Vect(init, N,beta),N),N);
init = assign_vect(init, N, v, N);
beta = Norme_vector(gamma, N);
v = Div_vect_scal(gamma, N, beta);
for(int i = 1 ; i < N ; i++)
{
Krylov[i][k] = v[i];
}
k++;
T[l][l] = alpha;
T[l+1][j] = beta;
T[l][j+1] = beta;
j++;
}
gamma = Prod_Mat_Vect(A, N, N, v, N);
alpha = Self_Dot_Prod(v, N, gamma, N);
T[m-1][m-1] = alpha;
gamma = vect_Sub(gamma,N,vect_Sub(Prod_Scal_Vect(v, N,alpha),N,Prod_Scal_Vect(init, N,beta),N),N);
init = assign_vect(init, N, v, N);
test_tolerance = Norme_vector(gamma, N);
//printf("tolerance1 %lf\n",test_tolerance);
test_tolerance = Absolute_value(test_tolerance);
//printf("tolerance2 %lf\n",test_tolerance);
/*printf("\n\n\tTridiagonal Matrix T\n\n");
for(int i = 0 ; i < m ; i++)
{
for(int j = 0 ; j < m ; j++)
{
printf("%lf\t",T[i][j]);
}
printf("\n");
}*/
//printf("\n\n\tLinearied matrix\n\n");
for(int i = 0 ; i < m ; i++ )
{
for(int j = 0 ; j < m ; j++)
{
a[i*m+j] = T[i][j];
//printf("a[%d][%d]%lf ",i,j,a[i*m+j]);
}
//printf("\n");
}
/*printf("\n\n\tKrylov Matrix \n\n");
for(int i = 0 ; i < N ; i++)
{
for(int j = 0 ; j < m ; j++)
{
printf("%lf\t",Krylov[i][j]);
}
printf("\n");
}
*/
info = LAPACKE_dsyev( LAPACK_ROW_MAJOR, 'V', 'U', n, a, lda, w );
/*printf("\n\n\tEigenvectors\n\n");
for(int i = 0 ; i < m ; i++ )
{
for(int j = 0 ; j < m ; j++)
{
printf("%lf\t",a[i*m+j]);
}
printf("\n");
}
*/
//printf("\n\n\tDelinearized a for eigen vetors\n\n");
for(int i = 0 ; i < m ; i++ )
{
for(int j = 0 ; j < m ; j++)
{
Eigenvect_matrix[i][j] = a[i*m+j];
//printf("%lf\t",Eigenvect_matrix[i][j]);
}
//printf("\n");
}
for(int i = 0 ; i < m ; i++)
tab[i] = w[i];
/*printf("\n\tEigenvalues\n\n");
for(int j = 0 ; j < m ; j++)
printf("%lf\t",tab[j]);
printf("\n");
*/
int index = 0;
for(int k = 0 ; k < m ; k++)
{
for(int i = 0 ; i < m ; i++)
{
eigenvect[i] = a[index];
index++;
}
test_tolerance *= Absolute_value(eigenvect[m-1]);
/*for(int j = 0 ; j < m ; j++)
printf("%lf\t",a[j]);*/
temp = Prod_Mat_Vect(Krylov, N, m, eigenvect, m);
for(int i = 0 ; i < N ; i++)
{
Ritz[i][k] = temp[i];
printf("\ti=%d ,\tk=%d\n",i,k);
}
}
printf("tolerance : %lf\n",test_tolerance);
count++;
printf("\n");
for(int i = 0 ; i < N ; i++)
{
init[i] = Ritz[i][0] + Ritz[i][1];
init[i] /= Norme_vector(init,N);
}
}
/*printf("\n\n\tRitz vectors\n\n");
for(int i = 0 ; i < N ; i++)
{
for(int j = 0 ; j < m ; j++)
{
printf("%lf\t",Ritz[i][j]);
}
printf("\n");
}*/
return 0;
}
最佳答案
你有内存损坏。您在某一时刻覆盖了“Ritz[0]”的值。您可以通过在崩溃发生后在 GDB 中打印 Ritz
和 Ritz[0]
的值来找出这一点。
然后要找出它被覆盖的位置,请在分配后设置一个断点(例如第 183 行)并运行程序直到该断点。然后使用watch Ritz[0]
命令告诉GDB在写入该位置时中断。让gdb继续。它到达这个循环:
for(int i = 1 ; i < N ; i++)
{
Krylov[i][k] = v[i];
}
其中i=3
和k=4
。 Krylov 有 N
(4) 个元素,但每个子数组只有 m
(2) 个元素。这就是你要出界的地方。
现在,我可以看到围绕该 for 循环的循环正在检查 l
,并在运行时增加 k
。但是,我认为您在外部 while 循环内的开头缺少一个 k = 1
(第 236 行)。
修复该问题后,您会遇到另一次崩溃。您在第 121 行 (somme += v[j] * A[i][j];
) 崩溃,其中 i=0
和 j=0
。看起来A[0]
在这里被覆盖了,再次在GDB中打印它证实了这一点。由于 A
是一个参数,我们需要找出它实际来自哪个变量,因此用 bt
查看堆栈,我们发现它来自 test.c :346
:
temp = Prod_Mat_Vect(Krylov, N, m, eigenvect, m);
所以A
有Krylov
。看起来 Krylov[0]
被覆盖了,所以让我们对观察点执行与 Ritz[0]
相同的操作。
GDB 将我们带到第 256 行 (T[l][j+1] = beta;
),其中 l=0
和 j=4
。同样,T
的子数组仅分配了 2 个元素,因此 j
的值显然是错误的。再次查看循环的结构,这与上次的错误完全相同,只是变量不同。
在外部 while 循环的开头设置 j = 0
(同样是第 236 行)也可以修复此问题。
这似乎就是立即和灾难性的内存损坏,因为程序在此之后运行良好。
<小时/>在一个不太重要的说明上,你在这里有一个错误,这应该是sizeof(double)
:
for( int i = 0 ; i < N ; i++ )
Ritz[i] = calloc( m , sizeof(double*) );
关于c - 3 次迭代后重新启动 Lanczos 方法时出现段错误 coredump,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34822262/
我搜索了重启我的 android 应用程序的替代方法,但我发现重启的唯一方法是使用 Flex 构建. 我可以用 as3 flash 重启我的 android adobe air 应用程序吗?我该怎么做
我有一个学校评估,是为了制作一个 child 的拼写游戏,当玩家单击"is"时,它必须循环/重新启动。到目前为止,当我测试游戏时,询问玩家是否想再次玩的选项/easygui.buttonbox 以
在.yml文件中,我定义了:restart: always。是否可以将此重启创建为--force-recreate标志的等效项? 我的XVFB有问题,标准重启无法解决问题,但通过--force-rec
我正在尝试重新启动 while 循环。我已经声明了 boolean 类型的变量 keepGoing 。如果 int 变量 x 超出窗口,则 keepGoing 更改为 false。然后reset()方
如何使用 Cast SDK 或其他方式让我的应用以官方 Chromecast 应用的方式触发 Chromecast 重启? 如果是“否则”,Google Play 可能会对这种做法不友善吗? 最佳答案
运行/etc/init.d/postgresql restart有没有危险?我们刚刚发生了一些关系“消失”的事件,我运行了上述命令。刚刚被系统管理员骂了一顿,但是他没有解释为什么这是一件坏事。我确实将
是否可以重新启动 while 循环?我目前在 foreach 循环中存在一个 while 循环,并且每次都需要 while 语句从头开始。 $sql = mysqli_query($link, "SE
我有如下倒计时器: - (void)updateCounterLabel:(NSTimer *)theTimer { if(secondsLeft > 0 ){ secondsLeft
就像我在 python 中一样。 choice1 = raw_input('John Blue Green') if choice1 == 'A': print('blah') elif cho
我的游戏在 True 循环中运行一段时间,我希望能够要求用户“再玩一次?”我已经有了用于弹出文本的矩形的代码,但我需要一种方法让用户单击矩形或按 y 表示是,然后代码再次自行运行。 最佳答案 在您的主
我是 nginx 的初学者。我正在使用 Ubuntu 16.04。我按照步骤操作, sudo apt-get 更新。 sudo apt-get install nginx sudo apt-get 升
我需要使用 javascript 重放一个 css 转换。当我重置我的 div 的 css 样式并应用新的过渡时,没有任何反应...... 我认为这两个代码是在同一个执行框架中执行的,并且通过优化,它
所以我有这几行代码: string[] newData = File.ReadAllLines(fileName) int length = newData.Length; for (int i =
所以我有一个计时器,每 5 秒旋转一组图像。因此,我在文档启动时运行它。 $(document).ready(function() { var intervalID=setInterval(funct
好吧,我在重新启动 Apache 服务器时遇到了一些问题。我修改了服务器上的 ulimit 但我无法重新启动 httpd; 我在 CentOS 5.8 x64 上运行服务器. httpd -V 的输出
我在使用 docker 时遇到问题 docker ps不会返回并被卡住。 我发现做 docker service restart 之类的sudo service docker restart (htt
从 .net 代码停止和重新启动 Storyboard的正确方法是什么? 我想 ... myStory.Stop(this); 期望随后调用 .Begin(this);将从零开始从时间线重新开始,但
我有一个带有一些缓存后端的应用程序,我想在重新启动网络服务器时清除缓存。 在网络服务器(重新)启动时是否有 apache 配置指令或任何其他方式来执行 shell 脚本? 谢谢, 菲尔 正如一些答案已
我愿意在我的应用程序中添加一个按钮,单击该按钮将重新启动应用程序。我搜索了谷歌,但发现除了 this one 没有任何帮助.但是这里遵循的程序违反了 Java 的 WORA 概念。 是否还有其他以 J
我们目前遇到间歇性邮件队列中断。我是 seeking diagnostic help in another area . 同时,有没有办法在不重启整个服务的情况下重启CF邮件队列? CF8标准 Win
我是一名优秀的程序员,十分优秀!