pocomath/src/complex/roundquotient.mjs

20 lines
553 B
JavaScript
Raw Normal View History

import Returns from '../core/Returns.mjs'
export * from './Types/Complex.mjs'
export const roundquotient = {
refactor(Complex): Now a template type! This means that the real and imaginary parts of a Complex must now be the same type. This seems like a real benefit: a Complex with a number real part and a bigint imaginary part does not seem sensible. Note that this is now straining typed-function in (at least) the following ways: (1) In this change, it was necessary to remove the logic that the square root of a negative number calls complex square root, which then calls back to the number square root in its algorithm. (This was creating a circular reference in the typed-function which the old implementation of Complex was somehow sidestepping.) (2) typed-function could not follow conversions that would be allowed by uninstantiated templates (e.g. number => Complex<number> if the latter template has not been instantiated) and so the facility for instantiating a template was surfaced (and for example is called explicitly in the demo loader `extendToComplex`. Similarly, this necessitated making the unary signature of the `complex` conversion function explicit, rather than just via implicit conversion to Complex. (3) I find the order of implementations is mattering more in typed-function definitions, implying that typed-function's sorting algorithm is having trouble distinguishing alternatives. But otherwise, the conversion went quite smoothly and I think is a good demo of the power of this approach. And I expect that it will work even more smoothly if some of the underlying facilities (subtypes, template types) are integrated into typed-function.
2022-08-06 15:27:44 +00:00
'Complex<T>,Complex<T>': ({
T,
refactor(Complex): Now a template type! This means that the real and imaginary parts of a Complex must now be the same type. This seems like a real benefit: a Complex with a number real part and a bigint imaginary part does not seem sensible. Note that this is now straining typed-function in (at least) the following ways: (1) In this change, it was necessary to remove the logic that the square root of a negative number calls complex square root, which then calls back to the number square root in its algorithm. (This was creating a circular reference in the typed-function which the old implementation of Complex was somehow sidestepping.) (2) typed-function could not follow conversions that would be allowed by uninstantiated templates (e.g. number => Complex<number> if the latter template has not been instantiated) and so the facility for instantiating a template was surfaced (and for example is called explicitly in the demo loader `extendToComplex`. Similarly, this necessitated making the unary signature of the `complex` conversion function explicit, rather than just via implicit conversion to Complex. (3) I find the order of implementations is mattering more in typed-function definitions, implying that typed-function's sorting algorithm is having trouble distinguishing alternatives. But otherwise, the conversion went quite smoothly and I think is a good demo of the power of this approach. And I expect that it will work even more smoothly if some of the underlying facilities (subtypes, template types) are integrated into typed-function.
2022-08-06 15:27:44 +00:00
'isZero(Complex<T>)': isZ,
'conjugate(Complex<T>)': conj,
'multiply(Complex<T>,Complex<T>)': mult,
'absquare(Complex<T>)': asq,
'self(T,T)': me,
'complex(T,T)': cplx
}) => Returns(`Complex<${T}>`, (n,d) => {
if (isZ(d)) return d
refactor(Complex): Now a template type! This means that the real and imaginary parts of a Complex must now be the same type. This seems like a real benefit: a Complex with a number real part and a bigint imaginary part does not seem sensible. Note that this is now straining typed-function in (at least) the following ways: (1) In this change, it was necessary to remove the logic that the square root of a negative number calls complex square root, which then calls back to the number square root in its algorithm. (This was creating a circular reference in the typed-function which the old implementation of Complex was somehow sidestepping.) (2) typed-function could not follow conversions that would be allowed by uninstantiated templates (e.g. number => Complex<number> if the latter template has not been instantiated) and so the facility for instantiating a template was surfaced (and for example is called explicitly in the demo loader `extendToComplex`. Similarly, this necessitated making the unary signature of the `complex` conversion function explicit, rather than just via implicit conversion to Complex. (3) I find the order of implementations is mattering more in typed-function definitions, implying that typed-function's sorting algorithm is having trouble distinguishing alternatives. But otherwise, the conversion went quite smoothly and I think is a good demo of the power of this approach. And I expect that it will work even more smoothly if some of the underlying facilities (subtypes, template types) are integrated into typed-function.
2022-08-06 15:27:44 +00:00
const cnum = mult(n, conj(d))
const dreal = asq(d)
return cplx(me(cnum.re, dreal), me(cnum.im, dreal))
})
}