Can';t使Jacobi算法在Objective-C中工作

Can';t使Jacobi算法在Objective-C中工作,objective-c,cocoa,Objective C,Cocoa,由于某种原因,我无法让这个程序运行。我让其他CS专业的学生看了看,他们也看不出来 该程序执行Jacobi算法(您可以看到分步指令和MATLAB实现)。顺便说一句,这与维基百科的同名文章不同 由于NSArray是一维的,因此我添加了一个方法,使其像二维C数组一样工作。在多次运行雅可比算法后,NSArray(i[0][0],i[1][1],等等)中的对角线项应该变大,而其他项接近0。但出于某种原因,它们都呈指数增长。例如,i[2][4]应该等于0.0000009,而不是999999,而i[2][2]

由于某种原因,我无法让这个程序运行。我让其他CS专业的学生看了看,他们也看不出来

该程序执行Jacobi算法(您可以看到分步指令和MATLAB实现)。顺便说一句,这与维基百科的同名文章不同

由于
NSArray
是一维的,因此我添加了一个方法,使其像二维C数组一样工作。在多次运行雅可比算法后,
NSArray
i[0][0]
i[1][1]
,等等)中的对角线项应该变大,而其他项接近0。但出于某种原因,它们都呈指数增长。例如,
i[2][4]
应该等于
0.0000009
,而不是
999999
,而
i[2][2]
应该很大

谢谢

克里斯

NSArray+Matrix.m
@实现NSArray(矩阵)
@动态偏移值,转置;
-(双倍)价值{
双和=0.0;
用于(MatrixItem*自身中的项目)
如果(项目.非对角线)
总和+=功率(项目值,2.0);
回报金额;
}
-(NSMutableArray*)转置{
NSMutableArray*转置=[[[NSMutableArray alloc]init]autorelease];
int i,j;
对于(i=0;i<5;i++){
对于(j=0;j<5;j++){
[transpose addObject:[self-objectAtRow:j和Column:i]];
}
}
返回转置;
}
-(id)objectAtRow:(nsInteger)行和列:(nsInteger)列{
整数索引=5*行+列;
return[self-objectAtIndex:index];
}
-(NSMutableArray*)multiplyWithMatrix:(NSArray*)数组{
NSMUTABLEARRY*结果=[[NSMUTABLEARRY alloc]init];
int i=0,j=0,k=0;
双重价值;
对于(i=0;i<5;i++){
对于(j=0;j<5;j++){
值=0.0;//(JeremyP的答案)
对于(k=0;k<5;k++){
MatrixItem*firstItem=[self-objectAtRow:i和Column:k];
MatrixItem*secondItem=[array objectAtRow:k和Column:j];
value+=firstItem.value*secondItem.value;
}
MatrixItem*项=[[MatrixItem alloc]initWithValue:value];
item.row=i;
第1项.列=j;
[结果添加对象:项];
}
}
返回结果;
}
@结束
Jacobi_算法AppDelegate.m
/。。。
-(无效)jacobiAlgorithmWithEntry:(MatrixItem*)条目{
MatrixItem*b11=[matrix objectAtRow:entry.row和Column:entry.row];
MatrixItem*b22=[matrix objectAtRow:entry.column和column:entry.column];
双muPlus=(b22.value+b11.value)/2.0;
muPlus+=sqrt(功率((b22.value-b11.value),2.0)+4.0*pow(entry.value,2.0));
Vector*u1=[[Vector alloc]initWithX:(-1.0*entry.value)andY:(b11.value-muPlus)]自动释放];
[u1正常化];
Vector*u2=[[Vector alloc]initWithX:-u1.y andY:u1.x]自动释放];
NSMutableArray*g=[[NSMutableArray alloc]init]autorelease];

对于(int i=0;i你对你的矩阵类别有任何单元测试吗?我的意思是,你确定乘法算法有效吗?我会说初始化值为0发生在错误的循环中。我认为你需要在j循环中进行

还有几个其他的观察结果:

  • 您不需要
    @dynamic
    属性声明,因为您自己定义属性的实现
  • 考虑创建您自己的矩阵类,它封装了一个普通的双精度C数组

您是否对矩阵类别进行了任何单元测试?我的意思是,您确定乘法算法有效吗?我会说,将值初始化为0发生在错误的循环中。我认为您需要在j循环中进行

还有几个其他的观察结果:

  • 您不需要
    @dynamic
    属性声明,因为您自己定义属性的实现
  • 考虑创建您自己的矩阵类,它封装了一个普通的双精度C数组

将平方根项添加到
muPlus
时,不能除以二。计算应为:

double muPlus = ( b22.value + b11.value ) / 2.0;
muPlus += sqrt( pow((b22.value - b11.value), 2.0) 
                + 4.0 * pow(entry.value, 2.0) 
              ) / 2.0;
或:

另外,您将
u1.y
分配给Gr、c和Gc,r。根据算法描述,您需要Gr、c=u1,2(或
u1.y
)和Gc、r=U2,1(或
U2.x
)。请注意,您实际上不需要
U2
;您可以用
-u1.y
代替
U2.x

离题 根据
-[NSArray multilywhithmatrix:应该返回一个自动释放的数组,因为被乘数应该放弃所有权。此外,您应该使用访问器将
GT*A*G
分配给
矩阵
,而不是直接进行分配,以便对其进行正确管理


由于循环中用于填写
g
的大多数测试在每次迭代期间都将是错误的,因此使用一些默认值填写
g
然后更新
g
可能更有效。您可以创建一个零矩阵,然后将对角线设置为1,然后从U中填写值,或者创建一个单位矩阵(将
i%6==0
测试留在循环中)然后填写U中的值。分析三种方法中的每种方法。

当您将平方根项添加到
muPlus
时,您不能除以二。计算应为:

double muPlus = ( b22.value + b11.value ) / 2.0;
muPlus += sqrt( pow((b22.value - b11.value), 2.0) 
                + 4.0 * pow(entry.value, 2.0) 
              ) / 2.0;
或:

另外,您将
u1.y
分配给Gr、c和Gc,r。根据算法描述,您需要Gr、c=u1,2(或
u1.y
)和Gc、r=U2,1(或
U2.x
)。请注意,您实际上不需要
U2
;您可以用
-u1.y
代替
U2.x

离题 根据,
-[NSArray
double muPlus = ( b22.value + b11.value ) / 2.0;
muPlus += sqrt( pow((b22.value - b11.value), 2.0) 
                + 4.0 * pow(entry.value, 2.0) 
              ) / 2.0;
double muPlus = ( b22.value + b11.value );
muPlus += sqrt( pow((b22.value - b11.value), 2.0) 
                + 4.0 * pow(entry.value, 2.0) );
muPlus /= 2.0;