以上是计算实习的题目。
说说我遇到的问题吧。
1、初始向量的选择对迭代结果的影响问题
我在刚开始做第一题时就遇到了一个大问题:得到的结果虽然收敛,但是却与正确答案不相符。刚开始我设置的初始迭代向量 为(1,0,0,……,0),用幂法计算λ得到的结果是-0.208098108534e+01,迭代次数为280次。这个错误几乎令我想要放弃,因为我已经通过在代码的各个地方设置断点不断缩小可能出错的地方,但是直到第二天我仍没有找到错在哪。直到我上网看到了幂法的收敛与否不仅与特征值分布有关,还与初始迭代向量有关,于是我修改了迭代向量 为(1,1,1,……,1),得到的答案果然完全正确!之后的题目就可以说是势如破竹,在很短的时间内就完成了。
2、关于预编译时发生堆栈溢出的问题
第一次调试,系统就提示Stack overflow,随后编译停留在了汇编指令test dword ptr[ecx],eax上。于是我重新编译,采取单步执行,随后报错:please enter the file for :CHKSTK.ASM。上网查找这两个错误后,得知原因是声明的函数大量使用了传值,要想解决问题,必须将函数的传参方式尽可能改为传递指针(引用)。我发现在第一次编写代码时,例如矩阵与向量相乘的函数,我对函数参数的定义就是直接将矩阵里所有的值传递到函数中,若改为将指针传进函数,将解决预编译栈溢出的问题。
3、向量可重复利用的问题
修改这个问题之前,我声明了一个大小为MAXSTEP=10000的向量数组μ,每个向量中又有501个double型的分量,占用了大量的空间,导致调试时发生了卡顿现象,因为内存被分配了太多。
幂法中用到的向量μ虽然确实有迭代步数k次,但经过一步后,前一步用过的向量将不再会用到,所以只需要声明两个向量 进行交替存储即可。
以下是最终输出的答案:
lamda1的值为-0.107001136151E+2。
lamda501的值为0.972463409986E+1。
lamda_s的值为-0.555791079422E-2。
lamda_i1的值为-0.101829340331E+2。
lamda_i2的值为-0.958570742507E+1。
lamda_i3的值为-0.917267242393E+1。
lamda_i4的值为-0.865228400790E+1。
lamda_i5的值为-0.809348380868E+1。
lamda_i6的值为-0.765940540769E+1。
lamda_i7的值为-0.711968464869E+1。
lamda_i8的值为-0.661176433940E+1。
lamda_i9的值为-0.606610322660E+1。
lamda_i10的值为-0.558510105263E+1。
lamda_i11的值为-0.511408352981E+1。
lamda_i12的值为-0.457887217687E+1。
lamda_i13的值为-0.409647092626E+1。
lamda_i14的值为-0.355421121575E+1。
lamda_i15的值为-0.304109001813E+1。
lamda_i16的值为-0.253397031113E+1。
lamda_i17的值为-0.200323076956E+1。
lamda_i18的值为-0.150355761123E+1。
lamda_i19的值为-0.993558606008E-0。
lamda_i20的值为-0.487042673885E-0。
lamda_i21的值为0.223173624957E-1。
lamda_i22的值为0.532417474207E-0。
lamda_i23的值为0.105289896269E+1。
lamda_i24的值为0.158944588188E+1。
lamda_i25的值为0.206033046027E+1。
lamda_i26的值为0.255807559707E+1。
lamda_i27的值为0.308024050931E+1。
lamda_i28的值为0.361362086769E+1。
lamda_i29的值为0.409137851045E+1。
lamda_i30的值为0.460303537828E+1。
lamda_i31的值为0.513292428390E+1。
lamda_i32的值为0.559490634808E+1。