Quansight-Labs / numpy.net

A port of NumPy to .Net
BSD 3-Clause "New" or "Revised" License
128 stars 14 forks source link

Consider replacing object return types with nparray #22

Closed Happypig375 closed 2 years ago

Happypig375 commented 2 years ago

This way, we can chain numpy operations better. To extract values we can still cast.

KevinBaselinesw commented 2 years ago

I don't understand this comment. Can you provide an example of when I am returning an object?

I think most of the functions return ndarray objects. In a scenario where python is returning a scalar value instead of an array, I provide ability to cast the array to the specified type to get make it equivalent with python.

C# requires strict definitions for return values. In other words, the same function can't return an ndarray sometimes and a scalar value a different time like python can. So, I always return an ndarray even if there is just one element. There is an easy cast to get that first element.

Happypig375 commented 2 years ago

object np.min(object) object np.max(object) object ndarray.this[object]

For example. These should return ndarray.

KevinBaselinesw commented 2 years ago

I don't understand your example. In the unit tests below, I tried to create some examples in both languages. The 'c' line does not compile in either language but 'a' and 'b' are the same result. Can you provide a more complete example?

Python unit test

 def test_HadrianTang_13(self):

       objecta = 9.234
       objectb = 33

       a = np.min(objecta)
       b = np.max(objectb)
       #c =  ndarray.this[objectb]

       print(a)
       print(b)
       #print(c)

C# unit test

      [TestMethod]
        public void test_HadrianTang_13()
        {
            var objecta = 9.234;
            var objectb = 33;

            var a = np.min(objecta);
            var b = np.max(objectb);
           // var c = ndarray.this[object];

            return;
        }
Happypig375 commented 2 years ago

Oh they are method signatures.

Happypig375 commented 2 years ago

The signature should have a return type of ndarray instead of object.

KevinBaselinesw commented 2 years ago

Please use amax and amin to get the return values as ndarray objects.

This is one of those weird cases where python can return either an ndarray or scalar value. Since I can't do that, I made np.max and np.min return the scalar and np.amax and np.amin return the array.

Happypig375 commented 2 years ago

But scalars can be represented using 0D arrays right?

KevinBaselinesw commented 2 years ago

I experimented with changing it and it breaks too many things. I can fix all of that up but then I risk breaking other customers who are depending on the current behavior.

The easiest thing is for you to use np.amin and np.amax.

Happypig375 commented 2 years ago

What about indexing?

KevinBaselinesw commented 2 years ago

Here is a simple example of indexing that returns an ndarray class. This will not compile because the 'set' operations must also be ndarray. It is not a problem returning an ndarray. It is a huge problem trying to set values to the index. I don't think we want to force everyone to convert every set operation to an ndarray.

   public partial class ndarrayXX
        {
            public ndarrayXX this[int index]
            {
                get
                {
                    return null;
                }
                set
                {

                }
            }
        }

        [TestMethod]
        public void test_HadrianTang_14()
        {
            ndarrayXX HadrianTang = new ndarrayXX();

            ndarrayXX a = HadrianTang[3];

            HadrianTang[3] = 2;

            return;
        }
KevinBaselinesw commented 2 years ago

FYI, there is a helper function I called ndarray.A. It really just calls the indexer and then casts to an ndarray if it is an ndarray. It is useful to avoid having to cast return values to ndarray if I know an array is coming back.

      [TestMethod]
        public void test_HadrianTang_14()
        {
            ndarray HadrianTang = np.array(new Int32[] { 1, 2, 3, 4, 5 });

            var a = HadrianTang[3];
            var arr = HadrianTang.A(3);

            HadrianTang[3] = 2;

            return;
        }
Happypig375 commented 2 years ago

thanks for explaining!