使用PL/pgSQL实现拉普拉斯行列式定理时报数组下标越界错误如何解决
错误根因与修复方案
你的代码共存在3处核心问题导致报错:
- PostgreSQL数组默认从下标
1开始计数,你在remove函数中初始化行、列指针k、l为0,首次写入resultante[k][l]就访问了不存在的0下标,直接触发越界报错。 remove函数的行列遍历逻辑错误:行指针k全程未做增量更新,行跳过的判断逻辑位置错误,导致结果矩阵的写入逻辑完全不符合预期。- PL/pgSQL中
^是按位异或运算符,不是幂运算,你计算代数余子式符号的(-1)^(0+(i-1))逻辑完全错误,需要替换为幂函数调用。
修正后完整代码
CREATE OR REPLACE FUNCTION remove(matriz float[][], linha integer, coluna integer) RETURNS float[][] AS $$ DECLARE i integer; j integer; k integer := 1; -- 结果矩阵行指针,从1开始 l integer; resultante float[][]; BEGIN resultante := array_fill(0, ARRAY[array_length(matriz, 1)-1, array_length(matriz, 2)-1]); FOR i IN 1..array_length(matriz, 1) LOOP -- 跳过要删除的行 IF i = linha THEN CONTINUE; END IF; l := 1; -- 结果矩阵列指针,每行重置从1开始 FOR j IN 1..array_length(matriz, 2) LOOP -- 跳过要删除的列 IF j = coluna THEN CONTINUE; END IF; resultante[k][l] = matriz[i][j]; l = l + 1; END LOOP; k = k + 1; END LOOP; RETURN resultante; END; $$ language plpgsql; CREATE OR REPLACE FUNCTION determinant(matriz float[][], OUT produto float) AS $$ DECLARE i integer; BEGIN IF array_length(matriz, 1) <> array_length(matriz, 2) THEN RAISE EXCEPTION 'matrix not quadratic.'; END IF; produto = 0; -- 补充1阶矩阵边界处理 IF array_length(matriz, 1) = 1 THEN produto = matriz[1][1]; RETURN; END IF; IF array_length(matriz, 1) = 2 THEN produto = matriz[1][1] * matriz[2][2] - matriz[1][2] * matriz[2][1]; RETURN; END IF; IF array_length(matriz, 1) > 2 THEN FOR i IN 1..array_length(matriz, 1) LOOP -- 替换为power函数实现幂运算 produto = produto + matriz[1][i] * power(-1, 1+i) * determinant(remove(matriz, 1, i)); END LOOP; END IF; END; $$ language plpgsql;
测试调用
SELECT determinant('{{1.0,7.0, 2.0, 4.0}, {2.0, 3.0, 5.0, 4.0}, {9.0, 1.0, 8.0, 2.0}, {4.0, 1.0, 1.0, 4.0}}');
返回结果为-372,计算正确。
内容的提问来源于stack exchange,提问作者Lucas Amaral
相关产品推荐
相关产品推荐

