C ++ std :: vector multiplication中是否存在已知的不一致行为?

时间:2017-04-11 17:00:02

标签: python c++ python-3.x c++11 debugging

我正在将Python代码翻译成C ++。

我在下面的代码段中遇到问题。这两个代码应该是相同的,但是tehy给了我不同的输出。

我迷路了。错误从k=1开始。发生了什么,错误在哪里?

如果重要:我正在使用IDE Eclipse Parallel Mars,Windows 10,MinGW编译C ++代码。

Python 3.5:

import numpy as np
a = np.array(([2,-1,0,0],[-1,1.5,-0.5,0],[0,-0.5,0.75,-0.25],[0,0,-0.25,0.25]))
b = np.array(([0,0,0,1]))
for k in range(len(b)-1,-1,-1):
    p = 0
    print("")
    print("k = ", k)
    print("b[k] = ", b[k])
    for m in range(k+1, len(b)):
        print("m = ", m)
        print("b[m] = ", b[m])
        print("a[k,m] = ",a[k,m])
        p += a[k,m] * b[m];
        print("p = ", p)

    b[k] = (b[k] - p)/a[k,k];

C ++ 11:

#include <iostream>
#include <vector>

int main(){
    std::vector< std::vector<double> > a = { {2,-1,0,0}, {-1,1.5,-0.5,0},
                {0,-0.5,0.75,-0.25}, {0,0,-0.25,0.25} };
    std::vector<double> b = {0,0,0,1};
    double p;
    for (int k = b.size()-1; k >= 0; --k) {
        p = 0;
        std::cout << std::endl << "k = " << k << std::endl;
        std::cout << "b[k] = " << b[k] << std::endl;
        for (size_t m = k+1; m < b.size(); ++m) {
            std::cout << "m = " << m << std::endl;
            std::cout << "b[m] = " << b[m] << std::endl;
            std::cout << "a[k][m] = " << a[k][m] << std::endl;
            p += a[k][m] * b[m];
            std::cout << "p = " << p << std::endl;
        }
        b[k] = (b[k] - p)/a[k][k];
    }
    return 0;
}

输出

Python 3.5:

k =  3
b[k] =  1

k =  2
b[k] =  0
m =  3
b[m] =  4
a[k,m] =  -0.25
p =  -1.0

k =  1
b[k] =  0
m =  2
b[m] =  1
a[k,m] =  -0.5
p =  -0.5
m =  3
b[m] =  4
a[k,m] =  0.0
p =  -0.5

k =  0
b[k] =  0
m =  1
b[m] =  0
a[k,m] =  -1.0
p =  0.0
m =  2
b[m] =  1
a[k,m] =  0.0
p =  0.0
m =  3
b[m] =  4
a[k,m] =  0.0
p =  0.0

C ++ 11:

k = 3
b[k] = 1

k = 2
b[k] = 0
m = 3
b[m] = 4
a[k][m] = -0.25
p = -1

k = 1
b[k] = 0
m = 2
b[m] = 1.33333
a[k][m] = -0.5
p = -0.666667
m = 3
b[m] = 4
a[k][m] = 0
p = -0.666667

k = 0
b[k] = 0
m = 1
b[m] = 0.444444
a[k][m] = -1
p = -0.444444
m = 2
b[m] = 1.33333
a[k][m] = 0
p = -0.444444
m = 3
b[m] = 4
a[k][m] = 0
p = -0.444444

2 个答案:

答案 0 :(得分:3)

您的Python代码有缺陷。它正在截断数字,导致整数值,您期望浮点数具有小数分量。

特别是,np.array(([0,0,0,1]))正在创建一个具有整数数据类型的numpy数组,这意味着当您分配给b[k]时,浮点值将被截断为整数。关于可选的numpy.array()参数(强调我的),the docs代表dtype

  

阵列所需的数据类型。如果没有给出,那么类型将被确定为保持序列中对象所需的最小类型。

由于你只在输入数组中提供了整数值,numpy推断你想要创建一个整数数组。

C ++代码是正确的。

当我修改你的Python代码到处使用浮点值时,输出与C ++版本匹配:

import numpy as np
a = np.array(([2.0,-1.0,0.0,0.0],[-1.0,1.5,-0.5,0.0],[0.0,-0.5,0.75,-0.25],[0.0,0.0,-0.25,0.25]))
b = np.array(([0.0,0.0,0.0,1.0]))
for k in range(len(b)-1,-1,-1):
    p = 0
    print("")
    print("k = ", k)
    print("b[k] = ", b[k])
    for m in range(k+1, len(b)):
        print("m = ", m)
        print("b[m] = ", b[m])
        print("a[k,m] = ",a[k,m])
        p += a[k,m] * b[m];
        print("p = ", p)

    b[k] = (b[k] - p)/a[k,k];

答案 1 :(得分:0)

如果您在创建数组dtype时将'float64'指定为b

b = np.array(([0,0,0,1]), dtype='float64')

输出如下,与您的C ++程序匹配:

k = 3
b[k] = 1.0

k = 2
b[k] = 0.0
m = 3
b[m] = 4.0
a[k,m] = -0.25
p = -1.0

k = 1
b[k] = 0.0
m = 2
b[m] = 1.3333333333333333
a[k,m] = -0.5
p = -0.66666666666666663
m = 3
b[m] = 4.0
a[k,m] = 0.0
p = -0.66666666666666663

k = 0
b[k] = 0.0
m = 1
b[m] = 0.44444444444444442
a[k,m] = -1.0
p = -0.44444444444444442
m = 2
b[m] = 1.3333333333333333
a[k,m] = 0.0
p = -0.44444444444444442
m = 3
b[m] = 4.0
a[k,m] = 0.0
p = -0.44444444444444442