예제 #1
0
def test_ccode_loops_multiple_contractions():
    from diofant.tensor import IndexedBase, Idx
    from diofant import symbols
    n, m, o, p = symbols('n m o p', integer=True)
    a = IndexedBase('a')
    b = IndexedBase('b')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)
    k = Idx('k', o)
    l = Idx('l', p)

    s = ('for (int i=0; i<m; i++){\n'
         '   y[i] = 0;\n'
         '}\n'
         'for (int i=0; i<m; i++){\n'
         '   for (int j=0; j<n; j++){\n'
         '      for (int k=0; k<o; k++){\n'
         '         for (int l=0; l<p; l++){\n'
         '            y[i] = y[i] + b[%s]*a[%s];\n' %
         (j * o * p + k * p + l, i * n * o * p + j * o * p + k * p + l) +
         '         }\n'
         '      }\n'
         '   }\n'
         '}')
    c = ccode(b[j, k, l] * a[i, j, k, l], assign_to=y[i])
    assert c == s
예제 #2
0
def test_m_tensor_loops_multiple_contractions():
    # see comments in previous test about vectorizing
    from diofant.tensor import IndexedBase, Idx
    from diofant import symbols
    n, m, o, p = symbols('n m o p', integer=True)
    A = IndexedBase('A')
    B = IndexedBase('B')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)
    k = Idx('k', o)
    l = Idx('l', p)
    result, = codegen(('tensorthing', Eq(y[i], B[j, k, l] * A[i, j, k, l])),
                      "Octave",
                      header=False,
                      empty=False)
    source = result[1]
    expected = ('function y = tensorthing(A, B, m, n, o, p)\n'
                '  for i = 1:m\n'
                '    y(i) = 0;\n'
                '  end\n'
                '  for i = 1:m\n'
                '    for j = 1:n\n'
                '      for k = 1:o\n'
                '        for l = 1:p\n'
                '          y(i) = y(i) + B(j, k, l).*A(i, j, k, l);\n'
                '        end\n'
                '      end\n'
                '    end\n'
                '  end\n'
                'end\n')
    assert source == expected
예제 #3
0
def test_ccode_loops_matrix_vector():
    n, m = symbols('n m', integer=True)
    A = IndexedBase('A')
    x = IndexedBase('x')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)

    s = ('for (int i=0; i<m; i++){\n'
         '   y[i] = 0;\n'
         '}\n'
         'for (int i=0; i<m; i++){\n'
         '   for (int j=0; j<n; j++){\n'
         '      y[i] = x[j]*A[%s] + y[i];\n' % (i * n + j) + '   }\n'
         '}')
    c = ccode(A[i, j] * x[j], assign_to=y[i])
    assert c == s

    pytest.raises(ValueError, lambda: ccode(A[i, j] * x[j], assign_to=x[j]))

    s2 = ('for (int i=0; i<m; i++){\n'
          '   y[i] = 0;\n'
          '}\n'
          'for (int i=0; i<m; i++){\n'
          '   for (int i=0; i<m; i++){\n'
          '      y[i] = y[i] + A[m*i + i];\n'
          '   }\n}')
    c = ccode(A[i, i], assign_to=y[i])
    assert c == s2
예제 #4
0
def test_jscode_loops_addfactor():
    from diofant.tensor import IndexedBase, Idx
    from diofant import symbols
    n, m, o, p = symbols('n m o p', integer=True)
    a = IndexedBase('a')
    b = IndexedBase('b')
    c = IndexedBase('c')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)
    k = Idx('k', o)
    l = Idx('l', p)

    s = (
        'for (var i=0; i<m; i++){\n'
        '   y[i] = 0;\n'
        '}\n'
        'for (var i=0; i<m; i++){\n'
        '   for (var j=0; j<n; j++){\n'
        '      for (var k=0; k<o; k++){\n'
        '         for (var l=0; l<p; l++){\n'
        '            y[i] = (a[%s] + b[%s])*c[%s] + y[i];\n' % (i*n*o*p + j*o*p + k*p + l, i*n*o*p + j*o*p + k*p + l, j*o*p + k*p + l) +
        '         }\n'
        '      }\n'
        '   }\n'
        '}'
    )
    c = jscode((a[i, j, k, l] + b[i, j, k, l])*c[j, k, l], assign_to=y[i])
    assert c == s
