Complex numbers (in ak.from_iter and elsewhere)
See original GitHub issueProbably low priority, as awkward1.from_numpy does.
>>> import awkward1 as ak
>>> import numpy as np
>>> ak.from_iter([0j])
~/venv/awkward/lib/python3.6/site-packages/awkward1/operations/convert.py in from_iter(iterable, highlevel, behavior, allow_record, initial, resize)
359 out = awkward1.layout.ArrayBuilder(initial=initial, resize=resize)
360 for x in iterable:
--> 361 out.fromiter(x)
362 layout = out.snapshot()
363 if highlevel:
ValueError: cannot convert 0j (type complex) to an array element
>>> ak.from_numpy(np.asarray([0j]))
<Array [0j] type='1 * complex128'>
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:10 (6 by maintainers)
Top Results From Across the Web
Intro to complex numbers (article) - Khan Academy
Learn what complex numbers are, and about their real and imaginary parts. In the real number system, there is no solution to the...
Read more >The Inside Story-Alaska: America's Strategic Frontier ...
“The military calls this strategic airspace. We've just arrived at the Arctic Circle. From here, fighter jets can reach anywhere in the Northern ......
Read more >1 Basics of Series and Complex Numbers
A complex number z = x+iy is composed of a real part (z) = x and an imaginary part (z) = y, both...
Read more >Complex numbers: reciprocals, conjugates, and division - Clark
Complex Numbers Reciprocals, conjugates, and division. We've studied addition, subtraction, and multiplication. Now it's time for division.
Read more >Dunleavy's budget proposal includes $3,900 dividend, no ...
15, 2022, in Juneau, Alaska, with members of his Cabinet also pictured. ... contributing to budget shortfalls in Anchorage and elsewhere.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

In that case, I can give you some pointers, so that you can evaluate how big of a project it will be.
For the complex types, there are fortunately stubs everywhere: they throw
std::runtime_errors, but that makes it convenient to find all the places where something needs to be inserted.I just looked at these search results in context and none of them need any work except the ones in NumpyArray.cpp. NumpyArray.cpp needs:
{"real": #, "imag": #}or maybe{"r": #, "i": #}? Do other libraries converge on some convention?NumpyArray::mergeandNumpyArray::numbers_to_typecallkernel::NumpyArray_fill<X, Y>(the latter does so indirectly), and this needs to be specialized to include complex cases in theXandY. That goes into kernel functions namedawkward_NumpyArray_fill_toY_fromX, which are described in more detail below.count,count_nonzero(implementations don’t depend on the type; it’s just a function signature),sum,prod(add the function signatures and the compiler does the work),any,all(have to determine whether a complex number is zero or not, but otherwise formulaic),min,max,argmin,argmax(can raisestd::invalid_argument("don't do that!")because complex numbers are unordered).std::invalid_argument("don't do that!")because complex numbers are unordered.Kernel functions separate code that actually touches the arrays from all the rest of the codebase. They’re a separate layer in the architecture:
and are, in fact, a separate shared library that can be dynamically loaded (
libawkward-cpu-kernels.soandlibawkward-cuda-kernels.so). The actual implementations of these functions (filling arrays and counting, summing, multiplying) are very simple and are templated by numerical type:https://github.com/scikit-hep/awkward-1.0/blob/029ae3991849d391733043db5e87389e333638fc/src/cpu-kernels/operations.cpp#L1136-L1146
However, that
extern "C"interface between the kernels layer and the C++ layer means that all of the kernel cases have to be given explicit names that dynamic library loaders can use to identify them. That means there’s a lot of boilerplate, linking named functions to template specializations:https://github.com/scikit-hep/awkward-1.0/blob/029ae3991849d391733043db5e87389e333638fc/src/cpu-kernels/operations.cpp#L1147-L1162
On the other side of the
extern "C"interface, we curb this insanity by gathering them back up again into template instantiations that are easier to use in the C++ codebase:https://github.com/scikit-hep/awkward-1.0/blob/029ae3991849d391733043db5e87389e333638fc/src/libawkward/kernel.cpp#L7073-L7095
(so the number of differently named functions explodes only at the interface). Why do we need an
extern "C"interface if it’s causing all this boilerplate? First of all, because of thatptr_lib == kernel::lib::cudacase in the above code; it lets us swap CPU-bound implementations for CUDA implementations at runtime, based on whether we get the array from NumPy or from CuPy. (The project we’re looking at here is just the CPU-bound implementation—we’re trying to auto-generate CUDA kernels from the CPU ones, and whatever you write would be part of that automatic translation.) Beyond swapping out implementations below theextern "C"interface, it also lets us swap out implementations above it, if someone’s interested in building a Julia/Rust/Swift/whatever implementation of Awkward Array.The only extra issue that complex numbers introduces is that
std::complexis notextern "C"compatible, so you’d have toreinterpret_castastd::complex<double>array of lengthnas adoublearray of lengthn * 2before passing it through the interface. C++ types likestd::complexcan be used on both sides of theextern "C"interface, just not through it. Thus, you don’t need to define type conversion or complex addition/multiplication inside the cpu-kernels, you canreinterpret_castthatdoublearray of lengthn * 2as astd::complex<double>array of lengthnand then the compiler takes over.But I apologize in advance about the boilerplate. I’ve been generating code with Emacs keyboard macros…
This should have been linked to #652: it’s done now!