> EjML functional interface looks like this > > void apply(ComplexDouble in, MutableComplexDouble out) > Similar to the mutable cursor idea we have been discussing. The Mutable object could be an interface?
Ok We may need to have more than one implementation of the underlying storage. Using interleaved real and imaginary will be more efficient for computation on a single number due to cache reads from memory. But the separate arrays are going to be useful when writing code with the vector API that requires extracting blocks of real or imaginary components. Ok > > > I am still wondering how these functions can be composed. Here are a few > ideas.... > > This may need more work.. > ComplexResultInterceptor class It does require a lot of code that may have a far bigger overhead impact than just creating a complex result. I think the overhead of creating the Complex objects for the intermediates may be lower than a solution that tries to avoid allocation overhead with complexity of ThreadLocal. A performance benchmark would be able to determine this so we can look at that in the future. Ok. Will extend java functions and create complex objects for intermediate results It may be useful here to create a branch in the numbers repository for all the changes. To keep it simple perhaps a 'develop' branch can be used that you can make your changes against. Ok. I can raise a PR to develop with the above changes. I will follow Alex's latest update to the Developer Guide for pull requests. Thanks, Sumanth On Wed, 15 Jun 2022 at 13:58, Alex Herbert <alex.d.herb...@gmail.com> wrote: > On Wed, 15 Jun 2022 at 17:38, Sumanth Rajkumar <rajkumar.suma...@gmail.com > > > wrote: > > > Hi Alex, > > > > What do you intend to support as a "Matrix"? Is it for 2D or ND? What > > functionality already exists for complex matrix operations such as add > and > > multiply in for example EJML? > > > > This may require some expansion. > > > > a) I reviewed EJML data naming conventions, this is what they follow: > > > > > > > https://github.com/lessthanoptimal/ejml#procedural-api-matrix-and-class-names > > Should we follow this approach as well? > > I wasn't thinking about implementing ND right now, maybe I can during > > Phase 2? > > > > OK. > > > > > > b) EJML only supports 2D matrices with vector (1XN) being a special case, > > should I do that too? > > > > OK. > > > > > > c) EJML uses a mutable ComplexResult, they use a single mutable class for > > both input and output and return void > > > > Here is the link to their implementation: > > > > > > > https://github.com/lessthanoptimal/ejml/blob/SNAPSHOT/main/ejml-core/src/org/ejml/ops/ComplexMath_F64.java > > > > Their functional interface looks like this > > > > void apply(ComplexDouble in, MutableComplexDouble out) > > > > Similar to the mutable cursor idea we have been discussing. The Mutable > object could be an interface? > > > > > > d) For dense Matrix internal storage, I'm planning on using separate > arrays > > (or a single array where the first half of the array will be real and the > > second half will be imaginary) instead of alternating real and imaginary > > because it allows us to optimize space for pure imaginary or real > matrices. > > > > Is that ok? > > > > We may need to have more than one implementation of the underlying storage. > Using interleaved real and imaginary will be more efficient for computation > on a single number due to cache reads from memory. But the separate arrays > are going to be useful when writing code with the vector API that requires > extracting blocks of real or imaginary components. > > > > > > > > I am still wondering how these functions can be composed. Here are a few > > ideas.... > > > > > > This may need more work.. > > > > > > I have provided an approach below using an intermediate > > ComplexResultInterceptor class that is thread-safe and minimizes object > > creation using thread local and stacks. It also doesn't require > > ComplexDouble constraint for the generic R result type. > > > > It does require a lot of code that may have a far bigger overhead impact > than just creating a complex result. > > Since thread safety requires an intermediate be stored then it may make > more sense to expand the API to allow operations on a list using a unary > operator of complex: > > UnaryOperator<Complex> op; > > You can then create your function to work on a complex number and chain > them together using the standard java 8 functions. This could be supported > for the ISO c99 functions by just using Complex. Unfortunately this does > not work as the UnaryOperator has not overridden andThen and compose for > the single argument. This is valid: > > UnaryOperator<Complex> op = Complex::sqrt; > // These compose to Function > Function<Complex, Complex> op2 = op.andThen(Complex::conj); > Function<Complex, Complex> op3 = op.compose(Complex::conj); > > // Invalid to assign back to UnaryOperator > op = op.andThen(Complex::conj); > // OK with a cast > op = (UnaryOperator<Complex>) op.andThen(Complex::conj); > > // In use: > // op could be declared as a UnaryOperator<Complex> or Function<Complex, > Complex> to just use the JDK functions as is with full support for > chaining. > list.forEach(op); > > To avoid the cast you can extend Function to add e.g. > > default UnaryOperator<T> andThen(UnaryOperator<T> after) { > Objects.requireNonNull(after); > return (T t) -> after.apply(apply(t)); > } > > I do not know why the JDK has not done this. It seems to compile on my > machine but I've not tested it. > > I think the overhead of creating the Complex objects for the intermediates > may be lower than a solution that tries to avoid allocation overhead with > complexity of ThreadLocal. A performance benchmark would be able to > determine this so we can look at that in the future. > > > > I'm working on this right now, I've refactored most of the existing > > instance methods and I should be done by tomorrow > > > > OK. > > It may be useful here to create a branch in the numbers repository for all > the changes. To keep it simple perhaps a 'develop' branch can be used that > you can make your changes against. > > Alex >