예제 #5
0
def test_m_loops():
    # Note: an Octave programmer would probably vectorize this across one or
    # more dimensions.  Also, size(A) would be used rather than passing in m
    # and n.  Perhaps users would expect us to vectorize automatically here?
    # Or is it possible to represent such things using IndexedBase?
    from diofant.tensor import IndexedBase, Idx
    from diofant import symbols
    n, m = symbols('n m', integer=True)
    A = IndexedBase('A')
    x = IndexedBase('x')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)
    result, = codegen(('mat_vec_mult', Eq(y[i], A[i, j] * x[j])),
                      "Octave",
                      header=False,
                      empty=False)
    source = result[1]
    expected = ('function y = mat_vec_mult(A, m, n, x)\n'
                '  for i = 1:m\n'
                '    y(i) = 0;\n'
                '  end\n'
                '  for i = 1:m\n'
                '    for j = 1:n\n'
                '      y(i) = %(rhs)s + y(i);\n'
                '    end\n'
                '  end\n'
                'end\n')
    assert (source == expected % {
        'rhs': 'A(%s, %s).*x(j)' % (i, j)
    } or source == expected % {
        'rhs': 'x(j).*A(%s, %s)' % (i, j)
    })
예제 #6
0
def test_loops():
    n, m = symbols('n,m', integer=True)
    A = IndexedBase('A')
    x = IndexedBase('x')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)

    expected = ('do i = 1, m\n'
                '   y(i) = 0\n'
                'end do\n'
                'do i = 1, m\n'
                '   do j = 1, n\n'
                '      y(i) = %(rhs)s\n'
                '   end do\n'
                'end do')

    code = fcode(A[i, j] * x[j], assign_to=y[i], source_format='free')
    assert (code == expected % {
        'rhs': 'y(i) + A(i, j)*x(j)'
    } or code == expected % {
        'rhs': 'y(i) + x(j)*A(i, j)'
    } or code == expected % {
        'rhs': 'x(j)*A(i, j) + y(i)'
    } or code == expected % {
        'rhs': 'A(i, j)*x(j) + y(i)'
    })
예제 #7
0
def test_ccode_loops_multiple_terms():
    from diofant.tensor import IndexedBase, Idx
    from diofant import symbols
    n, m, o, p = symbols('n m o p', integer=True)
    a = IndexedBase('a')
    b = IndexedBase('b')
    c = IndexedBase('c')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)
    k = Idx('k', o)

    s0 = ('for (int i=0; i<m; i++){\n' '   y[i] = 0;\n' '}\n')
    s1 = ('for (int i=0; i<m; i++){\n'
          '   for (int j=0; j<n; j++){\n'
          '      for (int k=0; k<o; k++){\n'
          '         y[i] = b[j]*b[k]*c[%s] + y[i];\n' %
          (i * n * o + j * o + k) + '      }\n'
          '   }\n'
          '}\n')
    s2 = ('for (int i=0; i<m; i++){\n'
          '   for (int k=0; k<o; k++){\n'
          '      y[i] = b[k]*a[%s] + y[i];\n' % (i * o + k) + '   }\n'
          '}\n')
    s3 = ('for (int i=0; i<m; i++){\n'
          '   for (int j=0; j<n; j++){\n'
          '      y[i] = b[j]*a[%s] + y[i];\n' % (i * n + j) + '   }\n'
          '}\n')
    c = ccode(b[j] * a[i, j] + b[k] * a[i, k] + b[j] * b[k] * c[i, j, k],
              assign_to=y[i])
    assert (c == s0 + s1 + s2 + s3[:-1] or c == s0 + s1 + s3 + s2[:-1]
            or c == s0 + s2 + s1 + s3[:-1] or c == s0 + s2 + s3 + s1[:-1]
            or c == s0 + s3 + s1 + s2[:-1] or c == s0 + s3 + s2 + s1[:-1])
예제 #8
0
def test_ccode_Indexed_without_looking_for_contraction():
    len_y = 5
    y = IndexedBase('y', shape=(len_y, ))
    x = IndexedBase('x', shape=(len_y, ))
    Dy = IndexedBase('Dy', shape=(len_y - 1, ))
    i = Idx('i', len_y - 1)
    e = Eq(Dy[i], (y[i + 1] - y[i]) / (x[i + 1] - x[i]))
    code0 = ccode(e.rhs, assign_to=e.lhs, contract=False)
    assert code0 == 'Dy[i] = (y[%s] - y[i])/(x[%s] - x[i]);' % (i + 1, i + 1)
