Scilab四舍五入错误

时间:2016-03-12 14:22:40

标签: scilab

我无法解决Scilab中的问题,因为它因为舍入错误而被卡住了。我收到了消息

!--error 9999 
Error: Round-off error detected, the requested tolerance (or default) cannot be achieved. Try using bigger tolerances.
at line       2 of function scalpol called by :  
at line       7 of function gram_schmidt_pol called by :  
gram_schmidt_pol(a,-1/2,-1/2)

这是一个Gram Schmidt过程,具有两个函数的积分和作为标量积的权重,介于-1和1之间。 gram_schmidt_pol是专为多项式设计的过程,scalpol是为多项式描述的标量积。

ab是重量的参数,即(1+x)^a*(1-x)^b

该条目是一个表示一组向量的矩阵,它与矩阵[[1;2;3],[4;5;6],[7;8;9]]配合得很好,但它在矩阵eye(2,2)上失败并出现上述消息错误,除此之外,我需要在眼睛上做(9,9)!

我在菜单中找了一个“容差设置”,General->Preferences->Xcos->Simulation中有一些,但我相信这不是我想要的,我尝试了低设置(高容忍度)和它没有改变任何东西。

那么我该如何解决这个问题呢?

随意告诉我,我的信息缺乏清晰度。 谢谢。

编辑:功能代码:

// function that evaluate a polynomial (vector of coefficients) in x
function [y] = pol(p, x) 
    y = 0
    for i=1:length(p)
        y = y + p(i)*x^(i-1)
    end
endfunction

// weight function evaluated in x, parametrized by a and b
// (poids = weight in french)
function [y] = poids(x, a, b)
    y = (1-x)^a*(1+x)^b
endfunction

// scalpol compute scalar product between polynomial p1 and p2
// using integrate, the weight and the pol functions.
function [s] = scalpol(p1, p2, a, b)
    s = integrate('poids(x,a, b)*pol(p1,x)*pol(p2,x)', 'x', -1, 1)
endfunction

// norm associated to scalpol
function [y] = normscalpol(f, a, b)
    y = sqrt(scalpol(f, f, a, b))
endfunction

// finally the gram schmidt process on a family of polynome
// represented by a matrix
function [o] = gram_schmidt_pol(m, a, b)
    [n,p] = size(m)
    o(1:n) = m(1:n,1)/(normscalpol(m(1:n,1), a, b))
    for k = 2:p
        s =0 
        for i = 1:(k-1)
            s = s + (scalpol(o(1:n,i), m(1:n,k), a, b) / scalpol(o(1:n,i),o(1:n,i), a, b) .* o(1:n,i))
        end
        o(1:n,k) = m(1:n,k) - s
        o(1:n,k) = o(1:n,k) ./ normscalpol(o(1:n,k), a, b)
    end
endfunction

1 个答案:

答案 0 :(得分:0)

默认情况下,Scilab的integrate('x', 'x', -1, 1) 例程尝试实现最多1e-8的绝对误差和最多1e-14的相对误差。这是合理的,但是它对相对误差的处理没有考虑精确值为零时发生的问题。 (见How to calculate relative error when true value is zero?)。出于这个原因,即使是简单的

integrate('...', 'x', -1, 1, 1e-8, 1)

抛出错误(在Scilab 5.5.1中)。

这就是在运行程序的过程中发生的事情:一些积分为零。有两种解决方案:

(A)放弃相对误差界限,将其指定为1:

integrate('100 + ... ', 'x', -1, 1) - 200

(B)向正在积分的函数添加一些常量,然后从结果中减去:

gram_schmidt_pol(eye(2,2), -1/2, -1/2)

(后者应该适用于大多数情况,但如果积分恰好是-200,你会再次遇到同样的问题)

以上适用于gram_schmidt_pol(eye(9,9), -1/2, -1/2),但对于较大的,例如inttrap,它会引发错误"积分可能是发散的,或者是慢慢收敛的#34;。

似乎自适应集成例程无法处理您所拥有的那种功能。后备是使用简单的function [s] = scalpol(p1, p2, a, b) t = -0.9995:0.001:0.9995 y = poids(t,a, b).*pol(p1,t).*pol(p2,t) s = inttrap(t,y) endfunction 代替,它只应用梯形规则。由于在x = -1和1处未定义函数poids,因此必须排除端点。

function [y] = pol(p, x) 
    y = 0
    for i=1:length(p)
        y = y + p(i)*x.^(i-1)
    end
endfunction

function [y] = poids(x, a, b)
    y = (1-x).^a.*(1+x).^b
endfunction

为了使其工作,必须对其他相关函数进行矢量化(*和^在必要时更改为。*和。^):

{{1}}

结果保证可以正常工作,虽然精度可能会低一些:你会得到一些像3D-16这样的数字,实际上是零。