Skip to content

Commit 3e85e06

Browse files
authored
Update README.md
1 parent 6e20218 commit 3e85e06

1 file changed

Lines changed: 42 additions & 7 deletions

File tree

README.md

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,16 @@ In my experience, calling `numpy` from C# is about 4 times slower than calling i
3838

3939
All of `numpy` is centered around the `ndarray` class which allows you to pass a huge chunk of data into the `C` routines and let them execute all kinds of operations on the elements efficiently without the need for looping over the data. So if you are manipulating arrays or matrices with thousands or hundreds of thousands of elements, the call overhead will be neglegible.
4040

41-
The most performance sensitive aspect is creating an `NDarray` from a `C#` array, since the data has to be moved from the `CLR` into the `Python` interpreter. `pythonnet` does not optimize for passing large arrays from `C#` to `Python` but we still found a way to do that very efficiently. When creating an array with `np.array( ... )` we internally use `Marshal.Copy` to copy the entiry `C#`-array's memory into the `numpy`-array's storage. And to efficiently retrieve computation results from `numpy` there is a method called `GetData<T>` which will copy the data back to `C#` in the same way.
41+
The most performance sensitive aspect is creating an `NDarray` from a `C#` array, since the data has to be moved from the `CLR` into the `Python` interpreter. `pythonnet` does not optimize for passing large arrays from `C#` to `Python` but we still found a way to do that very efficiently. When creating an array with `np.array( ... )` we internally use `Marshal.Copy` to copy the entiry `C#`-array's memory into the `numpy`-array's storage. And to efficiently retrieve computation results from `numpy` there is a method called `GetData<T>` which will copy the data back to `C#` in the same way:
42+
43+
```csharp
44+
// create a 2D-shaped NDarray<int> from an int[]
45+
var m = np.array(new int[] {1, 2, 3, 4});
46+
// calculate the cosine of each element
47+
var result = np.cos(m);
48+
// get the floating point data of the result NDarray back to C#
49+
var data = result.GetData<double>(); // double[] { 0.54030231, -0.41614684, -0.9899925 , -0.65364362 }
50+
```
4251

4352
## Numpy.NET vs NumSharp
4453

@@ -59,18 +68,44 @@ The SciSharp team is also developing a pure C# port of NumPy called [NumSharp](h
5968

6069
The vast majority of Numpy.NET's code is generated using [CodeMinion](https://github.com/SciSharp/CodeMinion) by parsing the documentation at [docs.scipy.org/doc/numpy/](docs.scipy.org/doc/numpy/). This allowed us to wrap most of the `numpy`-API in just two weeks. The rest of the API can be completed in a few more weeks, especially if there is popular demand.
6170

62-
TODO: information about completed API categories
71+
### Competion status
72+
73+
TODO: information about completion status API categories
74+
75+
### Auto-generated Unit-Tests
76+
77+
We even generated hundreds of unit tests from all the examples found on the NumPy documentation. Most of them don't compile without fixing them because we did not go so far as to employ a Python-To-C# converter. Instead, the tests are set up with a commented out Python-console log that shows what the expected results are and a commented out block of somewhat C#-ified Python code that doesn't compile without manual editing.
78+
79+
Another reason why this process can not be totally automated is the fact that NumPy obviously changed the way how arrays are printed out on the console after most of the examples where written (they removed extra spaces between the elements). This means that oftentimes the results needs to be reformatted manually for the test to pass.
80+
81+
Getting more unit tests to run is very easy though, and a good portion have already been processed to show that Numpy.NET really works. If you are interested in working on the test suite, please join in and help. You'll learn a lot about NumPy on the way.
6382

6483
## Documentation
6584

6685
Since we have taken great care to make Numpy.NET as similar to NumPy itself, you can, for the most part, rely on the official [NumPy manual](https://docs.scipy.org/doc/numpy/).
6786

87+
### Creating multi-dimensional NDarrays from C# arrays
88+
89+
Creating an `NDarray` from data is easy. Just pass the C# array into `np.array(...)`. You can pass 1D, 2D and 3D C# arrays into it.
90+
91+
```csharp
92+
// create a 2D NDarray
93+
var m = np.array(new int[,] {{1, 2}, {3, 4}}); // the NDarray represents a 2 by 2 matrix
94+
```
95+
96+
Another even more efficient way (saves one array copy operation) is to pass the data as a one-dimensional array and just reshape the NDarray.
97+
98+
```csharp
99+
// create a 2D NDarray
100+
var m = np.array(new int[] {1, 2, 3, 4}).reshape(2,2); // the reshaped NDarray represents a 2 by 2 matrix
101+
```
102+
68103
### Differences between Numpy.NET and NumPy
69104

70-
As you have seen in the example above, apart from language syntax and idioms, usage of Numpy.NET is almost identical to Python. However, there are some differences which can not be resolved due to lack of language support in C#.
105+
As you have seen, apart from language syntax and idioms, usage of Numpy.NET is almost identical to Python. However, due to lack of language support in C#, there are some differences which you should be aware of.
71106

72-
#### Slice syntax
73-
C# doesn't support the colon syntax in indexers i.e. `[:, 1]`. However, by allowing to pass a string with *Python slicing syntax* we circumvented it, i.e. `[":, 1"]`. Only the `...` operator is not yet implemented, as it is not very important.
107+
#### Array slicing syntax
108+
You can access parts of an NDarray using [array slicing](https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#arrays-indexing). C# doesn't support the colon syntax in indexers i.e. `a[:, 1]`. However, by allowing to pass a string we circumvented this limitation, i.e. `a[":, 1"]`. Only the `...` operator is not yet implemented, as it is not very important.
74109

75110
#### Variable argument lists
76111
Some NumPy functions like `reshape` allow variable argument lists at the beginning of the parameter list. This of course is not allowed in C#, which supports a variable argument list only as the last parameter. In case of `reshape` the solution was to replace the variable argument list that specifies the dimensions of the reshaped array by a `Shape` object which takes a variable list of dimensions in its constructor:
@@ -124,15 +159,15 @@ var roots = np.sqrt(a); // => { 0.0, 1.0, 1.414, ..., 9.899, 9.950 }
124159
```
125160

126161
#### Complex numbers
127-
Python has native support of complex numbers, something the C# language is lacking as well. Converting complex results to and from NumPy is not implemented at all.
162+
Python has native support of complex numbers, something the C# language is lacking as well. Converting complex results to and from NumPy is not implemented at all (yet). Please step forward if you want to work on this.
128163

129164
## Versions and Compatibility
130165

131166
Currently, Numpy.NET is targeting .NET Standard (on Windows) and packages the following binaries:
132167
* Python 3.7: (python-3.7.3-embed-amd64.zip)
133168
* NumPy 1.16 (numpy-1.16.3-cp37-cp37m-win_amd64.whl)
134169

135-
To make Numpy.NET support Linux a separate version of [Python.Included](https://github.com/henon/Python.Included) packaging linux binaries of Python needs to be made and a version of Numpy.NET that packages a linux-compatible NumPy wheel.
170+
To make Numpy.NET support Linux a separate version of [Python.Included](https://github.com/henon/Python.Included) packaging linux binaries of Python needs to be made and a version of Numpy.NET that packages a linux-compatible NumPy wheel. If you are interested, you may work on this issue.
136171

137172
## License
138173

0 commit comments

Comments
 (0)