mars-project / mars

Mars is a tensor-based unified framework for large-scale data computation which scales numpy, pandas, scikit-learn and Python functions.
https://mars-project.readthedocs.io
Apache License 2.0
2.71k stars 327 forks source link

Implements `mars.tensor.kron` #2157

Open wjsi opened 3 years ago

wjsi commented 3 years ago

Implements Kronecker product for tensors, just as numpy.kron does. This is required by module tensorly.

shantam-8 commented 2 years ago

Hello @wjsi, I would like to contribute to this issue but I am not sure how to do it. Could you please provide me some guidance regarding this function (similarities in the execution of other functions in linalg, etc) and also let me know how I can create the appropriate tests for the same?

wjsi commented 2 years ago

Hello @wjsi, I would like to contribute to this issue but I am not sure how to do it. Could you please provide me some guidance regarding this function (similarities in the execution of other functions in linalg, etc) and also let me know how I can create the appropriate tests for the same?

You may take a look at https://docs.pymars.org/en/latest/development/operand.html and how other operands are imlemented, for instance, mars.tensor.linalg.tensordot.

qinxuye commented 2 years ago

Better to understand the function itself. If we know how to parallelize it, it's actually workable, we need to implement an Operand with tile and execute method. We can help you if you find it's workable.

shantam-8 commented 2 years ago

Hello @wjsi @qinxuye. Firstly, I am very sorry for the late message. I was busy due to other commitments and could not give time to this. I was trying to implement the code and I have reached here-

import numpy as np

def kron(*args):
    """Replica of numpy Kronecker product of two arrays. Code has been adapted from other sources."""

    if len(args) != 2:
        raise TypeError (f"_kron_dispatcher() takes 2 positional arguments but {len(args)} were given")
    else:
        x = args[0]
        y = args[1] 

        if len(x.shape) != 1:
                return np.block([
            [x[i, j] * y for j in range(x.shape[1])]
            for i in range(x.shape[0])
        ])

        else:
                return np.block([
            x[i] * y for i in range(x.shape[0])
        ])

# Test
a = np.random.rand(3)
b = np.random.rand(4, 5)
assert np.array_equal(kron(a, b), np.kron(a,b)) == True

However, I am not sure if I am going in the right direction. Could you please provide me with some guidance as to how I can go about implementing the function?