예제 #9
0
def test_fcode_Indexed_without_looking_for_contraction():
    len_y = 5
    y = IndexedBase('y', shape=(len_y,))
    x = IndexedBase('x', shape=(len_y,))
    Dy = IndexedBase('Dy', shape=(len_y - 1,))
    i = Idx('i', len_y - 1)
    e = Eq(Dy[i], (y[i + 1] - y[i])/(x[i + 1] - x[i]))
    code0 = fcode(e.rhs, assign_to=e.lhs, contract=False)
    assert code0.endswith('Dy(i) = (y(i + 1) - y(i))/(x(i + 1) - x(i))')
예제 #10
0
def test_dummy_loops():
    i, m = symbols('i m', integer=True, cls=Dummy)
    x = IndexedBase('x')
    y = IndexedBase('y')
    i = Idx(i, m)

    expected = (
        'do i_%(icount)i = 1, m_%(mcount)i\n'
        '   y(i_%(icount)i) = x(i_%(icount)i)\n'
        'end do'
    ) % {'icount': i.label.dummy_index, 'mcount': m.dummy_index}
    code = fcode(x[i], assign_to=y[i], source_format='free')
    assert code == expected
예제 #11
0
def test_dummy_loops():
    i, m = symbols('i m', integer=True, cls=Dummy)
    x = IndexedBase('x')
    y = IndexedBase('y')
    i = Idx(i, m)

    expected = (
        'for (var i_%(icount)i=0; i_%(icount)i<m_%(mcount)i; i_%(icount)i++){\n'
        '   y[i_%(icount)i] = x[i_%(icount)i];\n'
        '}'
    ) % {'icount': i.label.dummy_index, 'mcount': m.dummy_index}
    code = jscode(x[i], assign_to=y[i])
    assert code == expected
예제 #12
0
def test_ccode_Indexed():
    n, m, o = symbols('n m o', integer=True)
    i, j, k = Idx('i', n), Idx('j', m), Idx('k', o)
    p = CCodePrinter()
    p._not_c = set()

    x = IndexedBase('x')[j]
    assert p._print_Indexed(x) == 'x[j]'
    A = IndexedBase('A')[i, j]
    assert p._print_Indexed(A) == 'A[%s]' % (m * i + j)
    B = IndexedBase('B')[i, j, k]
    assert p._print_Indexed(B) == 'B[%s]' % (i * o * m + j * o + k)

    assert p._not_c == set()
예제 #13
0
def test_Assignment():
    x, y = symbols("x, y")
    A = MatrixSymbol('A', 3, 1)
    mat = Matrix([1, 2, 3])
    B = IndexedBase('B')
    n = symbols("n", integer=True)
    i = Idx("i", n)
    # Here we just do things to show they don't error
    Assignment(x, y)
    Assignment(x, 0)
    Assignment(A, mat)
    Assignment(A[1, 0], 0)
    Assignment(A[1, 0], x)
    Assignment(B[i], x)
    Assignment(B[i], 0)
    # Here we test things to show that they error
    # Matrix to scalar
    pytest.raises(ValueError, lambda: Assignment(B[i], A))
    pytest.raises(ValueError, lambda: Assignment(B[i], mat))
    pytest.raises(ValueError, lambda: Assignment(x, mat))
    pytest.raises(ValueError, lambda: Assignment(x, A))
    pytest.raises(ValueError, lambda: Assignment(A[1, 0], mat))
    # Scalar to matrix
    pytest.raises(ValueError, lambda: Assignment(A, x))
    pytest.raises(ValueError, lambda: Assignment(A, 0))
    # Non-atomic lhs
    pytest.raises(TypeError, lambda: Assignment(mat, A))
    pytest.raises(TypeError, lambda: Assignment(0, x))
    pytest.raises(TypeError, lambda: Assignment(x * x, 1))
    pytest.raises(TypeError, lambda: Assignment(A + A, mat))
    pytest.raises(TypeError, lambda: Assignment(B, 0))
