Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Frobenius范数溢出问题及其在MATLAB中的实现_Matlab_Math_Computer Science - Fatal编程技术网

Frobenius范数溢出问题及其在MATLAB中的实现

Frobenius范数溢出问题及其在MATLAB中的实现,matlab,math,computer-science,Matlab,Math,Computer Science,我在MATLAB中实现了福布斯范数的以下定义 按照描述的方式(即,我对循环做了2次,并通过对每个元素进行平方运算来增加一个和,最后取和的平方根) 我的问题是,有没有一种方法可以实现这个标准,这样如果我在矩阵中输入一个相当大的数字,它的平方就不会溢出?函数在某些情况下返回“无穷大”,即使真正的福布斯范数可能远低于机器的溢出阈值。(请记住,计算结束时会取一个平方根) 编辑:还有下溢的问题。即使元素ai,j不是太小,其平方也可能下溢。在MATLAB中,一个 下溢的元素设置为0。现在只要其他一些元素是

我在MATLAB中实现了福布斯范数的以下定义

按照描述的方式(即,我对循环做了2次,并通过对每个元素进行平方运算来增加一个和,最后取和的平方根)

我的问题是,有没有一种方法可以实现这个标准,这样如果我在矩阵中输入一个相当大的数字,它的平方就不会溢出?函数在某些情况下返回“无穷大”,即使真正的福布斯范数可能远低于机器的溢出阈值。(请记住,计算结束时会取一个平方根)

编辑:还有下溢的问题。即使元素ai,j不是太小,其平方也可能下溢。在MATLAB中,一个 下溢的元素设置为0。现在只要其他一些元素是大的 够了,结果还是可以接受的。另一方面,如果所有元素都下溢,我的函数可能会错误地返回0

有什么帮助吗

在我的机器上产生无穷大矩阵的一个例子是

[1,99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999;1,1]


但是,当我使用内置的Frobenius norm函数时,它可以很好地处理该输入。为什么会这样?

下面的代码虽然是Java代码,但与Matlab在计算Frobenius范数时所做的非常接近。这里的技巧是
hypot
函数,它不只是执行
x^2+y^2
,而是计算斜边避免过流/过流海波图,因此,使用海波图代替计算sqrt(x^2+y^2),应该能够避免流量不足/过大

public static double normFrob(double[][] matrix) {
    double norm = 0.0;
    int rows = matrix.length;
    int cols = matrix[0].length;
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            norm = hypot(norm, matrix[i][j]);
        }
    }
    return norm;
}

public static double hypot(double a, double b) {
    double r;
    if (Math.abs(a) > Math.abs(b)) {
        r = b / a;
        r = Math.abs(a) * Math.sqrt(1 + r * r);
    } else if (b != 0) {
        r = a / b;
        r = Math.abs(b) * Math.sqrt(1 + r * r);
    } else {
        r = 0.0;
    }
    return r;
}
公共静态双normFrob(双[][]矩阵){
双范数=0.0;
int行=矩阵长度;
int cols=矩阵[0]。长度;
对于(int i=0;i数学abs(b)){
r=b/a;
r=Math.abs(a)*Math.sqrt(1+r*r);
}else如果(b!=0){
r=a/b;
r=数学绝对值(b)*数学平方比(1+r*r);
}否则{
r=0.0;
}
返回r;
}

这段代码片段是为了向Java引入矩阵库而编写的,其中一些开发人员是Matlab人员。

溢出保护可以通过多种方式完成。一种可能性是正常化。这是欧几里德标准,但想法是一样的

m_sum = 0;
y=max(abs(x));
for i=1:len(x)
  m_sum = m_sum + (x(i)/y)^2;
end
mynorm = y*sqrt(m_sum);

请发布一个重现问题的示例。如果可能的话,考虑矢量化这些循环,你可以得到一个大的速度改进。Matlab已经支持Frobenius范数。Matlab是如何实现Frobenius范数的?我查看了它们的定义,并尝试执行x=sqrt(trace(A*transpose(A)),但仍然存在溢出问题。当我使用内置的Frobenius函数(x=norm(A,'fro'))时,我没有发现溢出问题。Matlab还有一个内置的
hypot
函数。@horchler说得不错。实际上,我的目标是编写伪代码,但碰巧手头有那个java代码片段。由于OP没有发布任何代码,很难说,但我的最佳选择是
hypot
将解决他/她的问题。好建议。