예제 #14
0
def test_jscode_Indexed():
    from diofant.tensor import IndexedBase, Idx
    from diofant import symbols
    n, m, o = symbols('n m o', integer=True)
    i, j, k = Idx('i', n), Idx('j', m), Idx('k', o)
    p = JavascriptCodePrinter()
    p._not_c = set()

    x = IndexedBase('x')[j]
    assert p._print_Indexed(x) == 'x[j]'
    A = IndexedBase('A')[i, j]
    assert p._print_Indexed(A) == 'A[%s]' % (m*i+j)
    B = IndexedBase('B')[i, j, k]
    assert p._print_Indexed(B) == 'B[%s]' % (i*o*m+j*o+k)

    assert p._not_c == set()
예제 #15
0
def test_ccode_loops_add():
    n, m = symbols('n m', integer=True)
    A = IndexedBase('A')
    x = IndexedBase('x')
    y = IndexedBase('y')
    z = IndexedBase('z')
    i = Idx('i', m)
    j = Idx('j', n)

    s = ('for (int i=0; i<m; i++){\n'
         '   y[i] = x[i] + z[i];\n'
         '}\n'
         'for (int i=0; i<m; i++){\n'
         '   for (int j=0; j<n; j++){\n'
         '      y[i] = x[j]*A[%s] + y[i];\n' % (i * n + j) + '   }\n'
         '}')
    c = ccode(A[i, j] * x[j] + x[i] + z[i], assign_to=y[i])
    assert c == s
예제 #16
0
def test_jscode_loops_matrix_vector():
    n, m = symbols('n m', integer=True)
    A = IndexedBase('A')
    x = IndexedBase('x')
    y = IndexedBase('y')
    i = Idx('i', m)
    j = Idx('j', n)

    s = (
        'for (var i=0; i<m; i++){\n'
        '   y[i] = 0;\n'
        '}\n'
        'for (var i=0; i<m; i++){\n'
        '   for (var j=0; j<n; j++){\n'
        '      y[i] = x[j]*A[n*i + j] + y[i];\n'
        '   }\n'
        '}'
    )
    c = jscode(A[i, j]*x[j], assign_to=y[i])
    assert c == s
예제 #17
0
def test_jscode_inline_function():
    x = symbols('x')
    g = implemented_function('g', Lambda(x, 2*x))
    assert jscode(g(x)) == "2*x"
    g = implemented_function('g', Lambda(x, 2*x/Catalan))
    assert jscode(g(x)) == "var Catalan = %s;\n2*x/Catalan" % Catalan.n()
    A = IndexedBase('A')
    i = Idx('i', symbols('n', integer=True))
    g = implemented_function('g', Lambda(x, x*(1 + x)*(2 + x)))
    assert jscode(g(A[i]), assign_to=A[i]) == (
        "for (var i=0; i<n; i++){\n"
        "   A[i] = (A[i] + 1)*(A[i] + 2)*A[i];\n"
        "}"
    )
예제 #18
0
def test_inline_function():
    g = implemented_function('g', Lambda(x, 2 * x))
    assert fcode(g(x)) == "      2*x"
    g = implemented_function('g', Lambda(x, 2 * pi / x))
    assert fcode(g(x)) == ("      parameter (pi = 3.14159265358979d0)\n"
                           "      2*pi/x")
    A = IndexedBase('A')
    i = Idx('i', symbols('n', integer=True))
    g = implemented_function('g', Lambda(x, x * (1 + x) * (2 + x)))
    assert fcode(
        g(A[i]),
        assign_to=A[i]) == ("      do i = 1, n\n"
                            "         A(i) = (A(i) + 1)*(A(i) + 2)*A(i)\n"
                            "      end do")
예제 #19
0
def test_jscode_loops_add():
    from diofant.tensor import IndexedBase, Idx
    from diofant import symbols
    n, m = symbols('n m', integer=True)
    A = IndexedBase('A')
    x = IndexedBase('x')
    y = IndexedBase('y')
    z = IndexedBase('z')
    i = Idx('i', m)
    j = Idx('j', n)

    s = (
        'for (var i=0; i<m; i++){\n'
        '   y[i] = x[i] + z[i];\n'
        '}\n'
        'for (var i=0; i<m; i++){\n'
        '   for (var j=0; j<n; j++){\n'
        '      y[i] = x[j]*A[n*i + j] + y[i];\n'
        '   }\n'
        '}'
    )
    c = jscode(A[i, j]*x[j] + x[i] + z[i], assign_to=y[i])
    assert c == s