diff --git a/docs/src/man/a_toc.md b/docs/src/man/a_toc.md index 97ba6a5d..b2706977 100644 --- a/docs/src/man/a_toc.md +++ b/docs/src/man/a_toc.md @@ -9,7 +9,7 @@ 7. **[Monomial Indexing](@ref monoindex)**: Get/set individual monomial coefficients 8. **[`mono`](@ref mono)**: Creates a TPS corresponding to a specific monomial 9. **[Slicing and `par`](@ref slice)**: Indexing a specific polynomial within the TPS -10. **[TPS and Map Methods](@ref tpsmapmethods)**: Integrate, differentiate, poisson bracket, map (partial) inversion, etc. +10. **[TPS Methods](@ref tpsmethods)**: Integrate, differentiate, composition, evaluation, etc. 11. **[`@FastGTPSA`](@ref fastgtpsa)**: Speed up evaluation of expressions containing TPSs, transparent to other types 12. **[I/O](@ref io)**: Reading/writing TPSs 13. **[All Overloaded Functions](@ref all)**: List of all overloaded Base functions and more \ No newline at end of file diff --git a/docs/src/man/g_monoindex.md b/docs/src/man/g_monoindex.md index 8a9d41ac..d079cd7f 100644 --- a/docs/src/man/g_monoindex.md +++ b/docs/src/man/g_monoindex.md @@ -4,9 +4,12 @@ Individual monomial coefficients in a TPS can be get/set with two methods of indexing: **by order**, and **by sparse monomial**. ## By Order -`t[, ..., ,, ..., ]` +``` +t[[, ..., ,, ..., ]] +t[(, ..., ,, ..., )] +``` -A particular monomial can be indexed by specifying the orders of each variable and parameter. For example, for a TPS `t` with variables ``x_1``, ``x_2`` and parameter ``k_1`` the ``x_1^3x_2^1k_1^2`` monomial coefficient is accessed with `t[3,1,2]`. The 0th order part (the *scalar* part) of the TPS is indexed with `t[0,0,0]` or equivalently `t[0]`, as leaving out trailing zeros for unincluded variables/parameters is allowed. +A particular monomial can be indexed by specifying the orders of each variable and parameter. For example, for a TPS `t` with variables ``x_1``, ``x_2`` and parameters ``k_1``, ``k_2``, the ``x_1^3x_2^1k_1^2`` monomial coefficient is accessed with `t[[3,1,2,0]]` or equivalently `t[[3,1,2]]`, as leaving out trailing zeros for unincluded variables/parameters is allowed. A tuple is also allowed instead of a vector for the list of orders. ### Examples ```@repl @@ -15,16 +18,19 @@ d = Descriptor(2, 6, 3, 6); # 2 variables, 3 parameters all to 6th order x = vars(d); k = params(d); f = 5 + sin(x[1])*sin(x[2])*cos(k[1]) -f[3,1,2] # Leave out trailing zeros for unincluded variables/parameters -f[0] # Scalar part -f[1,1,1,1,1] = 123; # Set monomial coefficient +f[[3,1,2]] # Leave out trailing zeros for unincluded variables/parameters +f[[0]] # Scalar part +f[(1,1,1,1,1)] = 123; # Set monomial coefficient print(f) ``` ## By Sparse Monomial -`t[ => , ..., params=[ => , ...]]` +``` +t[[ => , ...], params=[ => , ...]] +t[( => , ...), params=( => , ...)] +``` -In GTPSAs with many variables and parameters, indexing-by-order is inconvenient because each order needs to be included up to the last included variable/parameter with nonzero order. In this case, a particular monomial can be indexed instead by specifying each variable/parameter number and its corresponding order in pairs. For example, for a TPS with variables ``x_1, ..., x_{15}`` and parameters ``k_1, ..., k_{10}``, the ``x_{1}^3x_{15}^1k_{10}^2`` monomial coefficient is accessed with `t[1=>3, 15=>1, params=[10=>2]]`. The scalar part of the TPS cannot be get/set with this method. +In GTPSAs with many variables and parameters, indexing-by-order is inconvenient because each order needs to be included up to the last included variable/parameter with nonzero order. In this case, a particular monomial can be indexed instead by specifying each variable/parameter number and its corresponding order in pairs. For example, for a TPS with variables ``x_1, ..., x_{15}`` and parameters ``k_1, ..., k_{10}``, the ``x_{1}^3x_{15}^1k_{10}^2`` monomial coefficient is accessed with `t[[1=>3, 15=>1], params=[10=>2]]`. The scalar part of the TPS cannot be get/set with this method. A tuple is also allowed instead of a vector for the list of pairs. ### Examples ```@repl @@ -34,11 +40,39 @@ GTPSA.show_sparse = true; # Use sparse output x = vars(d); k = params(d); f = 5 + sin(x[1])*sin(x[15])*cos(k[10]) -f[1=>3, 15=>1, params=[10=>2]] -f[1=>1, 15=>2, params=[10=>3]] = 123; # Set monomial coefficient +f[[1=>3, 15=>1], params=[10=>2]] +f[(1=>1, 15=>2), params=(10=>3,)] = 123; # Set monomial coefficient print(f) ``` +## By Monomial Index +``` +t[idx] +t[param=param_idx] +``` + +*This indexing method is not recommended/requires care when indexing monomials above first order.* Indexes the TPS with all monomials sorted by order. For example, for a TPS with one variable ``x_1`` and one parameter ``k_1`` the ``x_1`` monomial is indexed with `t[1]` and the ``x_1^2`` monomial is indexed with either `t[3]`. The ``k_1`` monomial can be indexed with either `t[2]` or equivalently using the `param` helper kwarg `t[param=1]`, which simply adds the number of variables in the GTPSA to the provided index. Note that above first-order, the `param` kwarg is basically useless. The zeroth order part, or the *scalar* part of the TPS, can be set with `t[0]`. This method requires zero allocations for indexing, unlike the other two. + +### Examples +```@repl +using GTPSA; GTPSA.show_sparse = false; GTPSA.show_header=false; #hide +# Example of indexing by monomial index ----------- +d = Descriptor(2, 10, 1, 10); +t = TPS(use=d); # Create zero TPS based on d + +t[0] = 0; +t[1] = 1; +t[2] = 2; +t[3] = 3; # or t[param=1] = 3 +t[4] = 4; +t[5] = 5; +t[6] = 6; +t[7] = 7; +t[8] = 8; +t[9] = 9; +t[10] = 10; +print(t) +``` diff --git a/docs/src/man/h_mono.md b/docs/src/man/h_mono.md index ea3e1587..74029593 100644 --- a/docs/src/man/h_mono.md +++ b/docs/src/man/h_mono.md @@ -2,34 +2,34 @@ *Creates a TPS corresponding to a specific monomial* ## Syntax ``` -m = mono(var_idx [, use=(descriptor|tps|complextps)]) -m = mono(param=param_idx [, use=(descriptor|tps|complextps)]) - m = mono(orders [, use=(descriptor|tps|complextps)]) m = mono([vars_sparse_mono] [, params=params_sparse_mono] [, use=(descriptor|tps|complextps)]) +m = mono(idx [, use=(descriptor|tps|complextps)]) +m = mono(param=param_idx [, use=(descriptor|tps|complextps)]) + m = complexmono(...) ``` ## Description -#### Index by Variable/Parameter - -`m = mono(var_idx)` creates a `TPS` equal to the variable specified by `var_idx` and the `Descriptor` in `GTPSA.desc_current` +#### Indexing by Order -`m = mono(param=param_idx)` creates a `TPS` equal to the parameter specified by `param_idx` and the `Descriptor` in `GTPSA.desc_current` +`m = mono(orders)` creates a `TPS` equal to the monomial specified by the indexing-by-order vector/tuple `orders` using the `Descriptor` in `GTPSA.desc_current` ------ -#### Indexing by Order +#### Indexing by Sparse Monomial -`m = mono(orders)` creates a `TPS` equal to the monomial specified by the indexing-by-order vector `orders` and the `Descriptor` in `GTPSA.desc_current` +`m = mono(vars_sparse_mono, params=params_sparse_mono)` creates a `TPS` equal to the monomial specified by the indexing-by-sparse monomial vector/tuple `vars_sparse_mono` and `params_sparse_mono` using the `Descriptor` in `GTPSA.desc_current` ------ -#### Indexing by Sparse Monomial +#### Indexing by Monomial Index + +`m = mono(idx)` creates a `TPS` equal to the monomial specified by `idx` and the `Descriptor` in `GTPSA.desc_current` -`m = mono(vars_sparse_mono, params=params_sparse_mono)` creates a `TPS` equal to the monomial specified by the indexing-by-sparse monomial vector `vars_sparse_mono` and `params_sparse_mono` and the `Descriptor` in `GTPSA.desc_current` +`m = mono(param=param_idx)` creates a `TPS` equal to the monomial specified by `param_idx + nv` where `nv` is the number of variables in the GTPSA, using the `Descriptor` in `GTPSA.desc_current` ------ @@ -50,9 +50,9 @@ d1 = Descriptor(3, 15, 2, 15); # 3 vars, 2 params, all to order 15 x1 = mono(1) k1 = mono(param=1) m312 = mono([3,1,2]) -m31221 = mono([3,1,2,2,1]) +m31221 = mono((3,1,2,2,1)) # Tuples allowed for indexing m312 = mono([1=>3, 2=>1, 3=>3]) -m31221 = mono([1=>3, 2=>1, 3=>2], params=[1=>2, 2=>1]) +m31221 = mono((1=>3, 2=>1, 3=>2), params=(1=>2, 2=>1)) ``` ## Documentation diff --git a/docs/src/man/j_slice.md b/docs/src/man/j_slice.md index d0a659f3..7ca23855 100644 --- a/docs/src/man/j_slice.md +++ b/docs/src/man/j_slice.md @@ -10,15 +10,22 @@ d = Descriptor(5, 10, 2, 10); x = vars(d); k = params(d); f = 2*x[1]^2*x[3] + 3*x[1]^2*x[2]*x[3]*x[4]^2*x[5]*k[1] + 6*x[3] + 5 -g = f[2,:,1] -h = f[2,:,1,:] +g = f[[2,:,1]] +h = f[[2,:,1,:]] ``` A TPS can also be sliced with indexing by sparse monomial. In this case, if a colon is included anywhere in the sparse monomial variable index, then all orders of all variables and parameters not explicity specified will be included (colon position does not matter in sparse monomial indexing): ```@repl slice -g = f[1=>2, :, 3=>1, 4=>0, 5=>0, params=[1=>0, 2=>0]] -h = f[1=>2, 3=>1, :] # Colon position is irrelevant in slicing with sparse monomial indexing +g = f[[1=>2, :, 3=>1, 4=>0, 5=>0], params=[1=>0, 2=>0]] +h = f[(1=>2, 3=>1, :)] # Colon position is irrelevant in slicing with sparse monomial indexing +``` + +When indexing by monomial index, a colon simply needs to be included after the variable index, or just a colon if a parameter is specified: + +```@repl slice +fx1 = f[1,:] +fk1 = f[:,param=2] ``` ## `par` @@ -30,22 +37,15 @@ h = f[1=>2, 3=>1, :] # Colon position is irrelevant in slicing with sparse mono ### Syntax ``` -f = par(tps, var_idx) -f = par(tps, param=param_idx) - f = par(tps, orders) f = par(tps [, vars_sparse_mono] [, params=params_sparse_mono]) + +f = par(tps, idx) +f = par(tps, param=param_idx) ``` ### Description -#### Index by Variable/Parameter -`f = par(tps, var_idx)` extracts the polynomial from the TPS with a first-order dependence on the specified variable, and removes the variable from the polynomial - -`f = par(tps, param=param_idx)` extracts the polynomial from the TPS with a first-order dependence on the specified parameter, and removes the parameter from the polynomial - ------- - #### Indexing by Order `f = par(tps, orders)` extracts the polynomial from the TPS with the monomial indexed-by-order in `orders`, and removes the variables/parameters included in the indexing from the polynomial @@ -58,6 +58,14 @@ f = par(tps [, vars_sparse_mono] [, params=params_sparse_mono]) `f = par(tps, vars_sparse_mono, params=params_sparse_mono)` extracts the polynomial from the TPS with the monomial indexed-by-sparse monomial in `vars_sparse_mono` and `params_sparse_mono`, and removes the variables and/or parameters included in the indexing from the polynomial +------ + +#### Indexing by Monomial Index +`f = par(tps, idx)` extracts the polynomial from the TPS with a first-order dependence on the specified monomial, and removes the variable from the polynomial + +`f = par(tps, param=param_idx)` extracts the polynomial from the TPS with a first-order dependence on the specified monomial with index `param_idx+nv` where `nv` is the number of variables in the GTPSA, and removes the parameter from the polynomial + + ### Examples ```@repl par diff --git a/docs/src/man/k_methods.md b/docs/src/man/k_methods.md index fd6ed9cd..a799cb0c 100644 --- a/docs/src/man/k_methods.md +++ b/docs/src/man/k_methods.md @@ -1,18 +1,19 @@ -# [TPS and Map Methods](@id tpsmapmethods) +# [TPS Methods](@id tpsmethods) ```@docs +clear! +complex! +compose! cutord +cutord! deriv +deriv! evaluate -exppb -fgrad -gethamiltonian +evaluate! getord -getvectorfield +getord! integ -lb -logpb -pb -ptinv +integ! scalar translate +translate! ``` \ No newline at end of file diff --git a/docs/src/man/o_all.md b/docs/src/man/o_all.md index d11e520f..f820cf59 100644 --- a/docs/src/man/o_all.md +++ b/docs/src/man/o_all.md @@ -6,7 +6,7 @@ sin, cos, tan, csc, sec, cot, sinc, sinh, cosh, tanh, csch, sech, coth, asin, acos, atan, acsc, asec, acot, asinh, acosh, atanh, acsch, asech, acoth, zero, one, real, imag, conj, angle, complex, promote_rule, getindex, setindex!, ==, <, >, <=, >=, -!=, isequal, show +!=, isequal, show, copy! ``` `GTPSA.jl` overloads (and exports) the following functions from the corresponding packages: @@ -15,7 +15,7 @@ complex, promote_rule, getindex, setindex!, ==, <, >, <=, >=, `GTPSA.jl` also provides the following functions NOT included in Base or any of the above packages: ``` -unit, sinhc, asinc, asinhc, polar, rect +unit, sinhc, asinc, asinhc, polar, rect ``` If there is a mathematical function in Base which you'd like and is not included in the above list, feel free to submit an [issue](https://github.com/bmad-sim/GTPSA.jl/issues). \ No newline at end of file diff --git a/docs/src/quickstart.md b/docs/src/quickstart.md index f6e5bad0..6c957a0d 100644 --- a/docs/src/quickstart.md +++ b/docs/src/quickstart.md @@ -52,12 +52,13 @@ Another global variable `GTPSA.show_eps` can be set to exclude showing monomials !!! note The value of a partial derivative is equal to the monomial coefficient in the Taylor series multiplied by a constant factor. E.g. for an expansion around zero ``f(x)\approx f(0) + \frac{\partial f}{\partial x}\rvert_0x + \frac{1}{2!}\frac{\partial^2 f}{\partial x^2}\rvert_0 x^2 + ...``, the 2nd order monomial coefficient is ``\frac{1}{2!}\frac{\partial^2 f}{\partial x^2}\rvert_0``. -Individual monomial coefficients in a TPS `t` can be get/set with two methods of indexing: +Individual monomial coefficients in a TPS `t` can be get/set with three methods of indexing: -1. **By Order:** `t[, ..., ]`. For example, for a TPS with variables ``x_1``, ``x_2``, the ``x_1^3x_2^1`` monomial coefficient is accessed with `t[3,1]`. The 0th order part (the *scalar* part) of the TPS is indexed with `t[0,0]` or equivalently `t[0]`, as leaving out trailing zeros for unincluded variables is allowed. -2. **By Sparse Monomial** `t[ => , ...]`. This method of indexing is convenient when a TPS contains many variables and parameters. For example, for a TPS with variables ``x_1,x_2,...x_{100}``, the ``x_{1}^3x_{99}^1`` monomial coefficient is accessed with `t[1=>3, 99=>1]`. The scalar part of the TPS cannot be get/set with this method. +1. **By Order:** `t[[, ..., ]]`. For example, for a TPS with three variables ``x_1``, ``x_2``, and ``x_3``, the ``x_1^3x_2^1`` monomial coefficient is accessed with `t[[3,1,0]]` or equivalently `t[[3,1]]`, as leaving out trailing zeros for unincluded variables is allowed. A tuple is also allowed instead of a vector for the list of orders. +2. **By Sparse Monomial** `t[[ => , ...]]`. This method of indexing is convenient when a TPS contains many variables and parameters. For example, for a TPS with variables ``x_1,x_2,...x_{100}``, the ``x_{1}^3x_{99}^1`` monomial coefficient is accessed with `t[[1=>3, 99=>1]]`. A tuple is also allowed instead of a vector for the list of pairs. +3. **By Monomial Index** `t[idx]`. *This method is not recommended for indexing above first order.* Indexes the TPS with all monomials sorted by order. For example, for a TPS with two variables ``x_1`` and ``x_2``, the ``x_1`` monomial is indexed with `t[1]` and the ``x_1^2`` monomial is indexed with `t[3]`. The zeroth order part, or the *scalar* part of the TPS, can be set with `t[0]`. This method requires zero allocations for indexing, unlike the other two. -These two methods of indexing are best shown with an example: +These three methods of indexing are best shown with an example: ```@example using GTPSA; GTPSA.show_header=false; GTPSA.show_sparse=false;#hide @@ -65,11 +66,11 @@ using GTPSA; GTPSA.show_header=false; GTPSA.show_sparse=false;#hide d = Descriptor(3, 10); t = TPS(use=d); # Create zero TPS based on d -t[0] = 1; -t[1] = 2; -t[0,1] = 3; -t[0,0,1] = 4; -t[2,1,3] = 5; +t[[0]] = 1; +t[[1]] = 2; +t[[0,1]] = 3; +t[(0,0,1)] = 4; # Tuples also allowed +t[(2,1,3)] = 5; print(t) ``` @@ -80,14 +81,34 @@ using GTPSA; GTPSA.show_header=false; GTPSA.show_sparse=false; #hide d = Descriptor(3, 10); t = TPS(use=d); # Create zero TPS based on d -t[1=>1] = 2; -t[2=>1] = 3; -t[3=>1] = 4; -t[1=>2,2=>1,3=>3] = 5; +t[[1=>1]] = 2; +t[[2=>1]] = 3; +t[[3=>1]] = 4; +t[(1=>2,2=>1,3=>3)] = 5; # Tuples also allowed print(t) ``` +```@example +using GTPSA; GTPSA.show_sparse = false; GTPSA.show_header=false; #hide +# Example of indexing by monomial index ----------- +d = Descriptor(3, 10); +t = TPS(use=d); # Create zero TPS based on d + +t[0] = 0; +t[1] = 1; +t[2] = 2; +t[3] = 3; +t[4] = 4; +t[5] = 5; +t[6] = 6; +t[7] = 7; +t[8] = 8; +t[9] = 9; +t[10] = 10; +print(t) +``` + ### Gradients, Jacobians, Hessians The convenience getters `gradient`, `jacobian`, and `hessian` (as well as their corresponding in-place methods `gradient!`, `jacobian!`, and `hessian!`) are also provided for extracting partial derivatives from a TPS/Vector of TPSs. Note that these functions are not actually calculating anything - at this point the TPS should already have been propagated through the system, and these functions are just extracting the corresponding partial derivatives. @@ -119,8 +140,8 @@ d = Descriptor(5, 10); x = vars(d); f = 2*x[1]^2*x[3] + 3*x[1]^2*x[2]*x[3]*x[4]^2*x[5] + 6*x[3] + 5; -g = f[2,:,1]; -h = f[2,:,1,:]; +g = f[[2,:,1]]; +h = f[[2,:,1,:]]; print(f) print(g) @@ -131,8 +152,8 @@ A TPS can also be sliced with indexing by sparse monomial. In this case, if a co ```@example slice # Colon position does not matter in sparse-monomial indexing -g = f[1=>2, :, 3=>1, 4=>0, 5=>0]; -h = f[1=>2, 3=>1, :]; +g = f[[1=>2, :, 3=>1, 4=>0, 5=>0]]; +h = f[[1=>2, 3=>1, :]]; print(g) diff --git a/src/GTPSA.jl b/src/GTPSA.jl index 4ab80736..d791d978 100644 --- a/src/GTPSA.jl +++ b/src/GTPSA.jl @@ -57,7 +57,8 @@ import Base: +, >=, !=, isequal, - show + show, + copy! import LinearAlgebra: norm import SpecialFunctions: erf, erfc @@ -78,6 +79,8 @@ export norm, polar, rect, + clear!, + complex!, # Monomial as TPS creators: vars, @@ -99,26 +102,17 @@ export # Methods: - evaluate, - compose, - integ, ∫, - deriv, ∂, - getord, - cutord, - pb, - lb, - getvectorfield, - gethamiltonian, - exppb, - logpb, - fgrad, - ptinv, - translate, + evaluate, evaluate!, + compose, compose!, + integ, ∫, integ!, ∫!, + deriv, ∂, deriv!, ∂!, + getord, getord!, + cutord, cutord!, + translate, translate!, par, scalar, setGTPSA!, getGTPSA, - clear!, # Temporaries: @FastGTPSA, @@ -132,798 +126,16 @@ export __t_asech, __t_acoth, __t_real, __t_imag, __t_conj, __t_angle, __t_complex, __t_sinhc, __t_asinc, __t_asinhc, __t_erf, __t_erfc, __t_norm, __t_polar, __t_rect +include("low.jl") # Low level, 1-to-1 Julia-to-C code including C struct definitions +include("descriptor.jl") # Descriptor struct and constructors +include("global.jl") # Global variables +include("tps.jl") # TPS/ComplexTPS structs and constructors +include("utils.jl") # Utility functions including changing Descriptor of TPS +include("ctors.jl") # Convenience constructors (vars, params, mono) +include("getset.jl") # Indexing/slicing TPS, par, convenience getters (gradient, jacobian, hessian) +include("show.jl") # Output +include("operators.jl") # TPS math overloaded operators/functions +include("methods.jl") # Higher-level TPS functions (derivatives, integrals, evaluate, etc) +include("fast_gtpsa.jl") # Everything for the @FastGTPSA macro - -# Low-level functions/structs and constants -const NAMSZ::Int = 16 -include("low_level/mono.jl") -include("low_level/desc.jl") -include("low_level/rtpsa.jl") -include("low_level/ctpsa.jl") - -# Useful type-generic functions: -cycle!(t::Ptr{RTPSA}, i::Cint, n::Cint, m_::Vector{Cuchar}, v_::Ref{Cdouble}) = (@inline; mad_tpsa_cycle!(t, i, n, m_, v_)) -cycle!(t::Ptr{CTPSA}, i::Cint, n::Cint, m_::Vector{Cuchar}, v_::Ref{ComplexF64}) = (@inline; mad_ctpsa_cycle!(t, i, n, m_, v_)) -idxm(t::Ptr{RTPSA}, n::Cint, m::Vector{Cuchar}) = (@inline; mad_tpsa_idxm(t, n, m)) -idxm(t::Ptr{CTPSA}, n::Cint, m::Vector{Cuchar}) = (@inline; mad_ctpsa_idxm(t, n, m)) -seti!(t::Ptr{RTPSA}, i::Cint, a::Cdouble, b::Cdouble) = (@inline; mad_tpsa_seti!(t, i, a, b)) -seti!(t::Ptr{CTPSA}, i::Cint, a::ComplexF64, b::ComplexF64) = (@inline; mad_ctpsa_seti!(t, i, a, b)) -setm!(t::Ptr{RTPSA}, n::Cint, m::Vector{Cuchar}, a::Cdouble, b::Cdouble) = (@inline; mad_tpsa_setm!(t, n, m, a, b)) -setm!(t::Ptr{CTPSA}, n::Cint, m::Vector{Cuchar}, a::ComplexF64, b::ComplexF64) = (@inline; mad_ctpsa_setm!(t, n, m, a, b)) - -const MAD_TPSA::String = :("libgtpsa") -const MAD_TPSA_DEFAULT::Cuchar = 255 -const MAD_TPSA_SAME::Cuchar = 254 -const MAD_DESC_CURR::Ptr{Desc} = C_NULL -const DESC_MAX_TMP::Int = 8 - -# Wrapper struct for Ptr{Desc} -struct Descriptor - desc::Ptr{Desc} - function Descriptor(desc::Ptr{Desc})::Descriptor - d = new(desc) - return d - end -end - -# Global non-constants (types MUST be specified) -desc_current::Descriptor = Descriptor(MAD_DESC_CURR) # Current Descriptor -show_eps::Float64 = 0.0 # Print epsilon -show_sparse::Bool = false # Use sparse monomial print -show_header::Bool = false # Print a header above each TPS - -""" - setGTPSA!(a::AbstractString, val) - -Function to set global variables in GTPSA. Options for `a` are: - -- `desc_current::Descriptor` -- defines the `Descriptor` to use when that information is not explicitly (or implicitly in a TPS copy constructor) available, e.g. when calling `TPS(a)` where `a` is not a TPS. This is set each time a new `Descriptor` is defined -- `show_eps::Float64` -- defines the value below which the absolute value of a monomial coefficient is NOT printed -- `show_sparse::Bool` -- specifies whether the sparse monomial format is used for printing. This is useful for GTPSAs containing a large number of variables and parameters -- `show_header::Bool` -- specifies whether or not to print the GTPSA `Descriptor` information above each TPS output -""" -function setGTPSA!(a::AbstractString, val) - a == "desc_current" && (return (GTPSA.desc_current = val)) - a == "show_eps" && (return (GTPSA.show_eps = val)) - a == "show_sparse" && (return (GTPSA.show_sparse = val)) - a == "show_header" && (return (GTPSA.show_header = val)) - error("Global variable \"$(a)\" does not exist!") -end - -""" - getGTPSA(a::AbstractString) - -Function to get global variables in GTPSA. Options for `a` are: - -- `desc_current::Descriptor` -- defines the `Descriptor` to use when that information is not explicitly (or implicitly in a TPS copy constructor) available, e.g. when calling `TPS(a)` where `a` is not a TPS. This is set each time a new `Descriptor` is defined -- `show_eps::Float64` -- defines the value below which the absolute value of a monomial coefficient is NOT printed -- `show_sparse::Bool` -- specifies whether the sparse monomial format is used for printing. This is useful for GTPSAs containing a large number of variables and parameters -- `show_header::Bool` -- specifies whether or not to print the GTPSA `Descriptor` information above each TPS output -""" -function getGTPSA(a::AbstractString) - a == "desc_current" && (return GTPSA.desc_current) - a == "show_eps" && (return GTPSA.show_eps) - a == "show_sparse" && (return GTPSA.show_sparse) - a == "show_header" && (return GTPSA.show_header) - error("Global variable \"$(a)\" does not exist!") -end - -# Descriptor outer constructors -""" - Descriptor(nv::Integer, mo::Integer)::Descriptor - -Creates a TPSA `Descriptor` with `nv` variables, and a maximum truncation order `mo`. - -### Input -- `nv` -- Number of variables in the TPSA -- `mo` -- Maximum truncation order of the TPSA -""" -function Descriptor(nv::Integer, mo::Integer)::Descriptor - d = Descriptor(mad_desc_newv(convert(Cint, nv), convert(Cuchar, mo))) - GTPSA.desc_current = d - return d -end - -""" - Descriptor(vos::Vector{<:Integer}, mo::Integer)::Descriptor - -Creates a TPSA `Descriptor` with `length(vos)` variables with individual truncation -orders specified in the Vector `vos`, and a maximum truncation order `mo` for the TPSA. - -### Input -- `vos` -- `Vector` of the individual truncation orders of each variable -- `mo` -- Maximum truncation order of the TPSA, <= sum(vos) -""" -function Descriptor(vos::Vector{<:Integer}, mo::Integer)::Descriptor - all(vos .<= mo) == true || error("Atleast one variable truncation order is > the maximum truncation order!") - mo <= sum(vos) || (@info "Maximum order too high: setting maximum order = sum($vos) = $(sum(vos))"; mo = sum(vos)) - nv = length(vos) - np = 0 - po = 0 - no = vos - d = Descriptor(mad_desc_newvpo(convert(Cint, nv), convert(Cuchar, mo), convert(Cint, np), convert(Cuchar, po), convert(Vector{Cuchar}, no))) - GTPSA.desc_current = d - return d -end - -""" - Descriptor(nv::Integer, mo::Integer, np::Integer, po::Integer)::Descriptor - -Creates a TPSA `Descriptor` with `nv` variables and `np` parameters. The maximum -truncation order is `mo` (including the parameters), and the truncation order for -the parameters part of a monomial is `po`. - -### Input -- `nv` -- Number of variables in the TPSA -- `mo` -- Maximum truncation order of the TPSA including variables and parameters -- `np` -- Number of parameters in the TPSA -- `po` -- Truncation order of the parameters part of a monomial -""" -function Descriptor(nv::Integer, mo::Integer, np::Integer, po::Integer)::Descriptor - d = Descriptor(mad_desc_newvp(convert(Cint, nv), convert(Cuchar, mo), convert(Cint, np), convert(Cuchar, po))) - GTPSA.desc_current = d - return d -end - - -""" - Descriptor(vos::Vector{<:Integer}, mo::Integer, pos::Vector{<:Integer}, po::Integer)::Descriptor - -Creates a TPSA `Descriptor` with `length(vos)` variables with individual truncation -orders specified in `vos`, and `length(pos)` parameters with individual truncation -orders specified in `pos`. The maximum truncation order including both variables and -parameters is `mo`, and the truncation order for just the parameters part of the is `po`. - -### Input -- `vos` -- `Vector` of the individual truncation orders of each variable -- `mo` -- Maximum truncation order of the TPSA including variables and parameters -- `pos` -- `Vector` of the individual truncation orders of each parameter -- `po` -- Truncation order of the parameters part of a monomial -""" -function Descriptor(vos::Vector{<:Integer}, mo::Integer, pos::Vector{<:Integer}, po::Integer)::Descriptor - nv = length(vos) - np = length(pos) - no = vcat(vos,pos) - d = Descriptor(mad_desc_newvpo(convert(Cint, nv), convert(Cuchar, mo), convert(Cint, np), convert(Cuchar, po), convert(Vector{Cuchar}, no))) - GTPSA.desc_current = d - return d -end - -# Wrapper struct for Ptr{RTPSA} -mutable struct TPS <: Real - tpsa::Ptr{RTPSA} - function TPS(t1::Ptr{RTPSA})::TPS - t = new(t1) - f(x) = mad_tpsa_del!(x.tpsa) - finalizer(f,t) - return t - end -end - -# Wrapper struct for Ptr{CTPSA} -mutable struct ComplexTPS <: Number - tpsa::Ptr{CTPSA} - function ComplexTPS(ct1::Ptr{CTPSA})::ComplexTPS - ct = new(ct1) - f(x) = mad_ctpsa_del!(x.tpsa) - finalizer(f,ct) - return ct - end -end - -""" - TPS(ta::Union{Real,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::TPS - -Constructor to create a new `TPS` equal to the real value `ta`. If `ta` is a `TPS`, this -is equivalent to a copy constructor, with the result by default having the same `Descriptor` as `ta`. -If `ta` is not a `TPS`, then the `Descriptor` used will by default be `GTPSA.desc_current`. The `Descriptor` -for the constructed `TPS` can be set using `use`. If a `TPS` or `ComplexTPS` is passed to `use`, -the `Descriptor` for that TPS will be used. - -The constructor can also be used to create a copy of a `TPS` under one `Descriptor` to instead -have a different `Descriptor`. In this case, invalid monomials under the new `Descriptor` are removed. - -### Input -- `ta` -- Any `Real` -- `use` -- (Optional) specify which `Descriptor` to use, default is `nothing` which uses the `Descriptor` for `ta` if `ta isa TPS`, else uses `GTPSA.desc_current` - -### Output -- `ret` -- New `TPS` equal to `ta` with removal of invalid monomials if `ta` is a `TPS` and a new `Descriptor` is specified -""" -function TPS(ta::Union{Real,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::TPS - return low_TPS(ta, use) -end - -# --- Blank TPS --- -function low_TPS(ta::Nothing, use::Descriptor) - return TPS(mad_tpsa_newd(use.desc, MAD_TPSA_DEFAULT)) -end - -function low_TPS(ta::Nothing, use::Union{TPS,ComplexTPS}) - return TPS(mad_tpsa_new(Base.unsafe_convert(Ptr{RTPSA}, use.tpsa), MAD_TPSA_SAME)) -end - -function low_TPS(ta::Nothing, use::Nothing) - return TPS(mad_tpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) -end - -# --- Copy ctor --- -function low_TPS(t1::TPS, use::Nothing) - t = TPS(mad_tpsa_new(t1.tpsa, MAD_TPSA_SAME)) - mad_tpsa_copy!(t1.tpsa, t.tpsa) - return t -end - -# --- Change descriptor --- -function low_TPS(t1::TPS, use::Descriptor) - return change(t1, use) -end - -function low_TPS(t1::TPS, use::Union{TPS,ComplexTPS}) - return change(t1, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa).d))) -end - -# --- promote real to TPS --- -function low_TPS(a::Real, use::Nothing) - t = TPS(mad_tpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) - mad_tpsa_set0!(t.tpsa, convert(Float64, 0), convert(Float64,a)) - return t -end - -function low_TPS(a::Real, use::Union{TPS,ComplexTPS}) - t = TPS(mad_tpsa_new(Base.unsafe_convert(Ptr{RTPSA}, use.tpsa), MAD_TPSA_SAME)) - mad_tpsa_set0!(t.tpsa, 0.0, convert(Float64,a)) - return t -end - -function low_TPS(a::Real, use::Descriptor) - t = TPS(mad_tpsa_newd(use.desc, MAD_TPSA_DEFAULT)) - mad_tpsa_set0!(t.tpsa, 0.0, convert(Float64,a)) - return t -end - -# ----------------------- -""" - ComplexTPS(cta::Union{Number,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::ComplexTPS - -Constructor to create a new `ComplexTPS` equal to the number `cta`. If `cta` is a `ComplexTPS` (or `TPS`), this -is equivalent to a copy constructor, with the result by default having the same `Descriptor` as `cta`. If `cta` -is not a `TPS` or`ComplexTPS`, then the `Descriptor` used will by default be `GTPSA.desc_current`. The `Descriptor` -for the constructed `ComplexTPS` can be set using `use`. If a `TPS` or `ComplexTPS` is passed to `use`, -the `Descriptor` for that TPS will be used. - -The constructor can also be used to create a copy of a `ComplexTPS` under one `Descriptor` to instead -have a different `Descriptor`. In this case, invalid monomials under the new `Descriptor` are removed. - -### Input -- `cta` -- Any `Number` -- `use` -- (Optional) specify which `Descriptor` to use, default is `nothing` which uses the `Descriptor` for `cta` if `cta <: Union{TPS,ComplexTPS}`, else uses `GTPSA.desc_current` - -### Output -- `ret` -- New `ComplexTPS` equal to `cta` with removal of invalid monomials if `cta` is a `TPS`/`ComplexTPS` and a new `Descriptor` is specified -""" -function ComplexTPS(cta::Union{Number,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::ComplexTPS - return low_ComplexTPS(cta, use) -end - -# For some reason I need to explicitly define this: -ComplexTPS(t::ComplexTPS; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing) = low_ComplexTPS(t,use) - -# --- Blank ComplexTPS --- -function low_ComplexTPS(cta::Nothing, use::Descriptor) - return ComplexTPS(mad_ctpsa_newd(use.desc, MAD_TPSA_DEFAULT)) -end - -function low_ComplexTPS(cta::Nothing, use::Union{TPS,ComplexTPS}) - return ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, use.tpsa), MAD_TPSA_SAME)) -end - -function low_ComplexTPS(cta::Nothing, use::Nothing) - return ComplexTPS(mad_ctpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) -end - -# --- Copy ctor --- -function low_ComplexTPS(ct1::ComplexTPS, use::Nothing) - ct = ComplexTPS(mad_ctpsa_new(ct1.tpsa, MAD_TPSA_SAME)) - mad_ctpsa_copy!(ct1.tpsa, ct.tpsa) - return ct -end - -function low_ComplexTPS(t1::TPS, use::Nothing) - ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) - mad_ctpsa_cplx!(t1.tpsa, Base.unsafe_convert(Ptr{RTPSA}, C_NULL), ct.tpsa) - return ct -end - -# --- Change descriptor --- -function low_ComplexTPS(t1::Union{TPS,ComplexTPS}, use::Descriptor) - return change(t1, use) -end - -function low_ComplexTPS(t1::Union{TPS,ComplexTPS}, use::Union{TPS,ComplexTPS}) - return change(t1, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa).d))) -end - -# --- promote number to ComplexTPS --- -function low_ComplexTPS(a::Union{Real,Complex}, use::Nothing) - ct = ComplexTPS(mad_ctpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64,a)) - return ct -end - -function low_ComplexTPS(a::Union{Real,Complex}, use::Union{TPS,ComplexTPS}) - ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, use.tpsa), MAD_TPSA_SAME)) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64,a)) - return ct -end - -function low_ComplexTPS(a::Union{Real,Complex}, use::Descriptor) - ct = ComplexTPS(mad_ctpsa_newd(use.desc, MAD_TPSA_DEFAULT)) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64,a)) - return ct -end - -# ----------------------- - -# Special real argument ctors -function ComplexTPS(ta::Real, tb::Real; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::ComplexTPS - low_ComplexTPS(ta, tb, use) -end - -function low_ComplexTPS(t1::TPS, t2::TPS, use::Nothing) - ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) - mad_ctpsa_cplx!(t1.tpsa, t2.tpsa, ct.tpsa) - return ct -end - -function low_ComplexTPS(t1::TPS, a::Real, use::Nothing) - ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) - mad_ctpsa_cplx!(t1.tpsa, Base.unsafe_convert(Ptr{RTPSA}, C_NULL), ct.tpsa) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, complex(0,a))) - return ct -end - -function low_ComplexTPS(a::Real, t1::TPS, use::Nothing) - ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) - mad_ctpsa_cplx!(Base.unsafe_convert(Ptr{RTPSA}, C_NULL), t1.tpsa, ct.tpsa) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, a)) - return ct -end - -function low_ComplexTPS(a::Real, b::Real, use::Nothing) - ct = ComplexTPS(mad_ctpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64, complex(a,b))) - return ct -end - -function low_ComplexTPS(a::Real, b::Real, use::Descriptor) - ct = ComplexTPS(mad_ctpsa_newd(use.desc, MAD_TPSA_DEFAULT)) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64, complex(a,b))) - return ct -end - -function low_ComplexTPS(a::Real, b::Real, use::Union{TPS,ComplexTPS}) - ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, use.tpsa), MAD_TPSA_SAME)) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64, complex(a,b))) - return ct -end - -function low_ComplexTPS(ta::TPS, tb::TPS, use::Descriptor) - ct = change(ta, use, type=ComplexTPS) - change!(ct, tb, 1, im) - return ct -end - -function low_ComplexTPS(ta::TPS, b::Real, use::Descriptor) - ct = change(ta, use, type=ComplexTPS) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, complex(0,b))) - return ct -end - -function low_ComplexTPS(a::Real, tb::TPS, use::Descriptor) - ct = change(tb, use, type=ComplexTPS, scl2=im) - mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, a)) - return ct -end - -function low_ComplexTPS(ta::TPS, tb::TPS, use::Union{TPS,ComplexTPS}) - return low_ComplexTPS(ta, tb, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa)))) -end - -function low_ComplexTPS(ta::TPS, b::Real, use::Union{TPS,ComplexTPS}) - return low_ComplexTPS(ta, b, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa)))) -end - -function low_ComplexTPS(a::Real, tb::TPS, use::Union{TPS,ComplexTPS}) - return low_ComplexTPS(a, tb, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa)))) -end - -# --- Variable/parameter generators --- - -""" - vars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} - -Returns `TPS`s corresponding to the variables for the `Descriptor` specified by `use`. -Default value is `GTPSA.desc_current`. - -### Input -- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` - -### Output -- `x` -- `Vector` containing unit `TPS`s corresponding to each variable -""" -function vars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} - t1 = TPS(use=use) - desc = unsafe_load(mad_tpsa_desc(t1.tpsa)) - nv = desc.nv - if nv < 1 - return TPS[] - end - x = Vector{TPS}(undef, nv) - t1[1] = 1.0 - x[1] = t1 - for i=2:nv - t = TPS(use=use) - mad_tpsa_seti!(t.tpsa, Cint(i), 0.0, 1.0) - x[i] = t - end - return x -end - -""" - params(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} - -Returns `TPS`s corresponding to the parameters for the `Descriptor` specified by `use`. -Default value is `GTPSA.desc_current`. - -### Input -- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` - -### Output -- `k` -- `Vector` containing unit `TPS`s corresponding to each parameter -""" -function params(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} - t1 = TPS(use=use) - desc = unsafe_load(mad_tpsa_desc(t1.tpsa)) - nv = desc.nv - np = desc.np - if np < 1 - return TPS[] - end - k = Vector{TPS}(undef, np) - mad_tpsa_seti!(t1.tpsa, Cint(nv+1), 0.0, 1.0) - k[1] = t1 - for i=nv+2:nv+np - t = TPS(use=use) - mad_tpsa_seti!(t.tpsa, Cint(i), 0.0, 1.0) - k[i-nv] = t - end - return k -end - - -""" - complexvars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{ComplexTPS} - -Returns `ComplexTPS`s corresponding to the variables for the `Descriptor` specified by `use`. -Default value is `GTPSA.desc_current`. - -### Input -- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` - -### Output -- `x` -- `Vector` containing unit `ComplexTPS`s corresponding to each variable -""" -function complexvars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{ComplexTPS} - ct1 = ComplexTPS(use=use) - desc = unsafe_load(mad_ctpsa_desc(ct1.tpsa)) - nv = desc.nv - if nv < 1 - return ComplexTPS[] - end - x = Vector{ComplexTPS}(undef, nv) - ct1[1] = 1.0 - x[1] = ct1 - for i=2:nv - ct = ComplexTPS(use=use) - mad_ctpsa_seti!(ct.tpsa, Cint(i), ComplexF64(0.0), ComplexF64(1.0)) - x[i] = ct - end - return x -end - -""" - complexparams(d::Descriptor=GTPSA.desc_current)::Vector{ComplexTPS} - -Returns `ComplexTPS`s corresponding to the parameters for the `Descriptor` specified by `use`. -Default value is `GTPSA.desc_current`. - -### Input -- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` - -### Output -- `k` -- `Vector` containing unit `ComplexTPS`s corresponding to each parameter -""" -function complexparams(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{ComplexTPS} - ct1 = ComplexTPS(use=use) - desc = unsafe_load(mad_ctpsa_desc(ct1.tpsa)) - nv = desc.nv - np = desc.np - if np < 1 - return ComplexTPS[] - end - k = Vector{ComplexTPS}(undef, np) - mad_ctpsa_seti!(ct1.tpsa, Cint(nv+1), ComplexF64(0.0), ComplexF64(1.0)) - k[1] = ct1 - for i=nv+2:nv+np - ct = ComplexTPS(use=use) - mad_ctpsa_seti!(ct.tpsa, Cint(i), ComplexF64(0.0), ComplexF64(1.0)) - k[i-nv] = ct - end - return k -end - -""" - mono(v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing, use::Descriptor=GTPSA.desc_current)::TPS - -Returns a `TPS` corresponding to a specific monomial, specified using the variable/parameter index, or -monomial indexing-by-order OR monomial indexing-by-sparse monomial. - -### Input -- `v` -- An integer (for variable index), an array of orders for each variable (for indexing-by-order), or an array of pairs (sparse monomial) -- `param` -- (Keyword argument, optional) An integer for the parameter index -- `params` -- (Keyword argument, optional) An array of pairs for sparse-monomial indexing -- `use` -- (Keyword argument, optional) The descriptor to use to generate the monomial. Default is most recently-defined. - -# Examples: Variable/Parameter Index: -```julia-repl -julia> d = Descriptor(3,10,2,10); - -julia> mono(1) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 1 0 0 0 0 - - -julia> mono(2, use=d) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 0 1 0 0 0 - - -julia> mono(param=2) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 0 0 0 0 1 -``` - -# Examples: Monomial Index-by-Order -```julia-repl -julia> mono([1]) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 1 0 0 0 0 - - -julia> mono([0,1]) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 0 1 0 0 0 - - -julia> mono([0,0,0,0,1], use=d) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 0 0 0 0 1 - - -julia> mono([1,0,0,0,1]) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 2 1 0 0 0 1 -``` - -# Examples: Monomial Index-by-Sparse Monomial -```julia-repl -julia> mono([1=>1]) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 1 0 0 0 0 - - -julia> mono([2=>1]) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 0 1 0 0 0 - - -julia> mono([1=>1], params=[2=>1], use=d) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 2 1 0 0 0 1 -``` -""" -function mono(v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing, use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::TPS - return low_mono(TPS, use, v, param, params) -end - -function complexmono(v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing, use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::ComplexTPS - return low_mono(ComplexTPS, use, v, param, params) -end - -# Variable/parameter: -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Integer, param::Nothing, params::Nothing)::T - t = T(use=d) - seti!(t.tpsa, Cint(v), convert(numtype(T), 0.0), convert(numtype(T), 1.0)) - return t -end - -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Nothing, param::Integer, params::Nothing)::T - t = T(use=d) - desc = unsafe_load(mad_tpsa_desc(t.tpsa)) - nv = desc.nv # TOTAL NUMBER OF VARS!!!! - seti!(t.tpsa, Cint(param) + nv, convert(numtype(T), 0.0), convert(numtype(T), 1.0)) - return t -end - -# Default to scalar value if nothing passed -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Nothing, param::Nothing, params::Nothing)::T - t = T(use=d) - t[0] = 1.0 - return t -end - -# Monomial by order: -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Vector{<:Integer}, param::Nothing, params::Nothing)::T - t = T(use=d) - t[v...] = 1.0 - return t -end - -# Monomial by sparse monomial: -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Vector{<:Pair{<:Integer,<:Integer}}, param::Nothing, params::Vector{<:Pair{<:Integer,<:Integer}})::T - t = T(use=d) - t[v..., params=params] = 1.0 - return t -end - -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Vector{<:Pair{<:Integer,<:Integer}}, param::Nothing, params::Nothing)::T - t = T(use=d) - # Need to create array of orders with length nv + np - t[v...] = 1.0 - return t -end - -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Nothing, param::Nothing, params::Vector{<:Pair{<:Integer,<:Integer}})::T - t = T(use=d) - t[params=params] = 1.0 - return t -end - -# Throw error if no above use cases satisfied: -function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v, param, params) - error("Invalid monomial specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") -end - -# Function to convert var=>ord, params=(param=>ord,) to low level sparse monomial format (varidx1, ord1, varidx2, ord2, paramidx, ordp1,...) -function pairs_to_sm(t::Union{TPS,ComplexTPS}, vars::Union{Vector{<:Pair{<:Integer, <:Integer}},Tuple{Vararg{Pair{<:Integer,<:Integer}}}}; params::Vector{<:Pair{<:Integer,<:Integer}}=Pair{Int,Int}[])::Tuple{Vector{Cint}, Cint} - # WE MUST Order THE VARIABLES !!! - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)) - nv = desc.nv # TOTAL NUMBER OF VARS!!!!!! - numv = Cint(length(vars)) - nump = Cint(length(params)) - imin = min(minimum(x->x.first, vars,init=typemax(Int)), minimum(x->x.first+nv, params,init=typemax(Int))) - imax = max(maximum(x->x.first, vars,init=0), maximum(x->x.first+nv, params,init=0)) - len = imax-imin+1 - sm = zeros(Cint, 2*len) - sm[1:2:end] = imin:imax - for i=1:numv - sm[2*(vars[i].first-imin+1)] = convert(Cint, vars[i].second) - end - for i=1:nump - sm[2*(params[i].first+nv-imin+1)] = convert(Cint, params[i].second) - end - - return sm, 2*len -end - -# Function to convert var=>ord, params=(param=>ord,) to monomial format (byte array of orders) -function pairs_to_m(t::Union{TPS,ComplexTPS}, vars::Union{Vector{<:Pair{<:Integer, <:Integer}},Tuple{Vararg{Pair{<:Integer,<:Integer}}}}; params::Vector{<:Pair{<:Integer,<:Integer}}=Pair{Int,Int}[],zero_mono=true)::Tuple{Vector{UInt8}, Cint} - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)) - nv = desc.nv - n = Cint(0) - if isempty(params) - n = Cint(maximum(map(x->x.first, vars))) - else - n = Cint(maximum(map(x->x.first, params))) + nv - end - if zero_mono - ords = zeros(Cuchar, n) - else - ords = ones(Cuchar, n).*0xff - end - for var in vars - ords[var.first] = convert(Cuchar, var.second) - end - for param in params - ords[nv + param.first] = convert(Cuchar, param.second) - end - return ords, n -end - -# Generic function to make new copy of TPS with different descriptor -function change(t1::Union{TPS,ComplexTPS}, newd::Descriptor; type::Type=typeof(t1), scl2::Number=1) - # Quick check if actually changing - if Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d) == newd.desc - return type(t1) - end - - # THE NUMBER OF VARIABLES and PARAMETERS MUST AGREE!!! - unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)).nv == unsafe_load(newd.desc).nv || error("Number of variables in GTPSAs do not agree!") - unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)).np == unsafe_load(newd.desc).np || error("Number of parameters in GTPSAs do not agree!") - - t = type(use=newd) - change!(t, t1, 0, scl2) - return t -end - -function change!(t::Union{TPS,ComplexTPS},t1::Union{TPS,ComplexTPS}, scl1::Number=0, scl2::Number=1) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)) - nv = desc.nv - np = desc.np - coef = Ref{numtype(t1)}() - mono = Vector{Cuchar}(undef, np+nv) - idx = cycle!(t1.tpsa, Cint(-1), np+nv, mono, coef) - while idx >= 0 - # if valid monomial in new descriptor: - if convert(Bool, mad_desc_isvalidm(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d), np+nv, mono)) - setm!(t.tpsa, np+nv, mono, convert(numtype(t), scl1), convert(numtype(t), scl2*coef[])) # set new tpsa - end - idx = cycle!(t1.tpsa, idx, np+nv, mono, coef) - end -end - -include("getset.jl") -include("show.jl") -include("operators.jl") -include("methods.jl") -include("fast_gtpsa.jl") - -# Prevent undefined behavior -# Until AbstractComplex is implemented, I make the ctor return error because this should never happen -# asumming I wrapped enough -#= -Complex(t1::TPS) = complex(t1) -Complex(t1::TPS, t2::TPS) = complex(t1, t2) -Complex(t1::TPS, a::Real) = complex(t1, a) -Complex(a::Real, t1::TPS) = complex(a, t1) -Complex{TPS}(t1::TPS) = complex(t1) -Complex{TPS}(t1::TPS, t2::TPS) = complex(t1, t2) -Complex{TPS}(t1::TPS, a::Real) = complex(t1, a) -Complex{TPS}(a::Real, t1::TPS) = complex(a, t1)=# -Complex(t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") -Complex(t1::TPS, t2::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") -Complex(t1::TPS, a::Real) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") -Complex(a::Real, t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") -Complex{TPS}(t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") -Complex{TPS}(t1::TPS, t2::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") -Complex{TPS}(t1::TPS, a::Real) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") -Complex{TPS}(a::Real, t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") - - -promote_rule(::Type{TPS}, ::Union{Type{<:AbstractFloat}, Type{<:Integer}, Type{<:Rational}, Type{<:AbstractIrrational}}) = TPS -promote_rule(::Type{ComplexTPS}, ::Union{Type{Complex{<:Real}},Type{<:AbstractFloat}, Type{<:Integer}, Type{<:Rational}, Type{<:AbstractIrrational}}) = ComplexTPS -promote_rule(::Type{TPS}, ::Union{Type{ComplexTPS}, Type{Complex{<:Real}}}) = ComplexTPS - -# Handle bool which is special for some reason -+(t::TPS, z::Complex{Bool}) = t + Complex{Int}(z) -+(z::Complex{Bool}, t::TPS) = Complex{Int}(z) + t --(t::TPS, z::Complex{Bool}) = t - Complex{Int}(z) --(z::Complex{Bool}, t::TPS) = Complex{Int}(z) - t -*(t::TPS, z::Complex{Bool}) = t * Complex{Int}(z) -*(z::Complex{Bool}, t::TPS) = Complex{Int}(z) * t -/(t::TPS, z::Complex{Bool}) = t / Complex{Int}(z) -/(z::Complex{Bool}, t::TPS) = Complex{Int}(z) / t -^(t::TPS, z::Complex{Bool}) = t ^ Complex{Int}(z) -^(z::Complex{Bool}, t::TPS) = Complex{Int}(z) ^ t end diff --git a/src/ctors.jl b/src/ctors.jl new file mode 100644 index 00000000..c067d1bc --- /dev/null +++ b/src/ctors.jl @@ -0,0 +1,241 @@ + + +# --- Variable/parameter generators --- + +""" + vars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} + +Returns `TPS`s corresponding to the variables for the `Descriptor` specified by `use`. +Default value is `GTPSA.desc_current`. + +### Input +- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` + +### Output +- `x` -- `Vector` containing unit `TPS`s corresponding to each variable +""" +function vars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} + nv = numvars(use) + x = Vector{TPS}(undef, nv) + for i=1:nv + t = TPS(use=use) + t[i] = 1.0 + x[i] = t + end + return x +end + +""" + params(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} + +Returns `TPS`s corresponding to the parameters for the `Descriptor` specified by `use`. +Default value is `GTPSA.desc_current`. + +### Input +- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` + +### Output +- `k` -- `Vector` containing unit `TPS`s corresponding to each parameter +""" +function params(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{TPS} + nv = numvars(use) + np = numparams(use) + k = Vector{TPS}(undef, np) + for i=nv+1:nv+np + t = TPS(use=use) + t[i] = 1.0 + k[i-nv] = t + end + return k +end + + +""" + complexvars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{ComplexTPS} + +Returns `ComplexTPS`s corresponding to the variables for the `Descriptor` specified by `use`. +Default value is `GTPSA.desc_current`. + +### Input +- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` + +### Output +- `x` -- `Vector` containing unit `ComplexTPS`s corresponding to each variable +""" +function complexvars(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{ComplexTPS} + nv = numvars(use) + x = Vector{ComplexTPS}(undef, nv) + for i=1:nv + t = ComplexTPS(use=use) + t[i] = 1.0 + x[i] = t + end + return x +end + +""" + complexparams(d::Descriptor=GTPSA.desc_current)::Vector{ComplexTPS} + +Returns `ComplexTPS`s corresponding to the parameters for the `Descriptor` specified by `use`. +Default value is `GTPSA.desc_current`. + +### Input +- `use` -- (Optional) Specify which TPSA `Descriptor` to use, default is `GTPSA.desc_current` + +### Output +- `k` -- `Vector` containing unit `ComplexTPS`s corresponding to each parameter +""" +function complexparams(use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current)::Vector{ComplexTPS} + nv = numvars(use) + np = numparams(use) + k = Vector{ComplexTPS}(undef, np) + for i=nv+1:nv+np + t = ComplexTPS(use=use) + t[i] = 1.0 + k[i-nv] = t + end + return k +end + +""" + mono(v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer}}, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing, use::Descriptor=GTPSA.desc_current)::TPS + +Returns a `TPS` corresponding to a specific monomial, specified using the variable/parameter index, or +monomial indexing-by-order OR monomial indexing-by-sparse monomial. + +### Input +- `v` -- An integer (for variable index), an array of orders for each variable (for indexing-by-order), or an array of pairs (sparse monomial) +- `param` -- (Keyword argument, optional) An integer for the parameter index +- `params` -- (Keyword argument, optional) An array of pairs for sparse-monomial indexing +- `use` -- (Keyword argument, optional) The descriptor to use to generate the monomial. Default is most recently-defined. + +# Examples: Variable/Parameter Index: +```julia-repl +julia> d = Descriptor(3,10,2,10); + +julia> mono(1) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 1 0 0 0 0 + + +julia> mono(2, use=d) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 0 1 0 0 0 + + +julia> mono(param=2) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 0 0 0 0 1 +``` + +# Examples: Monomial Index-by-Order +```julia-repl +julia> mono([1]) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 1 0 0 0 0 + + +julia> mono([0,1]) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 0 1 0 0 0 + + +julia> mono([0,0,0,0,1], use=d) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 0 0 0 0 1 + + +julia> mono([1,0,0,0,1]) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 2 1 0 0 0 1 +``` + +# Examples: Monomial Index-by-Sparse Monomial +```julia-repl +julia> mono([1=>1]) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 1 0 0 0 0 + + +julia> mono([2=>1]) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 1 0 1 0 0 0 + + +julia> mono([1=>1], params=[2=>1], use=d) +TPS: + Coefficient Order Exponent + 1.0000000000000000e+00 2 1 0 0 0 1 +``` +""" +function mono(v::Union{TPSIndexType,Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType,Nothing}=nothing, use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current) + return low_mono(TPS, use, v, param, params) +end + +function complexmono(v::Union{TPSIndexType,Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType,Nothing}=nothing, use::Union{Descriptor,TPS,ComplexTPS}=GTPSA.desc_current) + return low_mono(ComplexTPS, use, v, param, params) +end + +# Variable/parameter: +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Integer, param::Nothing, params::Nothing) + t = T(use=d) + seti!(t.tpsa, Cint(v), convert(numtype(T), 0.0), convert(numtype(T), 1.0)) + return t +end + +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Nothing, param::Integer, params::Nothing) + t = T(use=d) + desc = unsafe_load(mad_tpsa_desc(t.tpsa)) + nv = desc.nv # TOTAL NUMBER OF VARS!!!! + seti!(t.tpsa, Cint(param) + nv, convert(numtype(T), 0.0), convert(numtype(T), 1.0)) + return t +end + +# Default to scalar value if nothing passed +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Nothing, param::Nothing, params::Nothing) + t = T(use=d) + t[0] = 1.0 + return t +end + +# Monomial by order: +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::MIndexType, param::Nothing, params::Nothing) + t = T(use=d) + t[v] = 1.0 + return t +end + +# Monomial by sparse monomial: +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::SMIndexType, param::Nothing, params::SMIndexType) + t = T(use=d) + t[v, params=params] = 1.0 + return t +end + +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::SMIndexType, param::Nothing, params::Nothing) + t = T(use=d) + # Need to create array of orders with length nv + np + t[v] = 1.0 + return t +end + +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v::Nothing, param::Nothing, params::SMIndexType) + t = T(use=d) + t[params=params] = 1.0 + return t +end + +# Throw error if no above use cases satisfied: +function low_mono(T::Type, d::Union{Descriptor,TPS,ComplexTPS}, v, param, params) + error("Invalid monomial specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") +end + diff --git a/src/descriptor.jl b/src/descriptor.jl new file mode 100644 index 00000000..46dfb625 --- /dev/null +++ b/src/descriptor.jl @@ -0,0 +1,89 @@ +# Wrapper struct for Ptr{Desc} +struct Descriptor + desc::Ptr{Desc} + function Descriptor(desc::Ptr{Desc})::Descriptor + d = new(desc) + return d + end +end + +# Descriptor outer constructors +""" + Descriptor(nv::Integer, mo::Integer)::Descriptor + +Creates a TPSA `Descriptor` with `nv` variables, and a maximum truncation order `mo`. + +### Input +- `nv` -- Number of variables in the TPSA +- `mo` -- Maximum truncation order of the TPSA +""" +function Descriptor(nv::Integer, mo::Integer)::Descriptor + d = Descriptor(mad_desc_newv(convert(Cint, nv), convert(Cuchar, mo))) + GTPSA.desc_current = d + return d +end + +""" + Descriptor(vos::Vector{<:Integer}, mo::Integer)::Descriptor + +Creates a TPSA `Descriptor` with `length(vos)` variables with individual truncation +orders specified in the Vector `vos`, and a maximum truncation order `mo` for the TPSA. + +### Input +- `vos` -- `Vector` of the individual truncation orders of each variable +- `mo` -- Maximum truncation order of the TPSA, <= sum(vos) +""" +function Descriptor(vos::Vector{<:Integer}, mo::Integer)::Descriptor + all(vos .<= mo) == true || error("Atleast one variable truncation order is > the maximum truncation order!") + mo <= sum(vos) || (@info "Maximum order too high: setting maximum order = sum($vos) = $(sum(vos))"; mo = sum(vos)) + nv = length(vos) + np = 0 + po = 0 + no = vos + d = Descriptor(mad_desc_newvpo(convert(Cint, nv), convert(Cuchar, mo), convert(Cint, np), convert(Cuchar, po), convert(Vector{Cuchar}, no))) + GTPSA.desc_current = d + return d +end + +""" + Descriptor(nv::Integer, mo::Integer, np::Integer, po::Integer)::Descriptor + +Creates a TPSA `Descriptor` with `nv` variables and `np` parameters. The maximum +truncation order is `mo` (including the parameters), and the truncation order for +the parameters part of a monomial is `po`. + +### Input +- `nv` -- Number of variables in the TPSA +- `mo` -- Maximum truncation order of the TPSA including variables and parameters +- `np` -- Number of parameters in the TPSA +- `po` -- Truncation order of the parameters part of a monomial +""" +function Descriptor(nv::Integer, mo::Integer, np::Integer, po::Integer)::Descriptor + d = Descriptor(mad_desc_newvp(convert(Cint, nv), convert(Cuchar, mo), convert(Cint, np), convert(Cuchar, po))) + GTPSA.desc_current = d + return d +end + + +""" + Descriptor(vos::Vector{<:Integer}, mo::Integer, pos::Vector{<:Integer}, po::Integer)::Descriptor + +Creates a TPSA `Descriptor` with `length(vos)` variables with individual truncation +orders specified in `vos`, and `length(pos)` parameters with individual truncation +orders specified in `pos`. The maximum truncation order including both variables and +parameters is `mo`, and the truncation order for just the parameters part of the is `po`. + +### Input +- `vos` -- `Vector` of the individual truncation orders of each variable +- `mo` -- Maximum truncation order of the TPSA including variables and parameters +- `pos` -- `Vector` of the individual truncation orders of each parameter +- `po` -- Truncation order of the parameters part of a monomial +""" +function Descriptor(vos::Vector{<:Integer}, mo::Integer, pos::Vector{<:Integer}, po::Integer)::Descriptor + nv = length(vos) + np = length(pos) + no = vcat(vos,pos) + d = Descriptor(mad_desc_newvpo(convert(Cint, nv), convert(Cuchar, mo), convert(Cint, np), convert(Cuchar, po), convert(Vector{Cuchar}, no))) + GTPSA.desc_current = d + return d +end \ No newline at end of file diff --git a/src/getset.jl b/src/getset.jl index f1c0d175..29aea9da 100644 --- a/src/getset.jl +++ b/src/getset.jl @@ -1,77 +1,150 @@ -numtype(t::TPS) = Float64 -numtype(ct::ComplexTPS) = ComplexF64 -numtype(::Type{TPS}) = Float64 -numtype(::Type{ComplexTPS}) = ComplexF64 +# --- Setters --- +seti!(t::Ptr{RTPSA}, i::Cint, a::Cdouble, b::Cdouble) = mad_tpsa_seti!(t, i, a, b) +seti!(t::Ptr{CTPSA}, i::Cint, a::ComplexF64, b::ComplexF64) = mad_ctpsa_seti!(t, i, a, b) +setm!(t::Ptr{RTPSA}, n::Cint, m::Vector{Cuchar}, a::Float64, b::Float64) = mad_tpsa_setm!(t, n, m, a, b) +setm!(t::Ptr{CTPSA}, n::Cint, m::Vector{Cuchar}, a::ComplexF64, b::ComplexF64) = mad_ctpsa_setm!(t, n, m, a, b) +setsm!(t::Ptr{RTPSA}, n::Cint, m::Vector{Cint}, a::Float64, b::Float64)= mad_tpsa_setsm!(t, n, m, a, b) +setsm!(t::Ptr{CTPSA}, n::Cint, m::Vector{Cint}, a::ComplexF64, b::ComplexF64)= mad_ctpsa_setsm!(t, n, m, a, b) + +# All +function setindex!(t::Union{TPS,ComplexTPS}, v::Number, idx::Union{TPSIndexType,Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType,Nothing}=nothing) + lowset!(t, v, idx, param, params) +end -lowtype(t::TPS) = Ptr{RTPSA} -lowtype(ct::ComplexTPS) = Ptr{CTPSA} -lowtype(::Type{TPS}) = Ptr{RTPSA} -lowtype(::Type{ComplexTPS}) = Ptr{CTPSA} +# To override Base number.jl +#setindex!(t::Union{ComplexTPS, TPS}, v::Number, idx::Integer) = lowset!(t, v, tuple(idx), nothing, nothing) -# --- Setters --- -function setindex!(t::TPS, v::Real, ords::Integer...) - mad_tpsa_setm!(t.tpsa, convert(Cint, length(ords)), convert(Vector{Cuchar}, [ords...]), 0.0, convert(Cdouble, v)) +# Flat index +function lowset!(t::Union{TPS,ComplexTPS}, v::Number, i::Union{Nothing,Integer}, param::Union{Nothing,Integer}, params::Nothing) + if !xor(isnothing(i), isnothing(param)) + error("Invalid monomial index specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") + end + + if isnothing(param) + seti!(t.tpsa, Cint(i), (numtype(t))(0), (numtype(t))(v)) + else + nv = numvars(t) + seti!(t.tpsa, Cint(nv+param), (numtype(t))(0), (numtype(t))(v)) + end end -function setindex!(t::TPS, v::Real, vars::Pair{<:Integer, <:Integer}...; params::Vector{<:Pair{<:Integer,<:Integer}}=Pair{Int,Int}[]) - sm, n = pairs_to_sm(t, vars, params=params) - mad_tpsa_setsm!(t.tpsa, n, sm, 0.0, convert(Cdouble, v)) +# Monomial +function lowset!(t::Union{TPS,ComplexTPS}, v::Number, ords::MIndexType, param::Nothing, params::Nothing) + setm!(t.tpsa, convert(Cint, length(ords)), collect(Cuchar, ords), (numtype(t))(0), (numtype(t))(v)) end -function setindex!(ct::ComplexTPS, v::Number, ords::Integer...) - mad_ctpsa_setm!(ct.tpsa, convert(Cint, length(ords)), convert(Vector{Cuchar}, [ords...]), convert(ComplexF64, 0), convert(ComplexF64, v)) +# By sparse monomial +function lowset!(t::Union{TPS,ComplexTPS}, v::Number, vars::SMIndexType, param::Nothing, params::Union{SMIndexType,Nothing}) + sm, n = pairs_to_sm(t, vars, params=params) + setsm!(t.tpsa, n, sm, (numtype(t))(0), (numtype(t))(v)) end -function setindex!(ct::ComplexTPS, v::Number, vars::Pair{<:Integer, <:Integer}...; params::Vector{<:Pair{<:Integer,<:Integer}}=Pair{Int,Int}[]) - sm, n = pairs_to_sm(ct, vars, params=params) - mad_ctpsa_setsm!(ct.tpsa, n, sm, convert(ComplexF64, 0), convert(ComplexF64, v)) +# Sparse monomial with nothing for vars +function lowset!(t::Union{TPS,ComplexTPS}, v::Number, vars::Nothing, param::Nothing, params::SMIndexType) + sm, n = pairs_to_sm(t, Pair{Int,Int}[], params=params) + setsm!(t.tpsa, n, sm, (numtype(t))(0), (numtype(t))(v)) end +# In case someone forgets tuple: +lowset!(t, v, idx, param, params) = error("Invalid monomial index specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") + # --- Getters --- +geti(t::Ptr{RTPSA}, i::Cint) = mad_tpsa_geti(t, i) +geti(t::Ptr{CTPSA}, i::Cint) = mad_ctpsa_geti(t, i) getm(t::Ptr{RTPSA}, n::Cint, m::Vector{Cuchar}) = mad_tpsa_getm(t, n, m) getm(t::Ptr{CTPSA}, n::Cint, m::Vector{Cuchar}) = mad_ctpsa_getm(t, n, m) getsm(t::Ptr{RTPSA}, n::Cint, m::Vector{Cint})= mad_tpsa_getsm(t, n, m) getsm(t::Ptr{CTPSA}, n::Cint, m::Vector{Cint})= mad_ctpsa_getsm(t, n, m) -function getindex(t::Union{TPS,ComplexTPS}, ords::Integer...) - return getm(t.tpsa, convert(Cint, length(ords)), convert(Vector{Cuchar}, [ords...])) +# All +function getindex(t::Union{TPS,ComplexTPS}, idx::Union{TPSIndexType,Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType,Nothing}=nothing) + #println(typeof(t)) + #println(typeof(idx)) + #println(typeof(param)) + #println(typeof(params)) + return lowget(t, idx, param, params) +end + +# To override Base number.jl +getindex(t::Union{ComplexTPS, TPS}, idx::Integer) = lowget(t, idx, nothing, nothing) + +# Flat index +function lowget(t::Union{TPS,ComplexTPS}, i::Union{Nothing,Integer}, param::Union{Nothing,Integer}, params::Nothing) + if !xor(isnothing(i), isnothing(param)) + error("Invalid monomial index specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") + end + + if isnothing(param) + return geti(t.tpsa, Cint(i)) + else + nv = numvars(t) + return geti(t.tpsa, Cint(nv+param)) + end +end + +# Monomial +function lowget(t::Union{TPS,ComplexTPS}, ords::MIndexType, param::Nothing, params::Nothing) + return getm(t.tpsa, convert(Cint, length(ords)), collect(Cuchar, ords)) end -function getindex(t::Union{TPS,ComplexTPS}, vars::Pair{<:Integer, <:Integer}...; params::Vector{<:Pair{<:Integer,<:Integer}}=Pair{Int,Int}[]) - # use sparse monomial getter +# By sparse monomial +function lowget(t::Union{TPS,ComplexTPS}, vars::SMIndexType, param::Nothing, params::Union{SMIndexType,Nothing}) sm, n = pairs_to_sm(t, vars, params=params) return getsm(t.tpsa, n, sm) end -function getindex(t::Union{TPS,ComplexTPS}, ords::Union{Integer,Colon}...) - #= - if !(ords[1:end-1] isa Tuple{Vararg{Integer}}) - error("Invalid monomial index: colon must appear at end.") - end=# - return slice(t, setup_mono(t,ords,nothing,nothing), false) +# Sparse monomial with nothing for vars +function lowget(t::Union{TPS,ComplexTPS}, vars::Nothing, param::Nothing, params::SMIndexType) + sm, n = pairs_to_sm(t, Pair{Int,Int}[], params=params) + return getsm(t.tpsa, n, sm) end -function getindex(t::Union{TPS,ComplexTPS}, vars::Union{Pair{<:Integer, <:Integer}, Colon}...; params::Vector{<:Pair{<:Integer,<:Integer}}=Pair{Int,Int}[]) - return slice(t, setup_mono(t, vars, nothing, params), false) +lowget(t, idx, param, params) = error("Invalid monomial index specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") + + +# --- Slicing (getter) --- + +# Vectors (which will be Vector{Any}) must be converted to tuples so SM or M indexing can be resolved: +const SMColonIndexType = Tuple{Vararg{Union{Pair{<:Integer,<:Integer},Colon}}} +const MColonIndexType =Tuple{Vararg{Union{Integer,Colon}}} +const TPSColonIndexType = Union{MColonIndexType, + SMColonIndexType, + Vector{<:Any}} + +function getindex(t::Union{TPS,ComplexTPS}, v::TPSColonIndexType; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) + if (v isa Vector) + par_mono = setup_mono(t, tuple(v...), param, params) + else + par_mono = setup_mono(t, v, param, params) + end + return slice(t, par_mono, false) end -getindex(t::Union{TPS,ComplexTPS}) = t +# For flat indexing: +function getindex(t::Union{TPS,ComplexTPS}, v::Integer, c::Colon) + par_mono = setup_mono(t, v, nothing, nothing) + return slice(t, par_mono,false) +end -#= -function getindex(::TPS) - return TPS[] +function getindex(t::Union{TPS,ComplexTPS}, c::Colon; param::Union{Integer,Nothing}=nothing) + if isnothing(param) + return t + else + par_mono = setup_mono(t, nothing, param, nothing) + return slice(t, par_mono,false) + end end -=# + # --- par --- """ - par(t::Union{TPS,ComplexTPS}, v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer, <:Any}}, Tuple{Vararg{Union{<:Integer,Pair{<:Integer,<:Integer},<:Colon}}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing) + par(t::Union{TPS,ComplexTPS}, v::Union{TPSColonIndexType, Vector{Pair{<:Integer,<:Integer}}, Vector{<:Integer}, Integer, Colon, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) Extracts a polynomial from the TPS containing the specified monomial, and removes the monomial. ### Input -- `v` -- An integer (for variable index), an array of orders for each variable (for indexing-by-order), or an array of pairs (sparse monomial) +- `v` -- An integer (for variable index), an array/tuple of orders for each variable (for indexing-by-order), or an array/tuple of pairs (sparse monomial) - `param` -- (Keyword argument, optional) An integer for the parameter index - `params` -- (Keyword argument, optional) An array of pairs for sparse-monomial indexing @@ -132,60 +205,59 @@ TPS: 3.0000000000000000e+00 7 2 1 1 2 1 | 0 0 ``` """ -function par(t::Union{TPS,ComplexTPS}, v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer, <:Any}}, Tuple{Vararg{Union{<:Integer,Pair{<:Integer,<:Integer},<:Colon}}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing) - if (v isa Vector) && !(last(v) isa Colon) - par_mono = setup_mono(t, tuple(v...,:), param, params) +function par(t::Union{TPS,ComplexTPS}, v::Union{TPSColonIndexType, Vector{Pair{<:Integer,<:Integer}}, Vector{<:Integer}, Integer, Colon, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) + if (v isa Vector) + tmpv = tuple(v...) + if tmpv isa MColonIndexType # because par-ing, must add colon + par_mono = setup_mono(t, tuple(tmpv...,:), param, params) + else + par_mono = setup_mono(t, tmpv, param, params) + end else par_mono = setup_mono(t, v, param, params) end return slice(t, par_mono) end -# Variable/parameter: +# Flat index: function setup_mono(t1::Union{TPS,ComplexTPS}, v::Integer, param::Nothing, params::Nothing)::Vector{Cuchar} par_mono = ones(Cuchar, v+1).*0xff par_mono[v] = 0x1 return par_mono end -function setup_mono(t1::Union{TPS,ComplexTPS}, v::Nothing, param::Integer, params::Nothing)::Vector{Cuchar} - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)) - nv = desc.nv # TOTAL NUMBER OF VARS!!!! +function setup_mono(t1::Union{TPS,ComplexTPS}, v::Union{Nothing,Colon}, param::Integer, params::Nothing)::Vector{Cuchar} + nv = numvars(t1) # TOTAL NUMBER OF VARS!!!! par_mono = ones(Cuchar, param+nv+1).*0xff par_mono[nv+param] = 0x1 return par_mono end -#= -# Default to scalar part as TPS if nothing passed: -function setup_mono(t1::Union{TPS,ComplexTPS}, v::Nothing, param::Nothing, params::Nothing)::Vector{Cuchar} - return [0x0] -end -=# + # Monomial by order: # This one should ALWAYS be called by par or splicing colon IS in the tuple or vector somewhere -function setup_mono(t1::Union{TPS,ComplexTPS}, v::Union{Tuple{Vararg{Union{<:Integer,<:Colon}}},Vector{<:Any}}, param::Nothing, params::Nothing)::Vector{Cuchar} - return [replace(x-> x isa Colon ? 0xff::Cuchar : convert(Cuchar, x)::Cuchar, v)...] +function setup_mono(t1::Union{TPS,ComplexTPS}, v::MColonIndexType, param::Nothing, params::Nothing)::Vector{Cuchar} + return collect(replace(x-> x isa Colon ? 0xff::Cuchar : convert(Cuchar, x)::Cuchar, v)) end # By definition, sparse monomial makes everything else zero. SO if we reach this, it is automatically # assumed that everything else is colon except those explictly made ix_var=>0 # Monomial by sparse monomial: -function setup_mono(t1::Union{TPS,ComplexTPS}, v::Union{Vector{<:Pair{<:Integer,<:Integer}}, Tuple{Vararg{Union{Pair{<:Integer,<:Integer},<:Colon}}}}, param::Nothing, params::Vector{<:Pair{<:Integer,<:Integer}})::Vector{Cuchar} +function setup_mono(t1::Union{TPS,ComplexTPS}, v::SMColonIndexType, param::Nothing, params::SMIndexType)::Vector{Cuchar} # Need to create array of orders with length nv + np ords, ___ = pairs_to_m(t1,filter(x->!(x isa Colon), v),params=params,zero_mono=false) - return [ords..., 0xff] + return vcat(ords, 0xff) end -function setup_mono(t1::Union{TPS,ComplexTPS}, v::Union{Vector{<:Pair{<:Integer,<:Integer}}, Tuple{Vararg{Union{Pair{<:Integer,<:Integer},<:Colon}}}}, param::Nothing, params::Nothing)::Vector{Cuchar} +function setup_mono(t1::Union{TPS,ComplexTPS}, v::SMColonIndexType, param::Nothing, params::Nothing)::Vector{Cuchar} # Need to create array of orders with length nv + np ords, ___ = pairs_to_m(t1,filter(x->!(x isa Colon), v),zero_mono=false) - return [ords..., 0xff] + return vcat(ords, 0xff) end -function setup_mono(t1::Union{TPS,ComplexTPS}, v::Nothing, param::Nothing, params::Vector{<:Pair{<:Integer,<:Integer}})::Vector{Cuchar} +function setup_mono(t1::Union{TPS,ComplexTPS}, v::Nothing, param::Nothing, params::SMIndexType)::Vector{Cuchar} # Need to create array of orders with length nv + np ords, ___ = pairs_to_m(t1,Pair{Int,Int}[],params=params,zero_mono=false) - return [ords..., 0xff] + return vcat(ords, 0xff) end @@ -194,10 +266,12 @@ function setup_mono(t1::Union{TPS,ComplexTPS}, v, param, params) error("Invalid monomial specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") end +idxm(t::Ptr{RTPSA}, n::Cint, m::Vector{Cuchar}) = (@inline; mad_tpsa_idxm(t, n, m)) +idxm(t::Ptr{CTPSA}, n::Cint, m::Vector{Cuchar}) = (@inline; mad_ctpsa_idxm(t, n, m)) + function slice(t1::Union{TPS,ComplexTPS}, par_mono::Vector{Cuchar}, par_it=true) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)) - nv = desc.nv # TOTAL NUMBER OF VARS!!!! - np = desc.np + nv = numvars(t1) + np = numparams(t1) t = zero(t1) v = Cint(length(par_mono)) coef = Ref{numtype(t)}() @@ -214,10 +288,9 @@ function slice(t1::Union{TPS,ComplexTPS}, par_mono::Vector{Cuchar}, par_it=true) tmp = zeros(Cuchar, np+nv) tmp[invalid_idxs] .= mono[invalid_idxs] tmp[v+1:end] .= mono[v+1:end] - t[tmp...] = coef[] + t[tmp] = coef[] else - t[mono...] = coef[] - + t[idx] = coef[] end end end @@ -247,10 +320,9 @@ in the TPS. - `result` -- Preallocated `Vector` to fill with the gradient of the TPS """ function gradient!(result::Vector{<:Union{Float64,ComplexF64}}, t::Union{TPS,ComplexTPS}; include_params=false) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)) - n = desc.nv + n = numvars(t) if include_params - n += desc.np + n += numparams(t) end if length(result) != n error("Incorrect size for result") @@ -274,10 +346,9 @@ first-order monomial coefficients already in the TPS. - `grad` -- Gradient of the TPS """ function gradient(t::Union{TPS,ComplexTPS}; include_params=false) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)) - n = desc.nv + n = numvars(t) if include_params - n += desc.np + n += numparams(t) end grad = Vector{numtype(t)}(undef, n) getv!(t.tpsa, Cint(1), n, grad) @@ -301,10 +372,9 @@ in the TPSs. - `result` -- Preallocated matrix to fill with the Jacobian of `m` """ function jacobian!(result::Matrix{<:Union{Float64,ComplexF64}}, m::Vector{<:Union{TPS,ComplexTPS}}; include_params=false) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(first(m).tpsa).d)) - n = desc.nv + n = numvars(first(m)) if include_params - n += desc.np + n += numparams(first(m)) end if size(result)[2] != n error("Incorrect size for result") @@ -335,15 +405,14 @@ the first-order monomial coefficients already in the TPSs. - `J` -- Jacobian of `m` """ function jacobian(m::Vector{<:Union{TPS,ComplexTPS}}; include_params=false) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(first(m).tpsa).d)) - n = desc.nv + n = numvars(first(m)) if include_params - n += desc.np + n += numparams(first(m)) end J = Matrix{numtype(first(m))}(undef, length(m), n) grad = Vector{numtype(first(m))}(undef, n) for i=1:length(m) - mad_tpsa_getv!(m[i].tpsa, Cint(1), n, grad) + getv!(m[i].tpsa, Cint(1), n, grad) J[i,:] = grad end return J @@ -367,10 +436,9 @@ first-order monomial coefficients already in the TPSs and filling `result`. - `result` -- Preallocated matrix to fill with the transpose of the Jacobian of `m` """ function jacobiant!(result::Matrix{<:Union{Float64,ComplexF64}}, m::Vector{<:Union{TPS,ComplexTPS}}; include_params=false) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(first(m).tpsa).d)) - n = desc.nv + n = numvars(first(m)) if include_params - n += desc.np + n += numparams(first(m)) end if size(result)[2] != n error("Incorrect size for result") @@ -398,10 +466,9 @@ first-order monomial coefficients already in the TPSs. - `Jt` -- Transpose of the Jacobian of `m` """ function jacobiant(m::Vector{<:Union{TPS,ComplexTPS}}; include_params=false) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(first(m).tpsa).d)) - n = desc.nv + n = numvars(first(m)) if include_params - n += desc.np + n += numparams(first(m)) end result = Matrix{numtype(first(m))}(undef, length(m), n) jacobiant!(result, m, include_params=include_params) diff --git a/src/global.jl b/src/global.jl new file mode 100644 index 00000000..deae699f --- /dev/null +++ b/src/global.jl @@ -0,0 +1,47 @@ +const MAD_TPSA::String = :("libgtpsa") +const MAD_TPSA_DEFAULT::Cuchar = 255 +const MAD_TPSA_SAME::Cuchar = 254 +const MAD_DESC_CURR::Ptr{Desc} = C_NULL +const DESC_MAX_TMP::Int = 8 + +# Global non-constants (types MUST be specified) +desc_current::Descriptor = Descriptor(MAD_DESC_CURR) # Current Descriptor +show_eps::Float64 = 0.0 # Print epsilon +show_sparse::Bool = false # Use sparse monomial print +show_header::Bool = false # Print a header above each TPS + +""" + setGTPSA!(a::AbstractString, val) + +Function to set global variables in GTPSA. Options for `a` are: + +- `desc_current::Descriptor` -- defines the `Descriptor` to use when that information is not explicitly (or implicitly in a TPS copy constructor) available, e.g. when calling `TPS(a)` where `a` is not a TPS. This is set each time a new `Descriptor` is defined +- `show_eps::Float64` -- defines the value below which the absolute value of a monomial coefficient is NOT printed +- `show_sparse::Bool` -- specifies whether the sparse monomial format is used for printing. This is useful for GTPSAs containing a large number of variables and parameters +- `show_header::Bool` -- specifies whether or not to print the GTPSA `Descriptor` information above each TPS output +""" +function setGTPSA!(a::AbstractString, val) + a == "desc_current" && (return (GTPSA.desc_current = val)) + a == "show_eps" && (return (GTPSA.show_eps = val)) + a == "show_sparse" && (return (GTPSA.show_sparse = val)) + a == "show_header" && (return (GTPSA.show_header = val)) + error("Global variable \"$(a)\" does not exist!") +end + +""" + getGTPSA(a::AbstractString) + +Function to get global variables in GTPSA. Options for `a` are: + +- `desc_current::Descriptor` -- defines the `Descriptor` to use when that information is not explicitly (or implicitly in a TPS copy constructor) available, e.g. when calling `TPS(a)` where `a` is not a TPS. This is set each time a new `Descriptor` is defined +- `show_eps::Float64` -- defines the value below which the absolute value of a monomial coefficient is NOT printed +- `show_sparse::Bool` -- specifies whether the sparse monomial format is used for printing. This is useful for GTPSAs containing a large number of variables and parameters +- `show_header::Bool` -- specifies whether or not to print the GTPSA `Descriptor` information above each TPS output +""" +function getGTPSA(a::AbstractString) + a == "desc_current" && (return GTPSA.desc_current) + a == "show_eps" && (return GTPSA.show_eps) + a == "show_sparse" && (return GTPSA.show_sparse) + a == "show_header" && (return GTPSA.show_header) + error("Global variable \"$(a)\" does not exist!") +end \ No newline at end of file diff --git a/src/low.jl b/src/low.jl new file mode 100644 index 00000000..b9385f06 --- /dev/null +++ b/src/low.jl @@ -0,0 +1,6 @@ +# Low-level functions/structs and constants +const NAMSZ::Int = 16 +include("low_level/mono.jl") +include("low_level/desc.jl") +include("low_level/rtpsa.jl") +include("low_level/ctpsa.jl") \ No newline at end of file diff --git a/src/methods.jl b/src/methods.jl index 74a0642e..5b80be48 100644 --- a/src/methods.jl +++ b/src/methods.jl @@ -1,53 +1,61 @@ -# --- Evaluate --- -# TPS: +# --- clear --- +clear!(t::Ptr{RTPSA}) = mad_tpsa_clear!(t) +clear!(t::Ptr{CTPSA}) = mad_ctpsa_clear!(t) + """ - evaluate(m::Vector{TPS}, x::Vector{<:Real})::Vector{Float64} + clear!(t::Union{TPS,ComplexTPS}) -Evaluates `m` at the point `x`. +Clears the TPS (sets all monomial coefficients to 0). """ -function evaluate(m::Vector{TPS}, x::Vector{<:Real})::Vector{Float64} - na = Cint(length(m)) - ma = map(t->t.tpsa, m) - nb = Cint(length(x)) - tb = convert(Vector{Float64}, x) - tc = Vector{Float64}(undef, nb) - mad_tpsa_eval!(na, ma, nb, tb, tc) - return tc +function clear!(t::Union{TPS,ComplexTPS}) + clear!(t.tpsa) end +# --- complex! --- + """ - evaluate(t1::TPS, x::Vector{<:Real})::Float64 + complex!(ct::ComplexTPS, t::TPS) -Evaluates `t1` at the point `x`. +Sets the pre-allocated `ComplexTPS` `ct` equal to `t`. """ -function evaluate(t1::TPS, x::Vector{<:Real})::Float64 - return evaluate([t1], x)[1] +function complex!(ct::ComplexTPS, t::TPS) + mad_ctpsa_cplx!(t.tpsa, Base.unsafe_convert(Ptr{RTPSA}, C_NULL), ct.tpsa) end +# --- Evaluate --- +eval!(na::Cint, ma::Vector{Ptr{RTPSA}}, nb::Cint, tb::Vector{Float64}, tc::Vector{Float64}) = mad_tpsa_eval!(na, ma, nb, tb, tc) +eval!(na::Cint, ma::Vector{Ptr{CTPSA}}, nb::Cint, tb::Vector{ComplexF64}, tc::Vector{ComplexF64}) = mad_ctpsa_eval!(na, ma, nb, tb, tc) -# ComplexTPS: """ - evaluate(m::Vector{ComplexTPS}, x::Vector{<:Number})::Vector{ComplexF64} + evaluate!(tc::Vector{<:Number}, m::Vector{T}, tb::Vector{<:Number}; work_low::Vector{<:Union{Ptr{RTPSA},Ptr{CTPSA}}}=Vector{lowtype(T)}(undef, length(m))) where {T<:Union{TPS,ComplexTPS}} -Evaluates `m` at the point `x`. +Evaluates the vector function `m` at the point `tb`, and fills `tc` with the result. +An optional container `work_low` can be provided for containing the low-level TPS +structs for zero allocations. """ -function evaluate(m::Vector{ComplexTPS}, x::Vector{<:Number})::Vector{ComplexF64} +function evaluate!(tc::Vector{<:Number}, m::Vector{T}, tb::Vector{<:Number}; work_low::Vector{<:Union{Ptr{RTPSA},Ptr{CTPSA}}}=Vector{lowtype(T)}(undef, length(m))) where {T<:Union{TPS,ComplexTPS}} na = Cint(length(m)) - ma = map(t->t.tpsa, m) - nb = Cint(length(x)) - tb = convert(Vector{ComplexF64}, x) - tc = Vector{ComplexF64}(undef, nb) - mad_ctpsa_eval!(na, ma, nb, tb, tc) - return tc + nb = Cint(length(tb)) + @assert na == nb "Vector lengths for TPSs and evaluation point disagree" + @assert length(tc) == nb "Output vector length disagrees with input vector length" + @assert length(work_low) == na "work_low vector length != input vector length" + @assert eltype(tc) == numtype(T) "Output vector eltype should be $(numtype(T)), received $(typeof(tc))" + + map!(t->t.tpsa, work_low, m) + eval!(na, work_low, nb, tb, tc) + return end """ - evaluate(ct1::ComplexTPS, x::Vector{<:Number})::ComplexF64 + evaluate(m::Vector{T}, tb::Vector{<:Number}) where {T<:Union{TPS,ComplexTPS}} -Evaluates `ct1` at the point `x`. +Evaluates the vector function `m` at the point `tb`. """ -function evaluate(ct1::ComplexTPS, x::Vector{<:Number})::ComplexF64 - return evaluate([ct1], x)[1] +function evaluate(m::Vector{T}, tb::Vector{<:Number}) where {T<:Union{TPS,ComplexTPS}} + na = Cint(length(m)) + tc = Vector{numtype(T)}(undef, na) + evaluate!(tc, m, tb) + return tc end # --- Integral --- @@ -55,6 +63,21 @@ end integ!(tpsa1::Ptr{RTPSA}, tpsa::Ptr{RTPSA}, var::Cint) = (@inline; mad_tpsa_integ!(tpsa1, tpsa, var)) integ!(ctpsa1::Ptr{CTPSA}, ctpsa::Ptr{CTPSA}, var::Cint) = (@inline; mad_ctpsa_integ!(ctpsa1, ctpsa, var)) +""" + integ!(t::T, t1::T, var::Integer=1) where {T<:Union{TPS,ComplexTPS}} + ∫!(t::T, t1::T, var::Integer=1) where {T<:Union{TPS,ComplexTPS}} + +Integrates `t1` wrt the variable `var` and fills `t` with the result. +Integration wrt parameters is not allowed, and integration wrt higher order +monomials is not currently supported. +""" +function integ!(t::T, t1::T, var::Integer=1) where {T<:Union{TPS,ComplexTPS}} + integ(t1.tpsa, t.tpsa, Cint(var)) + return +end + +∫! = integ! + """ integ(t1::Union{TPS, ComplexTPS}, var::Integer=1) ∫(t1::Union{TPS, ComplexTPS}, var::Integer=1) @@ -65,7 +88,7 @@ monomials is not currently supported. """ function integ(t1::Union{TPS, ComplexTPS}, var::Integer=1) t = zero(t1) - integ!(t1.tpsa, t.tpsa, Cint(var)) + integ!(t, t1, var) return t end @@ -79,16 +102,35 @@ derivm!(tpsa1::Ptr{RTPSA}, tpsa::Ptr{RTPSA}, n::Cint, ords::Vector{Cuchar}) = (@ derivm!(ctpsa1::Ptr{CTPSA}, ctpsa::Ptr{CTPSA}, n::Cint, ords::Vector{Cuchar}) = (@inline; mad_ctpsa_derivm!(ctpsa1, ctpsa, n, ords)) """ - deriv(t1::Union{TPS,ComplexTPS}, v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing) - ∂(t1::Union{TPS,ComplexTPS}, v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing) + deriv!(t::T, t1::T, v::Union{TPSIndexType, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) where {T<:Union{TPS,ComplexTPS}} + ∂!(t::T, t1::T, v::Union{TPSIndexType, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) where {T<:Union{TPS,ComplexTPS}} + +Differentiates `t1` wrt the variable/parameter specified by the variable/parameter index, or +alternatively any monomial specified by indexing-by-order OR indexing-by-sparse monomial, and +sets `t` equal to the result in-place. See the `deriv` documentation for examples. + +### Input +- `v` -- An integer (for variable index), vector/tuple of orders for each variable (for indexing-by-order), or vector/tuple of pairs (sparse monomial) +- `param` -- (Keyword argument, optional) An integer for the parameter index +- `params` -- (Keyword argument, optional) Vector/tuple of pairs for sparse-monomial indexing +""" +function deriv!(t::T, t1::T, v::Union{TPSIndexType, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) where {T<:Union{TPS,ComplexTPS}} + low_deriv!(t, t1, v, param, params) +end + +∂! = deriv! + +""" + deriv(t1::Union{TPS,ComplexTPS}, v::Union{TPSIndexType, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) + ∂(t1::Union{TPS,ComplexTPS}, v::Union{TPSIndexType, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) Differentiates `t1` wrt the variable/parameter specified by the variable/parameter index, or alternatively any monomial specified by indexing-by-order OR indexing-by-sparse monomial. ### Input -- `v` -- An integer (for variable index), an array of orders for each variable (for indexing-by-order), or an array of pairs (sparse monomial) +- `v` -- An integer (for variable index), vector/tuple of orders for each variable (for indexing-by-order), or vector/tuple of pairs (sparse monomial) - `param` -- (Keyword argument, optional) An integer for the parameter index -- `params` -- (Keyword argument, optional) An array of pairs for sparse-monomial indexing +- `params` -- (Keyword argument, optional) Vector/tuple of pairs for sparse-monomial indexing # Examples: Variable/Parameter Index: ```julia-repl @@ -148,75 +190,72 @@ TPS: 1.0000000000000000e+00 0 0 0 ``` """ -function deriv(t1::Union{TPS,ComplexTPS}, v::Union{Integer, Vector{<:Union{<:Pair{<:Integer,<:Integer},<:Integer}}, Nothing}=nothing; param::Union{<:Integer,Nothing}=nothing, params::Union{Vector{<:Pair{<:Integer,<:Integer}}, Nothing}=nothing) - return low_deriv(t1, v, param, params) +function deriv(t1::Union{TPS,ComplexTPS}, v::Union{TPSIndexType, Nothing}=nothing; param::Union{Integer,Nothing}=nothing, params::Union{SMIndexType, Nothing}=nothing) + t = zero(t1) + low_deriv!(t, t1, v, param, params) + return t end # Variable/parameter: -function low_deriv(t1::Union{TPS,ComplexTPS}, v::Integer, param::Nothing, params::Nothing) - t = zero(t1) +function low_deriv!(t::T, t1::T, v::Integer, param::Nothing, params::Nothing) where {T<:Union{TPS,ComplexTPS}} deriv!(t1.tpsa, t.tpsa, convert(Cint, v)) - return t end -function low_deriv(t1::Union{TPS,ComplexTPS}, v::Nothing, param::Integer, params::Nothing) - t = zero(t1) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)) - nv = desc.nv # TOTAL NUMBER OF VARS!!!! +function low_deriv!(t::T, t1::T, v::Nothing, param::Integer, params::Nothing) where {T<:Union{TPS,ComplexTPS}} + nv = numvars(t1) deriv!(t1.tpsa, t.tpsa, Cint(param)+nv) - return t end # Default to first variable if nothing passed: -function low_deriv(t1::Union{TPS,ComplexTPS}, v::Nothing, param::Nothing, params::Nothing) - return low_deriv(t1, 1, nothing, nothing) +function low_deriv!(t::T, t1::T, v::Nothing, param::Nothing, params::Nothing) where {T<:Union{TPS,ComplexTPS}} + low_deriv!(t1, 1, nothing, nothing) end # Monomial by order: -function low_deriv(t1::Union{TPS,ComplexTPS}, v::Vector{<:Integer}, param::Nothing, params::Nothing) - t = zero(t1) +function low_deriv!(t::T, t1::T, v::MIndexType, param::Nothing, params::Nothing) where {T<:Union{TPS,ComplexTPS}} derivm!(t1.tpsa, t.tpsa, Cint(length(v)), convert(Vector{Cuchar}, v)) - return t end # Monomial by sparse monomial: -function low_deriv(t1::Union{TPS,ComplexTPS}, v::Vector{<:Pair{<:Integer,<:Integer}}, param::Nothing, params::Vector{<:Pair{<:Integer,<:Integer}}) - t = zero(t1) +function low_deriv!(t::T, t1::T, v::SMIndexType, param::Nothing, params::SMIndexType) where {T<:Union{TPS,ComplexTPS}} # Need to create array of orders with length nv + np ords, n = pairs_to_m(t1,v,params=params) derivm!(t1.tpsa, t.tpsa, n, ords) - return t end -function low_deriv(t1::Union{TPS,ComplexTPS}, v::Vector{<:Pair{<:Integer,<:Integer}}, param::Nothing, params::Nothing) - t = zero(t1) +function low_deriv!(t::T, t1::T, v::SMIndexType, param::Nothing, params::Nothing) where {T<:Union{TPS,ComplexTPS}} # Need to create array of orders with length nv + np ords, n = pairs_to_m(t1,v) derivm!(t1.tpsa, t.tpsa, n, ords) - return t end -function low_deriv(t1::Union{TPS,ComplexTPS}, v::Nothing, param::Nothing, params::Vector{<:Pair{<:Integer,<:Integer}}) - t = zero(t1) +function low_deriv!(t::T, t1::T, v::Nothing, param::Nothing, params::SMIndexType) where {T<:Union{TPS,ComplexTPS}} # Need to create array of orders with length nv + np ords, n = pairs_to_m(t1,Pair{Int,Int}[],params=params) derivm!(t1.tpsa, t.tpsa, n, ords) - return t end # Throw error if no above use cases satisfied: -function low_deriv(t1::Union{TPS,ComplexTPS}, v, param, params) +function low_deriv(t::T, t1::T, v, param, params) where {T<:Union{TPS,ComplexTPS}} error("Invalid monomial specified. Please use ONE of variable/parameter index, index by order, or index by sparse monomial.") end ∂ = deriv -# --- getord and cutord --- +# --- getord --- # Low-level equivalent calls for TPS and ComplexTPS: getord!(tpsa1::Ptr{RTPSA}, tpsa::Ptr{RTPSA}, order::Cuchar) = (@inline; mad_tpsa_getord!(tpsa1, tpsa, order)) getord!(ctpsa1::Ptr{CTPSA}, ctpsa::Ptr{CTPSA}, order::Cuchar) = (@inline; mad_ctpsa_getord!(ctpsa1, ctpsa, order)) -cutord!(tpsa1::Ptr{RTPSA}, tpsa::Ptr{RTPSA}, order::Cint) = (@inline; mad_tpsa_cutord!(tpsa1, tpsa, order)) -cutord!(ctpsa1::Ptr{CTPSA}, ctpsa::Ptr{CTPSA}, order::Cint) = (@inline; mad_ctpsa_cutord!(ctpsa1, ctpsa, order)) + +""" + getord!(t::T, t1::T, order::Integer) where {T<:Union{TPS,ComplexTPS}} + +Extracts one homogenous polynomial from `t1` of the given order and +fills `t` with the result in-place. +""" +function getord!(t::T, t1::T, order::Integer) where {T<:Union{TPS,ComplexTPS}} + getord!(t1.tpsa, t.tpsa, Cuchar(order)) +end """ getord(t1::Union{TPS, ComplexTPS}, order::Integer) @@ -225,10 +264,25 @@ Extracts one homogenous polynomial from `t1` of the given order. """ function getord(t1::Union{TPS, ComplexTPS}, order::Integer) t = zero(t1) - getord!(t1.tpsa, t.tpsa, convert(Cuchar, order)) + getord!(t, t1, order) return t end +# --- cutord --- +cutord!(tpsa1::Ptr{RTPSA}, tpsa::Ptr{RTPSA}, order::Cint) = (@inline; mad_tpsa_cutord!(tpsa1, tpsa, order)) +cutord!(ctpsa1::Ptr{CTPSA}, ctpsa::Ptr{CTPSA}, order::Cint) = (@inline; mad_ctpsa_cutord!(ctpsa1, ctpsa, order)) + +""" + cutord!(t::T, t1::T, order::Integer) where {T<:Union{TPS,ComplexTPS}} + +Cuts out the monomials in `t1` at the given order and above. Or, if `order` +is negative, will cut monomials with orders at and below `abs(order)`. `t` +is filled in-place with the result. See the documentation for `cutord` for examples. +""" +function cutord!(t::T, t1::T, order::Integer) where {T<:Union{TPS,ComplexTPS}} + cutord!(t1.tpsa, t.tpsa, convert(Cint, order)) +end + """ cutord(t1::Union{TPS, ComplexTPS}, order::Integer) @@ -257,13 +311,12 @@ TPS: """ function cutord(t1::Union{TPS, ComplexTPS}, order::Integer) t = zero(t1) - cutord!(t1.tpsa, t.tpsa, convert(Cint, order)) + cutord!(t, t1, order) return t end # --- scalar --- - """ scalar(t::Union{TPS,ComplexTPS}) @@ -274,458 +327,185 @@ function scalar(t::Union{TPS,ComplexTPS}) return t[0] end +# --- composition --- +compose!(na::Cint, ma::Vector{Ptr{RTPSA}}, nb::Cint, mb::Vector{Ptr{RTPSA}}, mc::Vector{Ptr{RTPSA}}) = (@inline; mad_tpsa_compose!(na, ma, nb, mb, mc)) +compose!(na::Cint, ma::Vector{Ptr{CTPSA}}, nb::Cint, mb::Vector{Ptr{CTPSA}}, mc::Vector{Ptr{CTPSA}}) = (@inline; mad_ctpsa_compose!(na, ma, nb, mb, mc)) -# --- Poisson bracket --- -# Low-level calls -poisbra!(tpsa1::Ptr{RTPSA}, tpsa2::Ptr{RTPSA}, tpsa::Ptr{RTPSA}, nv::Cint) = (@inline; mad_tpsa_poisbra!(tpsa1, tpsa2, tpsa, nv)) -poisbra!(tpsa1::Ptr{RTPSA}, ctpsa1::Ptr{CTPSA}, ctpsa::Ptr{CTPSA}, nv::Cint) = (@inline; mad_ctpsa_poisbrat!(ctpsa1,tpsa1,ctpsa, nv)) -poisbra!(ctpsa1::Ptr{CTPSA}, tpsa1::Ptr{RTPSA}, ctpsa::Ptr{CTPSA}, nv::Cint) = (@inline; mad_ctpsa_tpoisbra!(tpsa1, ctpsa1, ctpsa, nv)) -poisbra!(ctpsa1::Ptr{CTPSA}, ctpsa2::Ptr{CTPSA}, ctpsa::Ptr{CTPSA}, nv::Cint) = (@inline; mad_ctpsa_poisbra!(ctpsa1,ctpsa2, ctpsa, nv)) - -""" - pb(f::Union{TPS, ComplexTPS}, g::Union{TPS, ComplexTPS}) - -Assuming the variables in the TPSA are canonically-conjugate, and ordered so that the canonically- -conjugate variables are consecutive (q₁, p₁, q₂, p₂, ...), computes the Poisson bracket -of the scalar functions `f` and `g`. The Poisson bracket of two functions `{f, g}` is defined as -`Σᵢ (∂f/∂qᵢ)(∂g/∂pᵢ) - (∂g/∂qᵢ)(∂f/∂pᵢ)`. - -# Examples -```julia-repl -julia> d = Descriptor(4,10); - -julia> x = vars(d); - -julia> f = (x[1]^2 + x[2]^2)/2 + (x[3]^2 + x[4]^2)/2; - -julia> pb(f,x[1]) -TPS: - Coefficient Order Exponent - -1.0000000000000000e+00 1 0 1 0 0 - - -julia> pb(f,x[2]) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 1 0 0 0 - - -julia> pb(f,x[3]) -TPS: - Coefficient Order Exponent - -1.0000000000000000e+00 1 0 0 0 1 - - -julia> pb(f,x[4]) -TPS: - Coefficient Order Exponent - 1.0000000000000000e+00 1 0 0 1 0 -``` -""" -function pb(f::Union{TPS, ComplexTPS}, g::Union{TPS, ComplexTPS}) - t = promote_type(typeof(f),typeof(g))(use=f) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(f.tpsa).d)) - poisbra!(f.tpsa,g.tpsa,t.tpsa, desc.nv) - return t -end - -# --- Lie bracket --- -liebra!(na::Cint, m1::Vector{Ptr{RTPSA}}, m2::Vector{Ptr{RTPSA}}, m3::Vector{Ptr{RTPSA}}) = (@inline; mad_tpsa_liebra!(na, m1, m2, m3)) -liebra!(na::Cint, m1::Vector{Ptr{CTPSA}}, m2::Vector{Ptr{CTPSA}}, m3::Vector{Ptr{CTPSA}}) = (@inline; mad_ctpsa_liebra!(na, m1, m2, m3)) - -""" - lb(A::Vector{<:Union{TPS,ComplexTPS}}, F::Vector{<:Union{TPS,ComplexTPS}}) - -Computes the Lie bracket of the vector functions `A` and `F`, defined over N variables as -`Σᵢᴺ Aᵢ (∂F/∂xᵢ) - Fᵢ (∂A/∂xᵢ)` - -# Example -```julia-repl -julia> d = Descriptor(2,10); x = vars(); - -julia> A = [-x[2], x[1]] -2-element Vector{TPS}: - Out Coefficient Order Exponent -------------------------------------------------- - 1: -1.0000000000000000e+00 1 0 1 -------------------------------------------------- - 2: 1.0000000000000000e+00 1 1 0 - - -julia> F = [-x[1]^2, 2*x[1]*x[2]] -2-element Vector{TPS}: - Out Coefficient Order Exponent -------------------------------------------------- - 1: -1.0000000000000000e+00 2 2 0 -------------------------------------------------- - 2: 2.0000000000000000e+00 2 1 1 - - -julia> lb(A,F) -2-element Vector{TPS}: - Out Coefficient Order Exponent -------------------------------------------------- - 1: 4.0000000000000000e+00 2 1 1 -------------------------------------------------- - 2: 3.0000000000000000e+00 2 2 0 - 2: -2.0000000000000000e+00 2 0 2 -``` -""" -function lb(A::Vector{<:Union{TPS,ComplexTPS}}, F::Vector{<:Union{TPS,ComplexTPS}}) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(A[1].tpsa).d)) - if length(A) != desc.nv || length(F) != desc.nv - error("Vector length != number of variables in the GTPSA") - end - A1, F1 = promote(A, F) - m1 = map(t->t.tpsa, A1) - m2 = map(t->t.tpsa, F1) - mc = zero.(A1) - m3 = map(t->t.tpsa, mc) - GC.@preserve A1 F1 liebra!(Cint(length(A)), m1, m2, m3) - return mc -end - -# --- getvectorfield --- -vec2fld!(na::Cint, tpsa::Ptr{RTPSA}, m::Vector{Ptr{RTPSA}}) = (@inline; mad_tpsa_vec2fld!(na, tpsa, m)) -vec2fld!(na::Cint, ctpsa::Ptr{CTPSA}, m::Vector{Ptr{CTPSA}}) = (@inline; mad_ctpsa_vec2fld!(na, ctpsa, m)) - -""" - getvectorfield(h::Union{TPS,ComplexTPS})::Vector{<:typeof(h)} - -Assuming the variables in the TPSA are canonically-conjugate, and ordered so that the canonically- -conjugate variables are consecutive (q₁, p₁, q₂, p₂, ...), calculates the vector field (Hamilton's -equations) from the passed Hamiltonian, defined as `[∂h/∂p₁, -∂h/∂q₁, ...]` - -# Example -```julia-repl -julia> d = Descriptor(2,10); x = vars(); - -julia> h = (x[1]^2 + x[2]^2)/2 -TPS: - Coefficient Order Exponent - 5.0000000000000000e-01 2 2 0 - 5.0000000000000000e-01 2 0 2 - - -julia> getvectorfield(h) -2-element Vector{TPS}: - Out Coefficient Order Exponent -------------------------------------------------- - 1: -1.0000000000000000e+00 1 0 1 -------------------------------------------------- - 2: 1.0000000000000000e+00 1 1 0 -``` -""" -function getvectorfield(h::Union{TPS,ComplexTPS})::Vector{<:typeof(h)} - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(h.tpsa).d)) - na = desc.nv - mc = Vector{typeof(h)}(undef, na) - for i in eachindex(mc) - mc[i] = zero(h) - end - m = map(t->t.tpsa, mc) - vec2fld!(na, h.tpsa, m) - return mc -end - -# --- gethamiltonian --- -fld2vec!(na::Cint, ma::Vector{Ptr{RTPSA}}, tpsa::Ptr{RTPSA}) = (@inline; mad_tpsa_fld2vec!(na, ma, tpsa)) -fld2vec!(na::Cint, ma::Vector{Ptr{CTPSA}}, ctpsa::Ptr{CTPSA}) = (@inline; mad_ctpsa_fld2vec!(na, ma, ctpsa)) """ - gethamiltonian(F::Vector{<:Union{TPS,ComplexTPS}}) + compose!(m::Vector{<:Union{TPS,ComplexTPS}}, m2::Vector{<:Union{TPS,ComplexTPS}}, m1::Vector{<:Union{TPS,ComplexTPS}}; work_low::Union{Nothing,Tuple{Vararg{Vector{<:Union{Ptr{RTPSA},Ptr{CTPSA}}}}}}=nothing, work_prom::Union{Nothing,Tuple{Vararg{Vector{<:ComplexTPS}}}}=nothing) -Assuming the variables in the TPSA are canonically-conjugate, and ordered so that the canonically- -conjugate variables are consecutive (q₁, p₁, q₂, p₂, ...), this function calculates the Hamiltonian -from a vector field `F` that can be obtained from a Hamiltonian (e.g. by `getvectorfield`). Explicitly, -`∫ F₁ dp₁ - ∫ F₂ dq₁ + ... + ∫ F₂ₙ₋₁ dpₙ - ∫ F₂ₙ dqₙ ` +Composes the vector functions `m2 ∘ m1` and stores the result in-place in `m`. Promotion is allowed, provided +the output vector function `m` has the correct promoted type. -# Example -```julia-repl -julia> d = Descriptor(2,10); x = vars(); +For all compositions, 3 temporary vectors must be generated that contain Ptr{RTPSA} or Ptr{CTPSA} +for each TPS in the map (depending on output type), to pass to the low-level C composition function in GTPSA. +They are correspondingly referred to as `outx_low`, `m2x_low`, and `m1x_low`. These three temporaries containers +can be optionally passed as a tuple in `work_low`, and must satisfy the following requirements: -julia> h = (x[1]^2 + x[2]^2)/2 -TPS: - Coefficient Order Exponent - 5.0000000000000000e-01 2 2 0 - 5.0000000000000000e-01 2 0 2 +work_low[1] = outx_low # Length >= length(m) = length(m2) +work_low[2] = m2x_low # Length >= length(m2) = length(m) +work_low[3] = m1x_low # Length >= length(m1) +If promotion is occuring, then one of the input vectors must be promoted to `ComplexTPS`. A vector of pre-allocated +`ComplexTPS`s can optionally provided as the first argument in the `work_prom` tuple, and has the requirement: -julia> F = getvectorfield(h) -2-element Vector{TPS}: - Out Coefficient Order Exponent -------------------------------------------------- - 1: -1.0000000000000000e+00 1 0 1 -------------------------------------------------- - 2: 1.0000000000000000e+00 1 1 0 +If `eltype(m.x) != eltype(m1.x)` (then `m1` must be promoted): +work_prom[1] = m1x_prom # Length >= length(m1), Vector{ComplexTPS} +else if `eltype(m.x) != eltype(m2.x)` (then `m2` must be promoted): +work_prom[1] = m2x_prom # Length >= length(m2) = length(m), Vector{ComplexTPS} -julia> gethamiltonian(F) -TPS: - Coefficient Order Exponent - 5.0000000000000000e-01 2 2 0 - 5.0000000000000000e-01 2 0 2 -``` +Note that the `ComplexTPS`s in the vectors must be allocated and have the same `Descriptor`. """ -function gethamiltonian(F::Vector{<:Union{TPS,ComplexTPS}}) - descF = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(F[1].tpsa).d)) - if length(F) != descF.nv - error("Vector length != number of variables in the GTPSA") - end - h = zero(F[1]) - m1 = map(t->t.tpsa, F) - fld2vec!(Cint(length(m)), m1, h.tpsa) - return h -end - +function compose!(m::Vector{<:Union{TPS,ComplexTPS}}, m2::Vector{<:Union{TPS,ComplexTPS}}, m1::Vector{<:Union{TPS,ComplexTPS}}; work_low::Union{Nothing,Tuple{Vararg{Vector{<:Union{Ptr{RTPSA},Ptr{CTPSA}}}}}}=nothing, work_prom::Union{Nothing,Tuple{Vararg{Vector{<:ComplexTPS}}}}=nothing) + desc = getdesc(first(m)) + n = length(m) + n2 = length(m2) + n1 = length(m1) -# --- exp(F . grad) m --- -exppb!(na::Cint, ma::Vector{Ptr{RTPSA}}, mb::Vector{Ptr{RTPSA}}, mc::Vector{Ptr{RTPSA}}) = (@inline; mad_tpsa_exppb!(na, ma, mb, mc)) -exppb!(na::Cint, ma::Vector{Ptr{CTPSA}}, mb::Vector{Ptr{CTPSA}}, mc::Vector{Ptr{CTPSA}}) = (@inline; mad_ctpsa_exppb!(na, ma, mb, mc)) + @assert n == n2 "Incorrect output length, received length $(length(m)) but need $(length(m2))" + @assert numnn(first(m2)) == n1 "Not enough input arguments" + @assert !(m === m1) "Cannot compose!(m, m2, m1) with m === m1" + @assert eltype(m) == promote_type(eltype(m2),eltype(m1)) "Cannot compose: output vector type $(eltype(m)) must be $(promote_type(eltype(m2),eltype(m1)))" + outT = eltype(m) -""" - exppb(F::Vector{<:Union{TPS,ComplexTPS}}, m::Vector{<:Union{TPS,ComplexTPS}}=vars(first(F))) - -Calculates `exp(F⋅∇)m = m + F⋅∇m + (F⋅∇)²m/2! + ...`. If `m` is not provided, it is assumed -to be the identity. - -# Example - -```julia-repl -julia> d = Descriptor(2,10); x = vars()[1]; p = vars()[2]; - -julia> time = 0.01; k = 2; m = 0.01; - -julia> h = p^2/(2m) + 1/2*k*x^2; - -julia> hf = getvectorfield(h); - -julia> map = exppb(-time*hf, [x, p]) -2-element Vector{TPS}: - Out Coefficient Order Exponent -------------------------------------------------- - 1: 9.9001665555952290e-01 1 1 0 - 1: 9.9666999841313930e-01 1 0 1 -------------------------------------------------- - 2: -1.9933399968262787e-02 1 1 0 - 2: 9.9001665555952378e-01 1 0 1 -``` -""" -function exppb(F::Vector{<:Union{TPS,ComplexTPS}}, m::Vector{<:Union{TPS,ComplexTPS}}=vars(first(F))) - descF = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(F[1].tpsa).d)) - if length(F) != descF.nv - error("Vector length != number of variables in the GTPSA") + if !isnothing(work_low) + outx_low = work_low[1] + m2x_low = work_low[2] + m1x_low = work_low[3] + @assert length(outx_low) >= n "Incorrect length for work_low[1] = outx_low. Received $(length(outx_low)), should be >=$n" + @assert length(m2x_low) >= n2 "Incorrect length for work_low[2] = m2x_low. Received $(length(m2x_low)), should be >=$n2" + @assert length(m1x_low) >= n1 "Incorrect length for work_low[3] = m1x_low. Received $(length(m1x_low)), should be >=$n1" + else + outx_low = Vector{lowtype(outT)}(undef, n) + m2x_low = Vector{lowtype(outT)}(undef, n) + m1x_low = Vector{lowtype(outT)}(undef, n1) end - ma1, mb1 = promote(F, m) - m1 = map(t->t.tpsa, ma1) - m2 = map(t->t.tpsa, mb1) - mc = zero.(ma1) - m3 = map(t->t.tpsa, mc) - GC.@preserve ma1 mb1 exppb!(Cint(length(F)), m1, m2, m3) - return mc -end -# --- logpb --- -logpb!(na::Cint, ma::Vector{Ptr{RTPSA}}, mb::Vector{Ptr{RTPSA}}, mc::Vector{Ptr{RTPSA}}) = (@inline; mad_tpsa_logpb!(na, ma, mb, mc)) -logpb!(na::Cint, ma::Vector{Ptr{CTPSA}}, mb::Vector{Ptr{CTPSA}}, mc::Vector{Ptr{CTPSA}}) = (@inline; mad_ctpsa_logpb!(na, ma, mb, mc)) - -""" - logpb(mf::Vector{<:Union{TPS,ComplexTPS}}, mi::Vector{<:Union{TPS,ComplexTPS}}=vars(first(F))) - -Given a final map `mf` and initial map `mi`, this function calculates the vector field `F` -such that `mf=exp(F⋅∇)mi`. If `mi` is not provided, it is assumed to be the identity. - -```julia-repl -julia> d = Descriptor(2,10); x = vars()[1]; p = vars()[2]; - -julia> time = 0.01; k = 2; m = 0.01; - -julia> h = p^2/(2m) + 1/2*k*x^2; - -julia> hf = getvectorfield(h); - -julia> map = exppb(-time*hf); - -julia> logpb(map) == -time*hf -true -``` -""" -function logpb(mf::Vector{<:Union{TPS,ComplexTPS}}, mi::Vector{<:Union{TPS,ComplexTPS}}=vars(first(mf))) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(mf[1].tpsa).d)) - if length(mf) != desc.nv || length(mi) != desc.nv - error("Vector length != number of variables in the GTPSA") + if !isnothing(work_prom) + if outT != eltype(m1) + m1x_prom = work_prom[1] + m2x_prom = nothing + @assert length(m1x_prom) >= n1 "Incorrect length for work_prom[1] = m1x_prom: Received $(length(m1x_prom)), should be >=$n1" + elseif outT != eltype(m2) + m1x_prom = nothing + m2x_prom = work_prom[1] + @assert length(m2x_prom) >= n "Incorrect length for work_prom[1] = m2x_prom: Received $(length(m2x_prom)), should be >=$n" + else + m1x_prom = nothing + m2x_prom = nothing + end + else + if outT != eltype(m1) + m1x_prom = Vector{ComplexTPS}(undef, n1) + for i=1:n1 # Allocate + @inbounds m1x_prom[i] = ComplexTPS(use=desc) + end + m2x_prom = nothing + elseif outT != eltype(m2) + m1x_prom = nothing + m2x_prom = Vector{ComplexTPS}(undef, n) + for i=1:n + @inbounds m2x_prom[i] = ComplexTPS(use=desc) + end + else + m1x_prom = nothing + m2x_prom = nothing + end end - ma1, mb1 = promote(mf, mi) - m1 = map(t->t.tpsa, ma1) - m2 = map(t->t.tpsa, mb1) - mc = zero.(ma1) - m3 = map(t->t.tpsa, mc) - GC.@preserve ma1 mb1 logpb!(Cint(length(mf)), m1, m2, m3) - return mc -end - -# --- F . grad --- -fgrad!(na::Cint, ma::Vector{Ptr{RTPSA}}, b::Ptr{RTPSA}, c::Ptr{RTPSA}) = (@inline; mad_tpsa_fgrad!(na, ma, b, c)) -fgrad!(na::Cint, ma::Vector{Ptr{CTPSA}}, b::Ptr{CTPSA}, c::Ptr{CTPSA}) = (@inline; mad_ctpsa_fgrad!(na, ma, b, c)) -""" - fgrad(F::Vector{<:Union{TPS,ComplexTPS}}, g::Union{TPS,ComplexTPS}) - -Calculates `F⋅∇g`. -""" -function fgrad(F::Vector{<:Union{TPS,ComplexTPS}}, g::Union{TPS,ComplexTPS}) - descF = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(F[1].tpsa).d)) - if length(F) != descF.nv - error("Vector length != number of variables in the GTPSA") + # Do the composition, promoting if necessary + if outT != eltype(m1) + # Promote to ComplexTPS: + for i=1:n1 + @inbounds complex!(m1x_prom[i], m1[i]) + end + map!(t->t.tpsa, m1x_low, m1x_prom) + else + map!(t->t.tpsa, m1x_low, m1) end - type = promote_type(typeof(F[1]), typeof(g)) - ma1 = convert(Vector{type}, F) - b1 = convert(type, g) - m1 = map(t->t.tpsa, ma1) - c = zero(b1) - GC.@preserve ma1 fgrad!(Cint(length(ma)), m1, b1.tpsa, c.tpsa) - return c -end - -# --- mnrm --- -mnrm(na::Cint, ma::Vector{Ptr{RTPSA}})::Float64 = mad_tpsa_mnrm(na, ma) -mnrm(na::Cint, ma::Vector{Ptr{CTPSA}})::ComplexF64 = mad_ctpsa_mnrm(na, ma) - -#= -""" - norm(ma::Vector{<:Union{TPS,ComplexTPS}}) - -Calculates the norm of the map `ma`, defined as `sum(norm.(ma))` or the -sum of the absolute value of all coefficients in each TPS. -""" -function norm(ma::Vector{<:Union{TPS,ComplexTPS}}) - return mnrm(Cint(length(ma)), map(x->x.tpsa, ma)) -end -=# -# --- map inversion --- -minv!(na::Cint, ma::Vector{Ptr{RTPSA}}, mc::Vector{Ptr{RTPSA}}) = (@inline; mad_tpsa_minv!(na, ma, mc)) -minv!(na::Cint, ma::Vector{Ptr{CTPSA}}, mc::Vector{Ptr{CTPSA}}) = (@inline; mad_ctpsa_minv!(na, ma, mc)) - -""" - inv(ma::Vector{<:Union{TPS,ComplexTPS}}) - -Inverts the map `ma` such that `ma ∘ inv(ma) = 1` in the variables. - -# Example - -```julia-repl - -julia> d = Descriptor(2,10); x = vars()[1]; p = vars()[2]; - -julia> time = 0.01; k = 2; m = 0.01; - -julia> h = p^2/(2m) + 1/2*k*x^2; - -julia> hf = getvectorfield(h); - -julia> map = exppb(-time*hf, [x, p]); -julia> map ∘ inv(map) -2-element Vector{TPS}: - Out Coefficient Order Exponent -------------------------------------------------- - 1: 1.0000000000000000e+00 1 1 0 -------------------------------------------------- - 2: 1.0000000000000002e+00 1 0 1 -``` -""" -function inv(ma::Vector{<:Union{TPS,ComplexTPS}}) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(ma[1].tpsa).d)) - if length(ma) != desc.nv - error("Map length != number of variables in the GTPSA") + if outT != eltype(m2) + # Promote to ComplexTPS: + for i=1:n + @inbounds complex!(m2x_prom[i], m2[i]) + end + map!(t->t.tpsa, m2x_low, m2x_prom) + else + map!(t->t.tpsa, m2x_low, m2) end - mc = zero.(ma) - ma1 = map(x->x.tpsa, ma) - mc1 = map(x->x.tpsa, mc) - minv!(Cint(length(ma)), ma1, mc1) - return mc -end -# --- partial inversion --- -pminv!(na::Cint, ma::Vector{Ptr{RTPSA}}, mc::Vector{Ptr{RTPSA}}, select::Vector{Cint}) = (@inline; mad_tpsa_pminv!(na, ma, mc, select)) -pminv!(na::Cint, ma::Vector{Ptr{CTPSA}}, mc::Vector{Ptr{CTPSA}}, select::Vector{Cint}) = (@inline; mad_ctpsa_pminv!(na, ma, mc, select)) + # go low + map!(t->t.tpsa, outx_low, m) -""" - ptinv(ma::Vector{<:Union{TPS,ComplexTPS}}, vars::Vector{<:Integer}) + GC.@preserve m1x_prom m2x_prom compose!(Cint(n), m2x_low, Cint(n1), m1x_low, outx_low) -Partially-inverts the map `ma`, inverting only the variables specified by index -in `vars`. -""" -function ptinv(ma::Vector{<:Union{TPS,ComplexTPS}}, vars::Vector{<:Integer}) - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(ma[1].tpsa).d)) - if length(ma) != desc.nv - error("Map length != number of variables in the GTPSA") - end - mc = zero.(ma) - ma1 = map(x->x.tpsa, ma) - mc1 = map(x->x.tpsa, mc) - na = Cint(length(ma)) - select = zeros(Cint, na) - select[vars] .= Cint(1) - pminv!(na, ma1, mc1, select) - return mc + return end -# --- composition --- -compose!(na::Cint, ma::Vector{Ptr{RTPSA}}, nb::Cint, mb::Vector{Ptr{RTPSA}}, mc::Vector{Ptr{RTPSA}}) = (@inline; mad_tpsa_compose!(na, ma, nb, mb, mc)) -compose!(na::Cint, ma::Vector{Ptr{CTPSA}}, nb::Cint, mb::Vector{Ptr{CTPSA}}, mc::Vector{Ptr{CTPSA}}) = (@inline; mad_ctpsa_compose!(na, ma, nb, mb, mc)) - function ∘(ma::Vector{<:Union{TPS,ComplexTPS}}, mb::Vector{<:Union{TPS,ComplexTPS}}) na = Cint(length(ma)) nb = Cint(length(mb)) # Ensure mb is length = input - desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(ma[1].tpsa).d)) - if desc.nv + desc.np != nb + desc = getdesc(first(ma)) + if numnn(desc) != nb error("Not enough input arguments") end - ma1, mb1 = promote(ma, mb) - m1 = map(t->t.tpsa, ma1) - m2 = map(t->t.tpsa, mb1) - mc = Vector{typeof(ma1[1])}(undef, na) - for i in eachindex(mc) - mc[i] = zero(ma1[1]) + outT = promote_type(eltype(ma),eltype(mb)) + mc = Vector{outT}(undef, na) + for i=1:na + @inbounds mc[i] = outT(use=desc) end - m3 = map(t->t.tpsa, mc) - GC.@preserve ma1 mb1 compose!(na, m1, nb, m2, m3) + compose!(mc, ma, mb) return mc end compose = ∘ # --- translate --- +translate!(na::Cint, ma::Vector{Ptr{RTPSA}}, nb::Cint, tb::Vector{Float64}, mc::Vector{Ptr{RTPSA}}) = mad_tpsa_translate!(na, ma, nb, tb, mc) +translate!(na::Cint, ma::Vector{Ptr{CTPSA}}, nb::Cint, tb::Vector{ComplexF64}, mc::Vector{Ptr{CTPSA}}) = mad_ctpsa_translate!(na, ma, nb, tb, mc) + + """ - translate(m::Vector{TPS}, x::Vector{<:Real})::Vector{TPS} + translate!(mc::Vector{<:T}, ma::Vector{<:T}, tb::Vector{<:Number}) where {T<:Union{TPS,ComplexTPS}} -Translates the expansion point of the Vector of TPSs `m` by `x`. +Fills `ma` with the vector function equal to `ma` with its expansion point translated by `tb`. + +Two temporary vectors of either `Ptr{RTPSA}` or `Ptr{CTPSA}` must be created, or they can optionally +be passed as a tuple to the kwarg `work_low` where + +`ma_low` = low corresponding to `ma` = `work_low[1]` +`mb_low` = low corresponding to `mb` = `work_low[2]` """ -function translate(m::Vector{TPS}, x::Vector{<:Real})::Vector{TPS} - na = Cint(length(m)) - nb = Cint(length(x)) - tb = convert(Vector{Float64}, x) - ma1 = map(x->x.tpsa, m) - mc = zero.(m) - mc1 = map(x->x.tpsa, mc) - mad_tpsa_translate!(na, ma1, nb, tb, mc1) - return mc +function translate!(mc::Vector{<:T}, ma::Vector{<:T}, tb::Vector{<:Number}; work_low::Union{Nothing,Tuple{Vararg{Vector{<:Union{Ptr{RTPSA},Ptr{CTPSA}}}}}}=nothing) where {T<:Union{TPS,ComplexTPS}} + desc = getdesc(first(ma)) + nb = Cint(length(tb)) + na = Cint(length(ma)) + numnn(desc) == nb || error("Not enough input arguments") + length(mc) == na || error("Output vector length != input vector length") + eltype(tb) == numtype(T) || error("Translation vector must have eltype $(numtype(T))") + if !isnothing(work_low) + ma_low = work_low[1] + mc_low = work_low[2] + else + ma_low = map(t->t.tpsa, ma) + mc_low = map(t->t.tpsa, mc) + end + translate!(na, ma_low, nb, tb, mc_low) end """ - translate(m::Vector{ComplexTPS}, x::Vector{<:Number})::Vector{ComplexTPS} - -Translates the expansion point of the Vector of TPSs `m` by `x`. +Returns a vector function equal to `ma` with its expansion point translated by `tb` """ -function translate(m::Vector{ComplexTPS}, x::Vector{<:Number})::Vector{ComplexTPS} - na = Cint(length(m)) - nb = Cint(length(x)) - tb = convert(Vector{ComplexF64}, x) - ma1 = map(x->x.tpsa, m) - mc = zero.(m) - mc1 = map(x->x.tpsa, mc) - mad_ctpsa_translate!(na, ma1, nb, tb, mc1) +function translate(ma::Vector{<:T}, tb::Vector{<:Number}) where {T<:Union{TPS,ComplexTPS}} + desc = getdesc(first(ma)) + nc = length(ma) + mc = Vector{T}(undef, nc) + for i=1:nc + mc[i] = T(use=desc) + end + translate!(mc, ma, convert(Vector{numtype(T)}, tb)) return mc end \ No newline at end of file diff --git a/src/operators.jl b/src/operators.jl index e54a2748..9be7bcd5 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -1,13 +1,13 @@ -# -- clear -- -function clear!(t::TPS) - mad_tpsa_clear!(t.tpsa) +# --- copy --- +function copy!(t::TPS, t1::TPS) + mad_tpsa_copy!(t1.tpsa, t.tpsa) end -function clear!(t::ComplexTPS) - mad_ctpsa_clear!(t.tpsa) +function copy!(ct::ComplexTPS, ct1::ComplexTPS) + mad_ctpsa_copy!(ct1.tpsa, ct.tpsa) end -# -- zero -- +# --- zero --- function zero(t::TPS)::TPS return TPS(mad_tpsa_new(t.tpsa, MAD_TPSA_SAME)) end diff --git a/src/tps.jl b/src/tps.jl new file mode 100644 index 00000000..b004043d --- /dev/null +++ b/src/tps.jl @@ -0,0 +1,248 @@ +# Wrapper struct for Ptr{RTPSA} +mutable struct TPS <: Real + tpsa::Ptr{RTPSA} + function TPS(t1::Ptr{RTPSA})::TPS + t = new(t1) + f(x) = mad_tpsa_del!(x.tpsa) + finalizer(f,t) + return t + end +end + +# Wrapper struct for Ptr{CTPSA} +mutable struct ComplexTPS <: Number + tpsa::Ptr{CTPSA} + function ComplexTPS(ct1::Ptr{CTPSA})::ComplexTPS + ct = new(ct1) + f(x) = mad_ctpsa_del!(x.tpsa) + finalizer(f,ct) + return ct + end +end + +""" + TPS(ta::Union{Real,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::TPS + +Constructor to create a new `TPS` equal to the real value `ta`. If `ta` is a `TPS`, this +is equivalent to a copy constructor, with the result by default having the same `Descriptor` as `ta`. +If `ta` is not a `TPS`, then the `Descriptor` used will by default be `GTPSA.desc_current`. The `Descriptor` +for the constructed `TPS` can be set using `use`. If a `TPS` or `ComplexTPS` is passed to `use`, +the `Descriptor` for that TPS will be used. + +The constructor can also be used to create a copy of a `TPS` under one `Descriptor` to instead +have a different `Descriptor`. In this case, invalid monomials under the new `Descriptor` are removed. + +### Input +- `ta` -- Any `Real` +- `use` -- (Optional) specify which `Descriptor` to use, default is `nothing` which uses the `Descriptor` for `ta` if `ta isa TPS`, else uses `GTPSA.desc_current` + +### Output +- `ret` -- New `TPS` equal to `ta` with removal of invalid monomials if `ta` is a `TPS` and a new `Descriptor` is specified +""" +function TPS(ta::Union{Real,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::TPS + return low_TPS(ta, use) +end + +# --- Blank TPS --- +function low_TPS(ta::Nothing, use::Descriptor) + return TPS(mad_tpsa_newd(use.desc, MAD_TPSA_DEFAULT)) +end + +function low_TPS(ta::Nothing, use::Union{TPS,ComplexTPS}) + return TPS(mad_tpsa_new(Base.unsafe_convert(Ptr{RTPSA}, use.tpsa), MAD_TPSA_SAME)) +end + +function low_TPS(ta::Nothing, use::Nothing) + return TPS(mad_tpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) +end + +# --- Copy ctor --- +function low_TPS(t1::TPS, use::Nothing) + t = TPS(mad_tpsa_new(t1.tpsa, MAD_TPSA_SAME)) + mad_tpsa_copy!(t1.tpsa, t.tpsa) + return t +end + +# --- Change descriptor --- +function low_TPS(t1::TPS, use::Descriptor) + return change(t1, use) +end + +function low_TPS(t1::TPS, use::Union{TPS,ComplexTPS}) + return change(t1, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa).d))) +end + +# --- promote real to TPS --- +function low_TPS(a::Real, use::Nothing) + t = TPS(mad_tpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) + mad_tpsa_set0!(t.tpsa, convert(Float64, 0), convert(Float64,a)) + return t +end + +function low_TPS(a::Real, use::Union{TPS,ComplexTPS}) + t = TPS(mad_tpsa_new(Base.unsafe_convert(Ptr{RTPSA}, use.tpsa), MAD_TPSA_SAME)) + mad_tpsa_set0!(t.tpsa, 0.0, convert(Float64,a)) + return t +end + +function low_TPS(a::Real, use::Descriptor) + t = TPS(mad_tpsa_newd(use.desc, MAD_TPSA_DEFAULT)) + mad_tpsa_set0!(t.tpsa, 0.0, convert(Float64,a)) + return t +end + +# ----------------------- +""" + ComplexTPS(cta::Union{Number,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::ComplexTPS + +Constructor to create a new `ComplexTPS` equal to the number `cta`. If `cta` is a `ComplexTPS` (or `TPS`), this +is equivalent to a copy constructor, with the result by default having the same `Descriptor` as `cta`. If `cta` +is not a `TPS` or`ComplexTPS`, then the `Descriptor` used will by default be `GTPSA.desc_current`. The `Descriptor` +for the constructed `ComplexTPS` can be set using `use`. If a `TPS` or `ComplexTPS` is passed to `use`, +the `Descriptor` for that TPS will be used. + +The constructor can also be used to create a copy of a `ComplexTPS` under one `Descriptor` to instead +have a different `Descriptor`. In this case, invalid monomials under the new `Descriptor` are removed. + +### Input +- `cta` -- Any `Number` +- `use` -- (Optional) specify which `Descriptor` to use, default is `nothing` which uses the `Descriptor` for `cta` if `cta <: Union{TPS,ComplexTPS}`, else uses `GTPSA.desc_current` + +### Output +- `ret` -- New `ComplexTPS` equal to `cta` with removal of invalid monomials if `cta` is a `TPS`/`ComplexTPS` and a new `Descriptor` is specified +""" +function ComplexTPS(cta::Union{Number,Nothing}=nothing; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::ComplexTPS + return low_ComplexTPS(cta, use) +end + +# For some reason I need to explicitly define this: +ComplexTPS(t::ComplexTPS; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing) = low_ComplexTPS(t,use) + +# --- Blank ComplexTPS --- +function low_ComplexTPS(cta::Nothing, use::Descriptor) + return ComplexTPS(mad_ctpsa_newd(use.desc, MAD_TPSA_DEFAULT)) +end + +function low_ComplexTPS(cta::Nothing, use::Union{TPS,ComplexTPS}) + return ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, use.tpsa), MAD_TPSA_SAME)) +end + +function low_ComplexTPS(cta::Nothing, use::Nothing) + return ComplexTPS(mad_ctpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) +end + +# --- Copy ctor --- +function low_ComplexTPS(ct1::ComplexTPS, use::Nothing) + ct = ComplexTPS(mad_ctpsa_new(ct1.tpsa, MAD_TPSA_SAME)) + mad_ctpsa_copy!(ct1.tpsa, ct.tpsa) + return ct +end + +function low_ComplexTPS(t1::TPS, use::Nothing) + ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) + mad_ctpsa_cplx!(t1.tpsa, Base.unsafe_convert(Ptr{RTPSA}, C_NULL), ct.tpsa) + return ct +end + +# --- Change descriptor --- +function low_ComplexTPS(t1::Union{TPS,ComplexTPS}, use::Descriptor) + return change(t1, use) +end + +function low_ComplexTPS(t1::Union{TPS,ComplexTPS}, use::Union{TPS,ComplexTPS}) + return change(t1, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa).d))) +end + +# --- promote number to ComplexTPS --- +function low_ComplexTPS(a::Union{Real,Complex}, use::Nothing) + ct = ComplexTPS(mad_ctpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64,a)) + return ct +end + +function low_ComplexTPS(a::Union{Real,Complex}, use::Union{TPS,ComplexTPS}) + ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, use.tpsa), MAD_TPSA_SAME)) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64,a)) + return ct +end + +function low_ComplexTPS(a::Union{Real,Complex}, use::Descriptor) + ct = ComplexTPS(mad_ctpsa_newd(use.desc, MAD_TPSA_DEFAULT)) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64,a)) + return ct +end + +# ----------------------- + +# Special real argument ctors +function ComplexTPS(ta::Real, tb::Real; use::Union{Descriptor,TPS,ComplexTPS,Nothing}=nothing)::ComplexTPS + low_ComplexTPS(ta, tb, use) +end + +function low_ComplexTPS(t1::TPS, t2::TPS, use::Nothing) + ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) + mad_ctpsa_cplx!(t1.tpsa, t2.tpsa, ct.tpsa) + return ct +end + +function low_ComplexTPS(t1::TPS, a::Real, use::Nothing) + ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) + mad_ctpsa_cplx!(t1.tpsa, Base.unsafe_convert(Ptr{RTPSA}, C_NULL), ct.tpsa) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, complex(0,a))) + return ct +end + +function low_ComplexTPS(a::Real, t1::TPS, use::Nothing) + ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, t1.tpsa), MAD_TPSA_SAME)) + mad_ctpsa_cplx!(Base.unsafe_convert(Ptr{RTPSA}, C_NULL), t1.tpsa, ct.tpsa) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, a)) + return ct +end + +function low_ComplexTPS(a::Real, b::Real, use::Nothing) + ct = ComplexTPS(mad_ctpsa_newd(GTPSA.desc_current.desc, MAD_TPSA_DEFAULT)) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64, complex(a,b))) + return ct +end + +function low_ComplexTPS(a::Real, b::Real, use::Descriptor) + ct = ComplexTPS(mad_ctpsa_newd(use.desc, MAD_TPSA_DEFAULT)) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64, complex(a,b))) + return ct +end + +function low_ComplexTPS(a::Real, b::Real, use::Union{TPS,ComplexTPS}) + ct = ComplexTPS(mad_ctpsa_new(Base.unsafe_convert(Ptr{CTPSA}, use.tpsa), MAD_TPSA_SAME)) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 0), convert(ComplexF64, complex(a,b))) + return ct +end + +function low_ComplexTPS(ta::TPS, tb::TPS, use::Descriptor) + ct = change(ta, use, type=ComplexTPS) + change!(ct, tb, 1, im) + return ct +end + +function low_ComplexTPS(ta::TPS, b::Real, use::Descriptor) + ct = change(ta, use, type=ComplexTPS) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, complex(0,b))) + return ct +end + +function low_ComplexTPS(a::Real, tb::TPS, use::Descriptor) + ct = change(tb, use, type=ComplexTPS, scl2=im) + mad_ctpsa_set0!(ct.tpsa, convert(ComplexF64, 1), convert(ComplexF64, a)) + return ct +end + +function low_ComplexTPS(ta::TPS, tb::TPS, use::Union{TPS,ComplexTPS}) + return low_ComplexTPS(ta, tb, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa)))) +end + +function low_ComplexTPS(ta::TPS, b::Real, use::Union{TPS,ComplexTPS}) + return low_ComplexTPS(ta, b, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa)))) +end + +function low_ComplexTPS(a::Real, tb::TPS, use::Union{TPS,ComplexTPS}) + return low_ComplexTPS(a, tb, Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(use.tpsa)))) +end \ No newline at end of file diff --git a/src/utils.jl b/src/utils.jl new file mode 100644 index 00000000..9f8b76cc --- /dev/null +++ b/src/utils.jl @@ -0,0 +1,150 @@ +numtype(t::TPS) = Float64 +numtype(ct::ComplexTPS) = ComplexF64 +numtype(::Type{TPS}) = Float64 +numtype(::Type{ComplexTPS}) = ComplexF64 + +lowtype(t::TPS) = Ptr{RTPSA} +lowtype(ct::ComplexTPS) = Ptr{CTPSA} +lowtype(::Type{TPS}) = Ptr{RTPSA} +lowtype(::Type{ComplexTPS}) = Ptr{CTPSA} + +getdesc(t::Union{TPS,ComplexTPS}) = Descriptor(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)) +numvars(t::Union{TPS,ComplexTPS}) = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)).nv +numparams(t::Union{TPS,ComplexTPS}) = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)).np +numnn(t::Union{TPS,ComplexTPS}) = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d)).nn +getdesc(d::Descriptor) = d +numvars(d::Descriptor) = unsafe_load(d.desc).nv +numparams(d::Descriptor) = unsafe_load(d.desc).np +numnn(d::Descriptor) = unsafe_load(d.desc).nn +getdesc(d::Nothing) = nothing + + + +const SMIndexType = Union{Vector{<:Pair{<:Integer,<:Integer}}, Tuple{Vararg{Pair{<:Integer,<:Integer}}}} +const MIndexType = Union{Vector{<:Integer}, Tuple{Vararg{Integer}}} +const TPSIndexType = Union{Integer, + MIndexType, + SMIndexType} + + +cycle!(t::Ptr{RTPSA}, i::Cint, n::Cint, m_::Vector{Cuchar}, v_::Ref{Cdouble}) = (@inline; mad_tpsa_cycle!(t, i, n, m_, v_)) +cycle!(t::Ptr{CTPSA}, i::Cint, n::Cint, m_::Vector{Cuchar}, v_::Ref{ComplexF64}) = (@inline; mad_ctpsa_cycle!(t, i, n, m_, v_)) + +# Generic function to make new copy of TPS with different descriptor +function change(t1::Union{TPS,ComplexTPS}, newd::Descriptor; type::Type=typeof(t1), scl2::Number=1) + # Quick check if actually changing + if Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d) == newd.desc + return type(t1) + end + + # THE NUMBER OF VARIABLES and PARAMETERS MUST AGREE!!! + unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)).nv == unsafe_load(newd.desc).nv || error("Number of variables in GTPSAs do not agree!") + unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)).np == unsafe_load(newd.desc).np || error("Number of parameters in GTPSAs do not agree!") + + t = type(use=newd) + change!(t, t1, 0, scl2) + return t +end + +function change!(t::Union{TPS,ComplexTPS},t1::Union{TPS,ComplexTPS}, scl1::Number=0, scl2::Number=1) + desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)) + nv = desc.nv + np = desc.np + coef = Ref{numtype(t1)}() + mono = Vector{Cuchar}(undef, np+nv) + idx = cycle!(t1.tpsa, Cint(-1), np+nv, mono, coef) + while idx >= 0 + # if valid monomial in new descriptor: + if convert(Bool, mad_desc_isvalidm(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d), np+nv, mono)) + setm!(t.tpsa, np+nv, mono, convert(numtype(t), scl1), convert(numtype(t), scl2*coef[])) # set new tpsa + end + idx = cycle!(t1.tpsa, idx, np+nv, mono, coef) + end +end + +# Function to convert var=>ord, params=(param=>ord,) to low level sparse monomial format (varidx1, ord1, varidx2, ord2, paramidx, ordp1,...) +function pairs_to_sm(t::Union{TPS,ComplexTPS}, vars::Union{Vector{<:Pair{<:Integer, <:Integer}},Tuple{Vararg{Pair{<:Integer,<:Integer}}}}; params::Union{Vector{<:Pair{<:Integer,<:Integer}},Tuple{Vararg{<:Pair{<:Integer,<:Integer}}},Nothing}=nothing)::Tuple{Vector{Cint}, Cint} + # WE MUST Order THE VARIABLES !!! + nv = numvars(t) + numv = Cint(length(vars)) + if !isnothing(params) + nump = Cint(length(params)) + imin = min(minimum(x->x.first, vars,init=typemax(Int)), minimum(x->x.first+nv, params,init=typemax(Int))) + imax = max(maximum(x->x.first, vars,init=0), maximum(x->x.first+nv, params,init=0)) + else + nump = 0 + imin = minimum(x->x.first, vars,init=typemax(Int)) + imax = maximum(x->x.first, vars,init=0) + end + len = imax-imin+1 + sm = zeros(Cint, 2*len) + sm[1:2:end] = imin:imax + for i=1:numv + sm[2*(vars[i].first-imin+1)] = convert(Cint, vars[i].second) + end + for i=1:nump + sm[2*(params[i].first+nv-imin+1)] = convert(Cint, params[i].second) + end + + return sm, 2*len +end + +# Function to convert var=>ord, params=(param=>ord,) to monomial format (byte array of orders) +function pairs_to_m(t::Union{TPS,ComplexTPS}, vars::Union{Vector{<:Pair{<:Integer, <:Integer}},Tuple{Vararg{Pair{<:Integer,<:Integer}}}}; params::Union{Vector{<:Pair{<:Integer, <:Integer}},Tuple{Vararg{Pair{<:Integer,<:Integer}}}}=Pair{Int,Int}[],zero_mono=true)::Tuple{Vector{UInt8}, Cint} + nv = numvars(t) + n = Cint(0) + if isempty(params) + n = Cint(maximum(map(x->x.first, vars))) + else + n = Cint(maximum(map(x->x.first, params))) + nv + end + if zero_mono + ords = zeros(Cuchar, n) + else + ords = ones(Cuchar, n).*0xff + end + for var in vars + ords[var.first] = convert(Cuchar, var.second) + end + for param in params + ords[nv + param.first] = convert(Cuchar, param.second) + end + return ords, n +end + +# Prevent undefined behavior +# Until AbstractComplex is implemented, I make the ctor return error because this should never happen +# asumming I wrapped enough +#= +Complex(t1::TPS) = complex(t1) +Complex(t1::TPS, t2::TPS) = complex(t1, t2) +Complex(t1::TPS, a::Real) = complex(t1, a) +Complex(a::Real, t1::TPS) = complex(a, t1) +Complex{TPS}(t1::TPS) = complex(t1) +Complex{TPS}(t1::TPS, t2::TPS) = complex(t1, t2) +Complex{TPS}(t1::TPS, a::Real) = complex(t1, a) +Complex{TPS}(a::Real, t1::TPS) = complex(a, t1)=# +Complex(t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") +Complex(t1::TPS, t2::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") +Complex(t1::TPS, a::Real) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") +Complex(a::Real, t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") +Complex{TPS}(t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") +Complex{TPS}(t1::TPS, t2::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") +Complex{TPS}(t1::TPS, a::Real) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") +Complex{TPS}(a::Real, t1::TPS) = error("ComplexTPS can only be defined as an AbstractComplex type (to be implemented in Julia PR #35587). If this error was reached without explicitly attempting to create a Complex{TPS}, please submit an issue to GTPSA.jl with an example.") + +promote_rule(::Type{TPS}, ::Union{Type{<:AbstractFloat}, Type{<:Integer}, Type{<:Rational}, Type{<:AbstractIrrational}}) = TPS +promote_rule(::Type{ComplexTPS}, ::Union{Type{Complex{<:Real}},Type{<:AbstractFloat}, Type{<:Integer}, Type{<:Rational}, Type{<:AbstractIrrational}}) = ComplexTPS +promote_rule(::Type{TPS}, ::Union{Type{ComplexTPS}, Type{Complex{<:Real}}}) = ComplexTPS + +# Handle bool which is special for some reason ++(t::TPS, z::Complex{Bool}) = t + Complex{Int}(z) ++(z::Complex{Bool}, t::TPS) = Complex{Int}(z) + t +-(t::TPS, z::Complex{Bool}) = t - Complex{Int}(z) +-(z::Complex{Bool}, t::TPS) = Complex{Int}(z) - t +*(t::TPS, z::Complex{Bool}) = t * Complex{Int}(z) +*(z::Complex{Bool}, t::TPS) = Complex{Int}(z) * t +/(t::TPS, z::Complex{Bool}) = t / Complex{Int}(z) +/(z::Complex{Bool}, t::TPS) = Complex{Int}(z) / t +^(t::TPS, z::Complex{Bool}) = t ^ Complex{Int}(z) +^(z::Complex{Bool}, t::TPS) = Complex{Int}(z) ^ t \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 205b6c57..ed2e0929 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -136,9 +136,9 @@ import GTPSA: Desc, RTPSA, CTPSA # Now do operators # Test definition of 1-norm: tn = zero(t1) - tn[0] = 1; tn[1] = 2; tn[2] = 3; tn[3] = 4; tn[4] = 5; tn[5] = 6 + tn[0] = 1; tn[[1]] = 2; tn[[2]] = 3; tn[[3]] = 4; tn[[4]] = 5; tn[[5]] = 6 tcn = zero(ct1) - tcn[0] = 1+1im; tcn[1] = 2+2im; tcn[2] = 3+3im; tcn[3] = 4+4im; tcn[4] = 5+5im; tcn[5] = 6+6im + tcn[0] = 1+1im; tcn[[1]] = 2+2im; tcn[[2]] = 3+3im; tcn[[3]] = 4+4im; tcn[[4]] = 5+5im; tcn[[5]] = 6+6im @test norm(tn) == sum([i for i in 1:6]) @test norm(tcn) == sum([abs(i+i*im) for i in 1:6]) @@ -405,7 +405,7 @@ end @testset "Functions: identities, using TPSs" begin d = Descriptor(1, 5) t = TPS(use=d) - t[0] = 0.5; t[1] = 2; t[2] = 3; t[3] = 4; t[4] = 5; t[5] = 6 + t[0] = 0.5; t[[1]] = 2; t[[2]] = 3; t[[3]] = 4; t[[4]] = 5; t[[5]] = 6 tol = 1e-10 @@ -462,7 +462,7 @@ end @test norm(complex(t,t) - (t+im*t)) < tol t = ComplexTPS(t) - t[0] = 0.5+0.5im; t[1] = 2+2im; t[2] = 3+3im; t[3] = 4+4im; t[4] = 5+5im; t[5] = 6+6im + t[0] = 0.5+0.5im; t[[1]] = 2+2im; t[[2]] = 3+3im; t[[3]] = 4+4im; t[[4]] = 5+5im; t[[5]] = 6+6im @test norm(sin(t)^2+cos(t)^2 - 1) < tol @test norm(1/sin(t) - csc(t)) < tol @test norm(1/cos(t) - sec(t)) < tol @@ -522,216 +522,216 @@ end tol = 1e-18 f = sin(v[1]) - @test abs(f[0] - 0) < tol - @test abs(f[1] - 1) < tol - @test abs(f[2] - 0) < tol - @test abs(f[3] - -1/factorial(3)) < tol - @test abs(f[4] - 0) < tol - @test abs(f[5] - 1/factorial(5)) < tol - @test abs(f[6] - 0) < tol - @test abs(f[7] - -1/factorial(7)) < tol - @test abs(f[8] - 0) < tol - @test abs(f[9] - 1/factorial(9)) < tol - @test abs(f[10] - 0) < tol - - @test abs(f[1=>1] - f[1]) < tol - @test abs(f[1=>2] - f[2]) < tol - @test abs(f[1=>3] - f[3]) < tol - @test abs(f[1=>4] - f[4]) < tol - @test abs(f[1=>5] - f[5]) < tol - @test abs(f[1=>6] - f[6]) < tol - @test abs(f[1=>7] - f[7]) < tol - @test abs(f[1=>8] - f[8]) < tol - @test abs(f[1=>9] - f[9]) < tol - @test abs(f[1=>10] - f[10]) < tol + @test abs(f[[0]] - 0) < tol + @test abs(f[[1]] - 1) < tol + @test abs(f[[2]] - 0) < tol + @test abs(f[[3]] - -1/factorial(3)) < tol + @test abs(f[[4]] - 0) < tol + @test abs(f[[5]] - 1/factorial(5)) < tol + @test abs(f[[6]] - 0) < tol + @test abs(f[[7]] - -1/factorial(7)) < tol + @test abs(f[[8]] - 0) < tol + @test abs(f[[9]] - 1/factorial(9)) < tol + @test abs(f[[10]] - 0) < tol + + @test abs(f[[1=>1]] - f[[1]]) < tol + @test abs(f[[1=>2]] - f[[2]]) < tol + @test abs(f[[1=>3]] - f[[3]]) < tol + @test abs(f[[1=>4]] - f[[4]]) < tol + @test abs(f[[1=>5]] - f[[5]]) < tol + @test abs(f[[1=>6]] - f[[6]]) < tol + @test abs(f[[1=>7]] - f[[7]]) < tol + @test abs(f[[1=>8]] - f[[8]]) < tol + @test abs(f[[1=>9]] - f[[9]]) < tol + @test abs(f[[1=>10]] - f[[10]]) < tol fc = complex(f) - @test abs(fc[0] - 0) < tol - @test abs(fc[1] - 1) < tol - @test abs(fc[2] - 0) < tol - @test abs(fc[3] - -1/factorial(3)) < tol - @test abs(fc[4] - 0) < tol - @test abs(fc[5] - 1/factorial(5)) < tol - @test abs(fc[6] - 0) < tol - @test abs(fc[7] - -1/factorial(7)) < tol - @test abs(fc[8] - 0) < tol - @test abs(fc[9] - 1/factorial(9)) < tol - @test abs(fc[10] - 0) < tol - - @test abs(fc[1=>1] - f[1]) < tol - @test abs(fc[1=>2] - f[2]) < tol - @test abs(fc[1=>3] - f[3]) < tol - @test abs(fc[1=>4] - f[4]) < tol - @test abs(fc[1=>5] - f[5]) < tol - @test abs(fc[1=>6] - f[6]) < tol - @test abs(fc[1=>7] - f[7]) < tol - @test abs(fc[1=>8] - f[8]) < tol - @test abs(fc[1=>9] - f[9]) < tol - @test abs(fc[1=>10] - f[10]) < tol + @test abs(fc[[0]] - 0) < tol + @test abs(fc[[1]] - 1) < tol + @test abs(fc[[2]] - 0) < tol + @test abs(fc[[3]] - -1/factorial(3)) < tol + @test abs(fc[[4]] - 0) < tol + @test abs(fc[[5]] - 1/factorial(5)) < tol + @test abs(fc[[6]] - 0) < tol + @test abs(fc[[7]] - -1/factorial(7)) < tol + @test abs(fc[[8]] - 0) < tol + @test abs(fc[[9]] - 1/factorial(9)) < tol + @test abs(fc[[10]] - 0) < tol + + @test abs(fc[[1=>1]] - f[[1]]) < tol + @test abs(fc[[1=>2]] - f[[2]]) < tol + @test abs(fc[[1=>3]] - f[[3]]) < tol + @test abs(fc[[1=>4]] - f[[4]]) < tol + @test abs(fc[[1=>5]] - f[[5]]) < tol + @test abs(fc[[1=>6]] - f[[6]]) < tol + @test abs(fc[[1=>7]] - f[[7]]) < tol + @test abs(fc[[1=>8]] - f[[8]]) < tol + @test abs(fc[[1=>9]] - f[[9]]) < tol + @test abs(fc[[1=>10]] - f[[10]]) < tol f2 = sin(v[1]) + cos(v[2]) - @test abs(f2[0] - 1) < tol - @test abs(f2[1] - 1) < tol - @test abs(f2[2] - 0) < tol - @test abs(f2[3] - -1/factorial(3)) < tol - @test abs(f2[4] - 0) < tol - @test abs(f2[5] - 1/factorial(5)) < tol - @test abs(f2[6] - 0) < tol - @test abs(f2[7] - -1/factorial(7)) < tol - @test abs(f2[8] - 0) < tol - @test abs(f2[9] - 1/factorial(9)) < tol - @test abs(f2[10] - 0) < tol - - @test abs(f2[0,0] - 1) < tol - @test abs(f2[0,1] - 0) < tol - @test abs(f2[0,2] - -1/factorial(2)) < tol - @test abs(f2[0,3] - 0) < tol - @test abs(f2[0,4] - 1/factorial(4)) < tol - @test abs(f2[0,5] - 0) < tol - @test abs(f2[0,6] - -1/factorial(6)) < tol - @test abs(f2[0,7] - 0) < tol - @test abs(f2[0,8] - 1/factorial(8)) < tol - @test abs(f2[0,9] - 0) < tol - @test abs(f2[0,10] - -1/factorial(10)) < tol - - @test abs(f2[1=>1] - f2[1]) < tol - @test abs(f2[1=>2] - f2[2]) < tol - @test abs(f2[1=>3] - f2[3]) < tol - @test abs(f2[1=>4] - f2[4]) < tol - @test abs(f2[1=>5] - f2[5]) < tol - @test abs(f2[1=>6] - f2[6]) < tol - @test abs(f2[1=>7] - f2[7]) < tol - @test abs(f2[1=>8] - f2[8]) < tol - @test abs(f2[1=>9] - f2[9]) < tol - @test abs(f2[1=>10] - f2[10]) < tol - - @test abs(f2[2=>1] - f2[0,1]) < tol - @test abs(f2[2=>2] - f2[0,2]) < tol - @test abs(f2[2=>3] - f2[0,3]) < tol - @test abs(f2[2=>4] - f2[0,4]) < tol - @test abs(f2[2=>5] - f2[0,5]) < tol - @test abs(f2[2=>6] - f2[0,6]) < tol - @test abs(f2[2=>7] - f2[0,7]) < tol - @test abs(f2[2=>8] - f2[0,8]) < tol - @test abs(f2[2=>9] - f2[0,9]) < tol - @test abs(f2[2=>10] - f2[0,10]) < tol + @test abs(f2[[0]] - 1) < tol + @test abs(f2[[1]] - 1) < tol + @test abs(f2[[2]] - 0) < tol + @test abs(f2[[3]] - -1/factorial(3)) < tol + @test abs(f2[[4]] - 0) < tol + @test abs(f2[[5]] - 1/factorial(5)) < tol + @test abs(f2[[6]] - 0) < tol + @test abs(f2[[7]] - -1/factorial(7)) < tol + @test abs(f2[[8]] - 0) < tol + @test abs(f2[[9]] - 1/factorial(9)) < tol + @test abs(f2[[10]] - 0) < tol + + @test abs(f2[[0,0]] - 1) < tol + @test abs(f2[[0,1]] - 0) < tol + @test abs(f2[[0,2]] - -1/factorial(2)) < tol + @test abs(f2[[0,3]] - 0) < tol + @test abs(f2[[0,4]] - 1/factorial(4)) < tol + @test abs(f2[[0,5]] - 0) < tol + @test abs(f2[[0,6]] - -1/factorial(6)) < tol + @test abs(f2[[0,7]] - 0) < tol + @test abs(f2[[0,8]] - 1/factorial(8)) < tol + @test abs(f2[[0,9]] - 0) < tol + @test abs(f2[[0,10]] - -1/factorial(10)) < tol + + @test abs(f2[[1=>1]] - f2[[1]]) < tol + @test abs(f2[[1=>2]] - f2[[2]]) < tol + @test abs(f2[[1=>3]] - f2[[3]]) < tol + @test abs(f2[[1=>4]] - f2[[4]]) < tol + @test abs(f2[[1=>5]] - f2[[5]]) < tol + @test abs(f2[[1=>6]] - f2[[6]]) < tol + @test abs(f2[[1=>7]] - f2[[7]]) < tol + @test abs(f2[[1=>8]] - f2[[8]]) < tol + @test abs(f2[[1=>9]] - f2[[9]]) < tol + @test abs(f2[[1=>10]] - f2[[10]]) < tol + + @test abs(f2[[2=>1]] - f2[[0,1]]) < tol + @test abs(f2[[2=>2]] - f2[[0,2]]) < tol + @test abs(f2[[2=>3]] - f2[[0,3]]) < tol + @test abs(f2[[2=>4]] - f2[[0,4]]) < tol + @test abs(f2[[2=>5]] - f2[[0,5]]) < tol + @test abs(f2[[2=>6]] - f2[[0,6]]) < tol + @test abs(f2[[2=>7]] - f2[[0,7]]) < tol + @test abs(f2[[2=>8]] - f2[[0,8]]) < tol + @test abs(f2[[2=>9]] - f2[[0,9]]) < tol + @test abs(f2[[2=>10]] - f2[[0,10]]) < tol f2c = complex(sin(v[1]) + cos(v[2])) - @test abs(f2c[0] - 1) < tol - @test abs(f2c[1] - 1) < tol - @test abs(f2c[2] - 0) < tol - @test abs(f2c[3] - -1/factorial(3)) < tol - @test abs(f2c[4] - 0) < tol - @test abs(f2c[5] - 1/factorial(5)) < tol - @test abs(f2c[6] - 0) < tol - @test abs(f2c[7] - -1/factorial(7)) < tol - @test abs(f2c[8] - 0) < tol - @test abs(f2c[9] - 1/factorial(9)) < tol - @test abs(f2c[10] - 0) < tol - - @test abs(f2c[0,0] - 1) < tol - @test abs(f2c[0,1] - 0) < tol - @test abs(f2c[0,2] - -1/factorial(2)) < tol - @test abs(f2c[0,3] - 0) < tol - @test abs(f2c[0,4] - 1/factorial(4)) < tol - @test abs(f2c[0,5] - 0) < tol - @test abs(f2c[0,6] - -1/factorial(6)) < tol - @test abs(f2c[0,7] - 0) < tol - @test abs(f2c[0,8] - 1/factorial(8)) < tol - @test abs(f2c[0,9] - 0) < tol - @test abs(f2c[0,10] - -1/factorial(10)) < tol - - @test abs(f2c[1=>1] - f2c[1]) < tol - @test abs(f2c[1=>2] - f2c[2]) < tol - @test abs(f2c[1=>3] - f2c[3]) < tol - @test abs(f2c[1=>4] - f2c[4]) < tol - @test abs(f2c[1=>5] - f2c[5]) < tol - @test abs(f2c[1=>6] - f2c[6]) < tol - @test abs(f2c[1=>7] - f2c[7]) < tol - @test abs(f2c[1=>8] - f2c[8]) < tol - @test abs(f2c[1=>9] - f2c[9]) < tol - @test abs(f2c[1=>10] - f2c[10]) < tol - - @test abs(f2c[2=>1] - f2c[0,1]) < tol - @test abs(f2c[2=>2] - f2c[0,2]) < tol - @test abs(f2c[2=>3] - f2c[0,3]) < tol - @test abs(f2c[2=>4] - f2c[0,4]) < tol - @test abs(f2c[2=>5] - f2c[0,5]) < tol - @test abs(f2c[2=>6] - f2c[0,6]) < tol - @test abs(f2c[2=>7] - f2c[0,7]) < tol - @test abs(f2c[2=>8] - f2c[0,8]) < tol - @test abs(f2c[2=>9] - f2c[0,9]) < tol - @test abs(f2c[2=>10] - f2c[0,10]) < tol + @test abs(f2c[[0]] - 1) < tol + @test abs(f2c[[1]] - 1) < tol + @test abs(f2c[[2]] - 0) < tol + @test abs(f2c[[3]] - -1/factorial(3)) < tol + @test abs(f2c[[4]] - 0) < tol + @test abs(f2c[[5]] - 1/factorial(5)) < tol + @test abs(f2c[[6]] - 0) < tol + @test abs(f2c[[7]] - -1/factorial(7)) < tol + @test abs(f2c[[8]] - 0) < tol + @test abs(f2c[[9]] - 1/factorial(9)) < tol + @test abs(f2c[[10]] - 0) < tol + + @test abs(f2c[[0,0]] - 1) < tol + @test abs(f2c[[0,1]] - 0) < tol + @test abs(f2c[[0,2]] - -1/factorial(2)) < tol + @test abs(f2c[[0,3]] - 0) < tol + @test abs(f2c[[0,4]] - 1/factorial(4)) < tol + @test abs(f2c[[0,5]] - 0) < tol + @test abs(f2c[[0,6]] - -1/factorial(6)) < tol + @test abs(f2c[[0,7]] - 0) < tol + @test abs(f2c[[0,8]] - 1/factorial(8)) < tol + @test abs(f2c[[0,9]] - 0) < tol + @test abs(f2c[[0,10]] - -1/factorial(10)) < tol + + @test abs(f2c[[1=>1]] - f2c[[1]]) < tol + @test abs(f2c[[1=>2]] - f2c[[2]]) < tol + @test abs(f2c[[1=>3]] - f2c[[3]]) < tol + @test abs(f2c[[1=>4]] - f2c[[4]]) < tol + @test abs(f2c[[1=>5]] - f2c[[5]]) < tol + @test abs(f2c[[1=>6]] - f2c[[6]]) < tol + @test abs(f2c[[1=>7]] - f2c[[7]]) < tol + @test abs(f2c[[1=>8]] - f2c[[8]]) < tol + @test abs(f2c[[1=>9]] - f2c[[9]]) < tol + @test abs(f2c[[1=>10]] - f2c[[10]]) < tol + + @test abs(f2c[[2=>1]] - f2c[[0,1]]) < tol + @test abs(f2c[[2=>2]] - f2c[[0,2]]) < tol + @test abs(f2c[[2=>3]] - f2c[[0,3]]) < tol + @test abs(f2c[[2=>4]] - f2c[[0,4]]) < tol + @test abs(f2c[[2=>5]] - f2c[[0,5]]) < tol + @test abs(f2c[[2=>6]] - f2c[[0,6]]) < tol + @test abs(f2c[[2=>7]] - f2c[[0,7]]) < tol + @test abs(f2c[[2=>8]] - f2c[[0,8]]) < tol + @test abs(f2c[[2=>9]] - f2c[[0,9]]) < tol + @test abs(f2c[[2=>10]] - f2c[[0,10]]) < tol f3 = sin(v[1]) + cos(v[2]) + exp(p[1]) - @test abs(f3[0] - 2) < tol - @test abs(f3[1] - 1) < tol - @test abs(f3[2] - 0) < tol - @test abs(f3[3] - -1/factorial(3)) < tol - @test abs(f3[4] - 0) < tol - @test abs(f3[5] - 1/factorial(5)) < tol - @test abs(f3[6] - 0) < tol - @test abs(f3[7] - -1/factorial(7)) < tol - @test abs(f3[8] - 0) < tol - @test abs(f3[9] - 1/factorial(9)) < tol - @test abs(f3[10] - 0) < tol - - @test abs(f3[0,0] - 2) < tol - @test abs(f3[0,1] - 0) < tol - @test abs(f3[0,2] - -1/factorial(2)) < tol - @test abs(f3[0,3] - 0) < tol - @test abs(f3[0,4] - 1/factorial(4)) < tol - @test abs(f3[0,5] - 0) < tol - @test abs(f3[0,6] - -1/factorial(6)) < tol - @test abs(f3[0,7] - 0) < tol - @test abs(f3[0,8] - 1/factorial(8)) < tol - @test abs(f3[0,9] - 0) < tol - @test abs(f3[0,10] - -1/factorial(10)) < tol - - @test abs(f3[0,0,0,0] - 2) < tol - @test abs(f3[0,0,0,1] - 1/factorial(1)) < tol - @test abs(f3[0,0,0,2] - 1/factorial(2)) < tol - @test abs(f3[0,0,0,3] - 1/factorial(3)) < tol - @test abs(f3[0,0,0,4] - 1/factorial(4)) < tol - @test abs(f3[0,0,0,5] - 1/factorial(5)) < tol - @test abs(f3[0,0,0,6] - 1/factorial(6)) < tol - @test abs(f3[0,0,0,7] - 1/factorial(7)) < tol - @test abs(f3[0,0,0,8] - 1/factorial(8)) < tol - @test abs(f3[0,0,0,9] - 1/factorial(9)) < tol - @test abs(f3[0,0,0,10] - 1/factorial(10)) < tol - - @test abs(f3[1=>1] - f3[1]) < tol - @test abs(f3[1=>2] - f3[2]) < tol - @test abs(f3[1=>3] - f3[3]) < tol - @test abs(f3[1=>4] - f3[4]) < tol - @test abs(f3[1=>5] - f3[5]) < tol - @test abs(f3[1=>6] - f3[6]) < tol - @test abs(f3[1=>7] - f3[7]) < tol - @test abs(f3[1=>8] - f3[8]) < tol - @test abs(f3[1=>9] - f3[9]) < tol - @test abs(f3[1=>10] - f3[10]) < tol - - @test abs(f3[2=>1] - f3[0,1]) < tol - @test abs(f3[2=>2] - f3[0,2]) < tol - @test abs(f3[2=>3] - f3[0,3]) < tol - @test abs(f3[2=>4] - f3[0,4]) < tol - @test abs(f3[2=>5] - f3[0,5]) < tol - @test abs(f3[2=>6] - f3[0,6]) < tol - @test abs(f3[2=>7] - f3[0,7]) < tol - @test abs(f3[2=>8] - f3[0,8]) < tol - @test abs(f3[2=>9] - f3[0,9]) < tol - @test abs(f3[2=>10] - f3[0,10]) < tol - - @test abs(f3[params=[1=>1]] - f3[0,0,0,1]) < tol - @test abs(f3[params=[1=>2]] - f3[0,0,0,2]) < tol - @test abs(f3[params=[1=>3]] - f3[0,0,0,3]) < tol - @test abs(f3[params=[1=>4]] - f3[0,0,0,4]) < tol - @test abs(f3[params=[1=>5]] - f3[0,0,0,5]) < tol - @test abs(f3[params=[1=>6]] - f3[0,0,0,6]) < tol - @test abs(f3[params=[1=>7]] - f3[0,0,0,7]) < tol - @test abs(f3[params=[1=>8]] - f3[0,0,0,8]) < tol - @test abs(f3[params=[1=>9]] - f3[0,0,0,9]) < tol - @test abs(f3[params=[1=>10]] - f3[0,0,0,10]) < tol + @test abs(f3[[0]] - 2) < tol + @test abs(f3[[1]] - 1) < tol + @test abs(f3[[2]] - 0) < tol + @test abs(f3[[3]] - -1/factorial(3)) < tol + @test abs(f3[[4]] - 0) < tol + @test abs(f3[[5]] - 1/factorial(5)) < tol + @test abs(f3[[6]] - 0) < tol + @test abs(f3[[7]] - -1/factorial(7)) < tol + @test abs(f3[[8]] - 0) < tol + @test abs(f3[[9]] - 1/factorial(9)) < tol + @test abs(f3[[10]] - 0) < tol + + @test abs(f3[[0,0]] - 2) < tol + @test abs(f3[[0,1]] - 0) < tol + @test abs(f3[[0,2]] - -1/factorial(2)) < tol + @test abs(f3[[0,3]] - 0) < tol + @test abs(f3[[0,4]] - 1/factorial(4)) < tol + @test abs(f3[[0,5]] - 0) < tol + @test abs(f3[[0,6]] - -1/factorial(6)) < tol + @test abs(f3[[0,7]] - 0) < tol + @test abs(f3[[0,8]] - 1/factorial(8)) < tol + @test abs(f3[[0,9]] - 0) < tol + @test abs(f3[[0,10]] - -1/factorial(10)) < tol + + @test abs(f3[[0,0,0,0]] - 2) < tol + @test abs(f3[[0,0,0,1]] - 1/factorial(1)) < tol + @test abs(f3[[0,0,0,2]] - 1/factorial(2)) < tol + @test abs(f3[[0,0,0,3]] - 1/factorial(3)) < tol + @test abs(f3[[0,0,0,4]] - 1/factorial(4)) < tol + @test abs(f3[[0,0,0,5]] - 1/factorial(5)) < tol + @test abs(f3[[0,0,0,6]] - 1/factorial(6)) < tol + @test abs(f3[[0,0,0,7]] - 1/factorial(7)) < tol + @test abs(f3[[0,0,0,8]] - 1/factorial(8)) < tol + @test abs(f3[[0,0,0,9]] - 1/factorial(9)) < tol + @test abs(f3[[0,0,0,10]] - 1/factorial(10)) < tol + + @test abs(f3[[1=>1]] - f3[[1]]) < tol + @test abs(f3[[1=>2]] - f3[[2]]) < tol + @test abs(f3[[1=>3]] - f3[[3]]) < tol + @test abs(f3[[1=>4]] - f3[[4]]) < tol + @test abs(f3[[1=>5]] - f3[[5]]) < tol + @test abs(f3[[1=>6]] - f3[[6]]) < tol + @test abs(f3[[1=>7]] - f3[[7]]) < tol + @test abs(f3[[1=>8]] - f3[[8]]) < tol + @test abs(f3[[1=>9]] - f3[[9]]) < tol + @test abs(f3[[1=>10]] - f3[[10]]) < tol + + @test abs(f3[[2=>1]]- f3[[0,1]]) < tol + @test abs(f3[[2=>2]]- f3[[0,2]]) < tol + @test abs(f3[[2=>3]]- f3[[0,3]]) < tol + @test abs(f3[[2=>4]]- f3[[0,4]]) < tol + @test abs(f3[[2=>5]]- f3[[0,5]]) < tol + @test abs(f3[[2=>6]]- f3[[0,6]]) < tol + @test abs(f3[[2=>7]]- f3[[0,7]]) < tol + @test abs(f3[[2=>8]]- f3[[0,8]]) < tol + @test abs(f3[[2=>9]]- f3[[0,9]]) < tol + @test abs(f3[[2=>10]]- f3[[0,10]]) < tol + + @test abs(f3[params=[1=>1]] - f3[[0,0,0,1]]) < tol + @test abs(f3[params=[1=>2]] - f3[[0,0,0,2]]) < tol + @test abs(f3[params=[1=>3]] - f3[[0,0,0,3]]) < tol + @test abs(f3[params=[1=>4]] - f3[[0,0,0,4]]) < tol + @test abs(f3[params=[1=>5]] - f3[[0,0,0,5]]) < tol + @test abs(f3[params=[1=>6]] - f3[[0,0,0,6]]) < tol + @test abs(f3[params=[1=>7]] - f3[[0,0,0,7]]) < tol + @test abs(f3[params=[1=>8]] - f3[[0,0,0,8]]) < tol + @test abs(f3[params=[1=>9]] - f3[[0,0,0,9]]) < tol + @test abs(f3[params=[1=>10]] - f3[[0,0,0,10]]) < tol @@ -1037,7 +1037,7 @@ end @testset "@FastGTPSA - Functions: identities, using TPSs" begin d = Descriptor(1, 5) t = TPS(use=d) - t[0] = 0.5; t[1] = 2; t[2] = 3; t[3] = 4; t[4] = 5; t[5] = 6 + t[0] = 0.5; t[[1]] = 2; t[[2]] = 3; t[[3]] = 4; t[[4]] = 5; t[[5]] = 6 tol = 1e-10 @@ -1094,7 +1094,7 @@ end @test @FastGTPSA(norm(complex(t,t) - (t+im*t))) < tol t = ComplexTPS(t) - t[0] = 0.5+0.5im; t[1] = 2+2im; t[2] = 3+3im; t[3] = 4+4im; t[4] = 5+5im; t[5] = 6+6im + t[0] = 0.5+0.5im; t[[1]] = 2+2im; t[[2]] = 3+3im; t[[3]] = 4+4im; t[[4]] = 5+5im; t[[5]] = 6+6im @test @FastGTPSA(norm(sin(t)^2+cos(t)^2 - 1)) < tol @test @FastGTPSA(norm(1/sin(t) - csc(t))) < tol @test @FastGTPSA(norm(1/cos(t) - sec(t))) < tol diff --git a/test/type_stable.jl b/test/type_stable.jl index 4d5d2abd..c6c80a79 100644 --- a/test/type_stable.jl +++ b/test/type_stable.jl @@ -131,88 +131,89 @@ function type_stable_test() # Now do operators # Test definition of 1-norm: tn = zero(t1) - tn[0] = 1; tn[1] = 2; tn[2] = 3; tn[3] = 4; tn[4] = 5; tn[5] = 6 + tn[0] = 1; tn[[1]] = 2; tn[[2]] = 3; tn[[3]] = 4; tn[[4]] = 5; tn[[5]] = 6 tcn = zero(ct1) - tcn[0] = 1+1im; tcn[1] = 2+2im; tcn[2] = 3+3im; tcn[3] = 4+4im; tcn[4] = 5+5im; tcn[5] = 6+6im + tcn[0] = 1+1im; tcn[[1]] = 2+2im; tcn[[2]] = 3+3im; tcn[[3]] = 4+4im; tcn[[4]] = 5+5im; tcn[[5]] = 6+6im + norm(tn) == sum([i for i in 1:6]) norm(tcn) == sum([abs(i+i*im) for i in 1:6]) # TPS: - norm(t1 + t2 - t3) - norm(t2 + t1 - t3) - norm(t1 + 2 - t3) - norm(2 + t1 - t3) - norm(t3 - t2 - t1) - norm(t2 - t3 - -t1) - norm(t3 - 2 - t1) - norm(2 - t3 - -t1) - norm(t2 * t3 - 6) - norm(t3 * t2 - 6) - norm(t2 * 5 - 10) - norm(5 * t2 - 10 * t1) - norm(t1 / t2 - 1/2) - norm(t2 / t1 - 2) - norm(1 / t2 - 1/2) - norm(t2 / 3 - 2/3) - norm(t2 / t2 - t1) - norm(t2 / t2 - 1) - norm(t2 ^ t3 - 8) - norm(t3 ^ t2 - 9) - norm(t2 ^ 3 - 8) - norm(t2 ^ (1/2) - sqrt(2)) - norm(t2 ^ (1/2) - sqrt(t2)) - norm(2 ^ t3 - 8) - norm(inv(t3) - 1/t3) - norm(inv(t3) - 1/3) + norm(t1 + t2 - t3) < tol + norm(t2 + t1 - t3) < tol + norm(t1 + 2 - t3) < tol + norm(2 + t1 - t3) < tol + norm(t3 - t2 - t1) < tol + norm(t2 - t3 - -t1) < tol + norm(t3 - 2 - t1) < tol + norm(2 - t3 - -t1) < tol + norm(t2 * t3 - 6) < tol + norm(t3 * t2 - 6) < tol + norm(t2 * 5 - 10) < tol + norm(5 * t2 - 10 * t1) < tol + norm(t1 / t2 - 1/2) < tol + norm(t2 / t1 - 2) < tol + norm(1 / t2 - 1/2) < tol + norm(t2 / 3 - 2/3) < tol + norm(t2 / t2 - t1) < tol + norm(t2 / t2 - 1) < tol + norm(t2 ^ t3 - 8) < tol + norm(t3 ^ t2 - 9) < tol + norm(t2 ^ 3 - 8) < tol + norm(t2 ^ (1/2) - sqrt(2)) < tol + norm(t2 ^ (1/2) - sqrt(t2)) < tol + norm(2 ^ t3 - 8) < tol + norm(inv(t3) - 1/t3) < tol + norm(inv(t3) - 1/3) < tol # ComplexTPS: - norm(ct1 + ct2 - ct3) - norm(ct2 + ct1 - ct3) - norm(ct1 + (2+2im) - ct3) - norm((2+2im) + ct1 - ct3) - norm(ct3 - ct2 - ct1) - norm(ct2 - ct3 - -ct1) - norm(ct3 - (2+2im) - ct1) - norm((2+2im) - ct3 - -ct1) - norm(ct2 * ct3 - (2+2im)*(3+3im)) - norm(ct3 * ct2 - (2+2im)*(3+3im)) - norm(ct2 * 5 - (10+10im)) - norm(5 * ct2 - (10 * ct1)) - norm(ct1 / ct2 - (1+im)/(2+2im)) - norm(ct2 / ct1 - 2) - norm(1 / ct2 - 1/(2+2im)) - norm(ct2 / 3 - (2+2im)/3) - norm(ct2 / ct2 - 1) - norm(ct2 ^ ct3 - (2+2im)^(3+3im)) - norm(ct3 ^ ct2 - (3+3im)^(2+2im)) - norm(ct2 ^ 3 - (2+2im)^3) - norm(ct2 ^ (1/2) - sqrt(2+2im)) - norm(ct2 ^ (1/2) - sqrt(ct2)) - norm(2 ^ ct3 - 2^(3+3im)) - norm(inv(ct3) - 1/ct3) - norm(inv(ct3) - 1/(3+3im)) + norm(ct1 + ct2 - ct3) < tol + norm(ct2 + ct1 - ct3) < tol + norm(ct1 + (2+2im) - ct3) < tol + norm((2+2im) + ct1 - ct3) < tol + norm(ct3 - ct2 - ct1) < tol + norm(ct2 - ct3 - -ct1) < tol + norm(ct3 - (2+2im) - ct1) < tol + norm((2+2im) - ct3 - -ct1) < tol + norm(ct2 * ct3 - (2+2im)*(3+3im)) < tol + norm(ct3 * ct2 - (2+2im)*(3+3im)) < tol + norm(ct2 * 5 - (10+10im)) < tol + norm(5 * ct2 - (10 * ct1)) < tol + norm(ct1 / ct2 - (1+im)/(2+2im)) < tol + norm(ct2 / ct1 - 2) < tol + norm(1 / ct2 - 1/(2+2im)) < tol + norm(ct2 / 3 - (2+2im)/3) < tol + norm(ct2 / ct2 - 1) < tol + norm(ct2 ^ ct3 - (2+2im)^(3+3im)) < tol + norm(ct3 ^ ct2 - (3+3im)^(2+2im)) < tol + norm(ct2 ^ 3 - (2+2im)^3) < tol + norm(ct2 ^ (1/2) - sqrt(2+2im)) < tol + norm(ct2 ^ (1/2) - sqrt(ct2)) < tol + norm(2 ^ ct3 - 2^(3+3im)) < tol + norm(inv(ct3) - 1/ct3) < tol + norm(inv(ct3) - 1/(3+3im)) < tol # Promotion of TPS to ComplexTPS - norm(t1 + ct2 - (1 + (2+2im))) - norm(ct2 + t1 - (1 + (2+2im))) - norm(t1 + (2+2im) - (1 + (2+2im))) - norm((2+2im) + t1 - (1 + (2+2im))) - norm(t3 - ct2 - (3 - (2+2im))) - norm(ct2 - t3 - ((2+2im) - 3)) - norm(t3 - (2+2im) - (3 - (2+2im))) - norm((2+2im) - t3 - ((2+2im) - 3)) - norm(t2 * ct3 - 2 * (3+3im)) - norm(ct3 * t2 - 2 * (3+3im)) - norm(t2 * (3+3im) - 2 * (3+3im)) - norm((3+3im) * t2 - 2 * (3+3im)) - norm(t2 / ct3 - 2/(3+3im)) - norm(ct3 / t2 - (3+3im)/2) - norm(t2 / (3+3im) - 2/(3+3im)) - norm((3+3im) / t2 - (3+3im)/2) - norm(t2 ^ ct3 - 2^(3+3im)) - norm(ct3 ^ t2 - (3+3im)^2) - norm(t2 ^ (3+3im) - 2^(3+3im)) - norm((3+3im)^t2 - (3+3im)^2) + norm(t1 + ct2 - (1 + (2+2im))) < tol + norm(ct2 + t1 - (1 + (2+2im))) < tol + norm(t1 + (2+2im) - (1 + (2+2im))) < tol + norm((2+2im) + t1 - (1 + (2+2im))) < tol + norm(t3 - ct2 - (3 - (2+2im))) < tol + norm(ct2 - t3 - ((2+2im) - 3)) < tol + norm(t3 - (2+2im) - (3 - (2+2im))) < tol + norm((2+2im) - t3 - ((2+2im) - 3)) < tol + norm(t2 * ct3 - 2 * (3+3im)) < tol + norm(ct3 * t2 - 2 * (3+3im)) < tol + norm(t2 * (3+3im) - 2 * (3+3im)) < tol + norm((3+3im) * t2 - 2 * (3+3im)) < tol + norm(t2 / ct3 - 2/(3+3im)) < tol + norm(ct3 / t2 - (3+3im)/2) < tol + norm(t2 / (3+3im) - 2/(3+3im)) < tol + norm((3+3im) / t2 - (3+3im)/2) < tol + norm(t2 ^ ct3 - 2^(3+3im)) < tol + norm(ct3 ^ t2 - (3+3im)^2) < tol + norm(t2 ^ (3+3im) - 2^(3+3im)) < tol + norm((3+3im)^t2 - (3+3im)^2) < tol d = Descriptor(1, 5) t = TPS(use=d) @@ -227,75 +228,78 @@ function type_stable_test() t3[0] = 3 - norm(abs(-t) - abs(-v) ) - norm(sqrt(t) - sqrt(v)) - norm(exp(t) - exp(v)) - norm(log(t) - log(v)) - norm(sin(t) - sin(v)) - norm(cos(t) - cos(v)) - norm(tan(t) - tan(v)) - norm(csc(t) - csc(v)) - norm(sec(t) - sec(v)) - norm(cot(t) - cot(v)) - norm(sinc(t) - sinc(v)) - norm(sinh(t) - sinh(v)) - norm(cosh(t) - cosh(v)) - norm(tanh(t) - tanh(v)) - norm(csch(t) - csch(v)) - norm(sech(t) - sech(v)) - norm(coth(t) - coth(v)) - norm(asin(t) - asin(v)) - norm(acos(t) - acos(v)) - norm(atan(t) - atan(v)) - norm(acsc(1/t) - acsc(1/v)) - norm(asec(1/t) - asec(1/v)) - norm(acot(1/t) - acot(1/v)) - norm(asinh(t) - asinh(v)) - norm(acosh(1/t) - acosh(1/v)) - norm(atanh(t) - atanh(v)) - norm(acsch(1/t) - acsch(1/v)) - norm(asech(t) - asech(v)) - norm(acoth(1/t) - acoth(1/v)) - norm(asinc(t/pi) - asin(v)/(v)) - norm(asinhc(t/pi) - asinh(v)/(v)) - norm(zero(t) - zero(v)) - norm(real(t) - real(v)) - norm(imag(t) - imag(v)) - norm(conj(t) - conj(v)) - norm(sinhc(t/pi) - sinh(v)/v) - norm(erf(t) - erf(v)) - norm(erfc(t) - erfc(v)) - norm(-im*erf(t*im) - erfi(v)) - norm(atan(t3,t2) - atan(3,2)) - norm(atan(t3,2) - atan(3,2)) - norm(atan(3,t2) - atan(3,2)) - norm(atan(t3,-t2) - atan(3,-2)) - norm(atan(t3,-2) - atan(3,-2)) - norm(atan(3,-t2) - atan(3,-2)) - norm(atan(-t3,-t2) - atan(-3,-2)) - norm(atan(-t3,-2) - atan(-3,-2)) - norm(atan(-3,-t2) - atan(-3,-2)) - norm(atan(-t3,t2) - atan(-3,2)) - norm(atan(-t3,2) - atan(-3,2)) - norm(atan(-3,t2) - atan(-3,2)) - norm(hypot(t2,t3) - hypot(2,3)) - norm(hypot(2,t3) - hypot(2,3)) - norm(hypot(t2,3) - hypot(2,3)) - norm(hypot(t1,t2,t3) - hypot(1,2,3)) - norm(hypot(1, t2, t3) - hypot(1,2,3)) - norm(hypot(t1, 2, t3) - hypot(1,2,3)) - norm(hypot(t1, t2, 3) - hypot(1,2,3)) - norm(hypot(1, 2, t3) - hypot(1,2,3)) - norm(hypot(1, t2, 3) - hypot(1,2,3)) - norm(hypot(t1, 2, 3) - hypot(1,2,3)) - norm(angle(t2) - angle(2)) - norm(angle(-t2) - angle(-2)) - norm(complex(t3) - complex(3)) - norm(complex(t2,t3) - complex(2,3)) - norm(polar(t2) - (abs(2)+im*atan(0,2))) - norm(polar(-t1) - (abs(-1)+im*atan(0,-1))) - norm(rect(t2) - (2*cos(0) + 2*sin(0))) - norm(rect(-t1) - (-1*cos(0) + -1*sin(0))) + norm(abs(-t) - abs(-v) ) < tol + norm(sqrt(t) - sqrt(v)) < tol + norm(exp(t) - exp(v)) < tol + norm(log(t) - log(v)) < tol + norm(sin(t) - sin(v)) < tol + norm(cos(t) - cos(v)) < tol + norm(tan(t) - tan(v)) < tol + norm(csc(t) - csc(v)) < tol + norm(sec(t) - sec(v)) < tol + norm(cot(t) - cot(v)) < tol + norm(sinc(t) - sinc(v)) < tol + norm(sinh(t) - sinh(v)) < tol + norm(cosh(t) - cosh(v)) < tol + norm(tanh(t) - tanh(v)) < tol + norm(csch(t) - csch(v)) < tol + norm(sech(t) - sech(v)) < tol + norm(coth(t) - coth(v)) < tol + norm(asin(t) - asin(v)) < tol + norm(acos(t) - acos(v)) < tol + norm(atan(t) - atan(v)) < tol + norm(acsc(1/t) - acsc(1/v)) < tol + norm(asec(1/t) - asec(1/v)) < tol + norm(acot(1/t) - acot(1/v)) < tol + norm(asinh(t) - asinh(v)) < tol + norm(acosh(1/t) - acosh(1/v)) < tol + norm(atanh(t) - atanh(v)) < tol + norm(acsch(1/t) - acsch(1/v)) < tol + norm(asech(t) - asech(v)) < tol + norm(acoth(1/t) - acoth(1/v)) < tol + norm(asinc(t/pi) - asin(v)/(v)) < tol + norm(asinhc(t/pi) - asinh(v)/(v)) < tol + norm(zero(t) - zero(v)) < tol + norm(real(t) - real(v)) < tol + norm(imag(t) - imag(v)) < tol + norm(conj(t) - conj(v)) < tol + norm(sinhc(t/pi) - sinh(v)/v) < tol + norm(erf(t) - erf(v)) < tol + norm(erfc(t) - erfc(v)) < tol + norm(-im*erf(t*im) - erfi(v)) < tol + + norm(atan(t3,t2) - atan(3,2)) < tol + norm(atan(t3,2) - atan(3,2)) < tol + norm(atan(3,t2) - atan(3,2)) < tol + norm(atan(t3,-t2) - atan(3,-2)) < tol + norm(atan(t3,-2) - atan(3,-2)) < tol + norm(atan(3,-t2) - atan(3,-2)) < tol + norm(atan(-t3,-t2) - atan(-3,-2)) < tol + norm(atan(-t3,-2) - atan(-3,-2)) < tol + norm(atan(-3,-t2) - atan(-3,-2)) < tol + norm(atan(-t3,t2) - atan(-3,2)) < tol + norm(atan(-t3,2) - atan(-3,2)) < tol + norm(atan(-3,t2) - atan(-3,2)) < tol + + norm(hypot(t2,t3) - hypot(2,3)) < tol + norm(hypot(2,t3) - hypot(2,3)) < tol + norm(hypot(t2,3) - hypot(2,3)) < tol + norm(hypot(t1,t2,t3) - hypot(1,2,3)) < tol + norm(hypot(1, t2, t3) - hypot(1,2,3)) < tol + norm(hypot(t1, 2, t3) - hypot(1,2,3)) < tol + norm(hypot(t1, t2, 3) - hypot(1,2,3)) < tol + norm(hypot(1, 2, t3) - hypot(1,2,3)) < tol + norm(hypot(1, t2, 3) - hypot(1,2,3)) < tol + norm(hypot(t1, 2, 3) - hypot(1,2,3)) < tol + norm(angle(t2) - angle(2)) < tol + norm(angle(-t2) - angle(-2)) < tol + norm(complex(t3) - complex(3)) < tol + norm(complex(t2,t3) - complex(2,3)) < tol + norm(polar(t2) - (abs(2)+im*atan(0,2))) < tol + norm(polar(-t1) - (abs(-1)+im*atan(0,-1))) < tol + norm(rect(t2) - (2*cos(0) + im*2*sin(0))) < tol + norm(rect(-t1) - (-1*cos(0) + im*-1*sin(0))) < tol + v = 0.5+0.5im t = ComplexTPS(t) @@ -306,196 +310,200 @@ function type_stable_test() ct2[0] = 2 + 2im ct3 = zero(ct1) ct3[0] = 3 + 3im - norm(abs(-t) - abs(-v) ) - norm(sqrt(t) - sqrt(v)) - norm(exp(t) - exp(v)) - norm(log(t) - log(v)) - norm(sin(t) - sin(v)) - norm(cos(t) - cos(v)) - norm(tan(t) - tan(v)) - norm(csc(t) - csc(v)) - norm(sec(t) - sec(v)) - norm(cot(t) - cot(v)) - norm(sinc(t) - sinc(v)) - norm(sinh(t) - sinh(v)) - norm(cosh(t) - cosh(v)) - norm(tanh(t) - tanh(v)) - norm(csch(t) - csch(v)) - norm(sech(t) - sech(v)) - norm(coth(t) - coth(v)) - norm(asin(t) - asin(v)) - norm(acos(t) - acos(v)) - norm(atan(t) - atan(v)) - norm(acsc(t) - acsc(v)) - norm(asec(t) - asec(v)) - norm(acot(t) - acot(v)) - norm(asinh(t) - asinh(v)) - norm(acosh(t) - acosh(v)) - norm(atanh(t) - atanh(v)) - norm(acsch(t) - acsch(v)) - norm(asech(t) - asech(v)) - norm(acoth(t) - acoth(v)) - norm(asinc(t) - asin(v)/v) - norm(asinhc(t) - asinh(v)/v) - norm(zero(t) - zero(v)) - norm(real(t) - real(v)) - norm(imag(t) - imag(v)) - norm(conj(t) - conj(v)) - norm(sinhc(t/pi) - sinh(v)/v) - norm(erf(t) - erf(v)) - norm(erfc(t) - erfc(v)) - norm(-im*erf(t*im) - erfi(v)) - norm(hypot(ct2,ct3) - hypot(2+2im,3+3im)) - norm(hypot(2+2im,ct3) - hypot(2+2im,3+3im)) - norm(hypot(ct2,3+3im) - hypot(2+2im,3+3im)) - norm(hypot(ct1,ct2,ct3) - hypot(1+1im,2+2im,3+3im)) - norm(hypot(1+1im, ct2, ct3) - hypot(1+1im,2+2im,3+3im)) - norm(hypot(ct1, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im)) - norm(hypot(ct1, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im)) - norm(hypot(1+1im, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im)) - norm(hypot(1+1im, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im)) - norm(hypot(ct1, 2+2im, 3+3im) - hypot(1+1im,2+2im,3+3im)) - norm(angle(t2+im*t3) - angle(2+3im)) - norm(angle(t2-im*t3) - angle(2-3im)) - norm(angle(-t2-im*t3) - angle(-2-3im)) - norm(angle(-t2+im*t3) - angle(-2+3im)) - norm(angle(ct2) - angle(2+2im)) - norm(angle(-ct2) - angle(-2-2im)) - norm(complex(ct3) - complex(3+3im)) - norm(polar(ct2) - (abs(2+2im)+im*angle(2+2im))) - norm(polar(-ct1) - (abs(-1-im)+im*angle(-1-im))) - norm(rect(ct2) - (2*cos(2) + 2*sin(2))) - norm(rect(-ct1) - (-1*cos(-1) + -1*sin(-1))) + norm(abs(-t) - abs(-v) ) < tol + norm(sqrt(t) - sqrt(v)) < tol + norm(exp(t) - exp(v)) < tol + norm(log(t) - log(v)) < tol + norm(sin(t) - sin(v)) < tol + norm(cos(t) - cos(v)) < tol + norm(tan(t) - tan(v)) < tol + norm(csc(t) - csc(v)) < tol + norm(sec(t) - sec(v)) < tol + norm(cot(t) - cot(v)) < tol + norm(sinc(t) - sinc(v)) < tol + norm(sinh(t) - sinh(v)) < tol + norm(cosh(t) - cosh(v)) < tol + norm(tanh(t) - tanh(v)) < tol + norm(csch(t) - csch(v)) < tol + norm(sech(t) - sech(v)) < tol + norm(coth(t) - coth(v)) < tol + + norm(asin(t) - asin(v)) < tol + norm(acos(t) - acos(v)) < tol + norm(atan(t) - atan(v)) < tol + norm(acsc(t) - acsc(v)) < tol + norm(asec(t) - asec(v)) < tol + norm(acot(t) - acot(v)) < tol + norm(asinh(t) - asinh(v)) < tol + norm(acosh(t) - acosh(v)) < tol + norm(atanh(t) - atanh(v)) < tol + norm(acsch(t) - acsch(v)) < tol + norm(asech(t) - asech(v)) < tol + norm(acoth(t) - acoth(v)) < tol + norm(asinc(t/pi) - asin(v)/v) < tol + norm(asinhc(t/pi) - asinh(v)/v) < tol + + norm(zero(t) - zero(v)) < tol + norm(real(t) - real(v)) < tol + norm(imag(t) - imag(v)) < tol + norm(conj(t) - conj(v)) < tol + norm(sinhc(t/pi) - sinh(v)/v) < tol + norm(erf(t) - erf(v)) < tol + norm(erfc(t) - erfc(v)) < tol + norm(-im*erf(t*im) - erfi(v)) < tol + norm(hypot(ct2,ct3) - hypot(2+2im,3+3im)) < tol + norm(hypot(2+2im,ct3) - hypot(2+2im,3+3im)) < tol + norm(hypot(ct2,3+3im) - hypot(2+2im,3+3im)) < tol + norm(hypot(ct1,ct2,ct3) - hypot(1+1im,2+2im,3+3im)) < tol + norm(hypot(1+1im, ct2, ct3) - hypot(1+1im,2+2im,3+3im)) < tol + norm(hypot(ct1, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im)) < tol + norm(hypot(ct1, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im)) < tol + norm(hypot(1+1im, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im)) < tol + norm(hypot(1+1im, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im)) < tol + norm(hypot(ct1, 2+2im, 3+3im) - hypot(1+1im,2+2im,3+3im)) < tol + + norm(angle(t2+im*t3) - angle(2+3im)) < tol + norm(angle(t2-im*t3) - angle(2-3im)) < tol + norm(angle(-t2-im*t3) - angle(-2-3im)) < tol + norm(angle(-t2+im*t3) - angle(-2+3im)) < tol + norm(angle(ct2) - angle(2+2im)) < tol + norm(angle(-ct2) - angle(-2-2im)) < tol + norm(complex(ct3) - complex(3+3im)) < tol + norm(polar(ct2) - (abs(2+2im)+im*angle(2+2im))) < tol + norm(polar(-ct1) - (abs(-1-im)+im*angle(-1-im))) < tol + norm(rect(ct2) - (2*cos(2) + im*2*sin(2))) < tol + norm(rect(-ct1) - (-1*cos(-1) + im*-1*sin(-1))) < tol + # Hypot, mixing TPS with ComplexTPS - norm(hypot(ct1, ct2, t3) - hypot(1+1im,2+2im,3)) - norm(hypot(ct1, t2, ct3) - hypot(1+1im,2,3+3im)) - norm(hypot(t1, ct2, ct3) - hypot(1,2+2im,3+3im)) - norm(hypot(ct1, t2, t3) - hypot(1+1im,2,3)) - norm(hypot(t1, ct2, t3) - hypot(1,2+2im,3)) - norm(hypot(t1, t2, ct3) - hypot(1,2,3+3im)) - norm(hypot(ct1,t2,3+3im) - hypot(1+1im,2,3+3im)) - norm(hypot(t1, ct2, 3+3im) - hypot(1,2+2im,3+3im)) - norm(hypot(ct1,2+2im,t3) - hypot(1+1im,2+2im,3)) - norm(hypot(t1,2+2im,ct3) - hypot(1,2+2im,3+3im)) - norm(hypot(1+1im,ct2,t3) - hypot(1+1im,2+2im,3)) - norm(hypot(1+1im, t2, ct3) - hypot(1+1im,2,3+3im)) - norm(hypot(t1,t2,3+3im) - hypot(1,2,3+3im)) - norm(hypot(t1,2+2im,t3) - hypot(1,2+2im,3)) - norm(hypot(1+1im,t2,t3) - hypot(1+1im,2,3)) - norm(hypot(t1,2,3+3im) - hypot(1,2,3+3im)) - norm(hypot(1,t2,3+3im) - hypot(1,2,3+3im)) - norm(hypot(1+1im,2,t3) - hypot(1+1im,2,3)) + norm(hypot(ct1, ct2, t3) - hypot(1+1im,2+2im,3)) < tol + norm(hypot(ct1, t2, ct3) - hypot(1+1im,2,3+3im)) < tol + norm(hypot(t1, ct2, ct3) - hypot(1,2+2im,3+3im)) < tol + norm(hypot(ct1, t2, t3) - hypot(1+1im,2,3)) < tol + norm(hypot(t1, ct2, t3) - hypot(1,2+2im,3)) < tol + norm(hypot(t1, t2, ct3) - hypot(1,2,3+3im)) < tol + norm(hypot(ct1,t2,3+3im) - hypot(1+1im,2,3+3im)) < tol + norm(hypot(t1, ct2, 3+3im) - hypot(1,2+2im,3+3im)) < tol + norm(hypot(ct1,2+2im,t3) - hypot(1+1im,2+2im,3)) < tol + norm(hypot(t1,2+2im,ct3) - hypot(1,2+2im,3+3im)) < tol + norm(hypot(1+1im,ct2,t3) - hypot(1+1im,2+2im,3)) < tol + norm(hypot(1+1im, t2, ct3) - hypot(1+1im,2,3+3im)) < tol + norm(hypot(t1,t2,3+3im) - hypot(1,2,3+3im)) < tol + norm(hypot(t1,2+2im,t3) - hypot(1,2+2im,3)) < tol + norm(hypot(1+1im,t2,t3) - hypot(1+1im,2,3)) < tol + norm(hypot(t1,2,3+3im) - hypot(1,2,3+3im)) < tol + norm(hypot(1,t2,3+3im) - hypot(1,2,3+3im)) < tol + norm(hypot(1+1im,2,t3) - hypot(1+1im,2,3)) < tol d = Descriptor(1, 5) t = TPS(use=d) - t[0] = 0.5; t[1] = 2; t[2] = 3; t[3] = 4; t[4] = 5; t[5] = 6 + t[0] = 0.5; t[[1]] = 2; t[[2]] = 3; t[[3]] = 4; t[[4]] = 5; t[[5]] = 6 tol = 1e-10 - norm(sin(t)^2+cos(t)^2 - 1) - norm(1/sin(t) - csc(t)) - norm(1/cos(t) - sec(t)) - norm(1/tan(t) - cot(t)) - norm(sin(t)/cos(t) - tan(t)) - norm(cos(2*t) - cos(t)^2 + sin(t)^2) - norm(sec(t)^2 - 1 - tan(t)^2) - norm(sin(t/2) - sqrt((1-cos(t))/2)) - norm(cos(t/2) - sqrt((1+cos(t))/2)) - norm(sqrt(t^2) - abs(t)) - norm(csc(t)^2 - cot(t)^2 - 1) - norm(exp(log(t)) - t) - norm(log(exp(t)) - t) - norm(log(exp(t)) - exp(log(t))) - norm(log(t^2) - 2*log(t)) - norm(5*log(t) - log(t^5)) - norm(t*log(5) - log(5^t)) - norm(sinc(t) - sin(pi*t)/(pi*t)) - norm(sinhc(t/pi) - sinh(t)/t) - norm(exp(im*t) - cos(t) - im*sin(t)) - norm(real(exp(im*t)) - cos(t)) - norm(imag(exp(im*t)) - sin(t)) - norm(sinh(t) - (exp(t) - exp(-t))/2) - norm(cosh(t) - (exp(t) + exp(-t))/2) - norm(tanh(t) - sinh(t)/cosh(t)) - norm(csch(t) - 1/sinh(t)) - norm(sech(t) - 1/cosh(t)) - norm(coth(t) - cosh(t)/sinh(t)) - norm(coth(t) - 1/tanh(t)) - norm(cosh(t)^2 - sinh(t)^2 - 1) - norm(1 - tanh(t)^2 - sech(t)^2) - norm(coth(t)^2 - 1 - csch(t)^2) - norm(asin(sin(t)) - t) - norm(acos(cos(t)) - t) - norm(atan(tan(t)) - t) - norm(acsc(1/t) - asin(t)) - norm(asec(1/t) - acos(t)) - norm(acot(1/t) - atan(t)) - norm(asinh(sinh(t)) - t) - norm(acosh(cosh(t)) - t) - norm(atanh(tanh(t)) - t) - norm(acsch(t) - asinh(1/t)) - norm(asech(t) - acosh(1/t)) - norm(acoth(1/t) - atanh(t)) - norm(asinc(t/pi) - asin(t)/t) - norm(asinhc(t/pi) - asinh(t)/t) - norm(erfc(t) - 1 + erf(t)) - norm(erf(-t) + erf(t)) - norm(angle(t)) - norm(complex(t) - t) - norm(complex(t,t) - (t+im*t)) + norm(sin(t)^2+cos(t)^2 - 1) < tol + norm(1/sin(t) - csc(t)) < tol + norm(1/cos(t) - sec(t)) < tol + norm(1/tan(t) - cot(t)) < tol + norm(sin(t)/cos(t) - tan(t)) < tol + norm(cos(2*t) - cos(t)^2 + sin(t)^2) < tol + norm(sec(t)^2 - 1 - tan(t)^2) < tol + norm(sin(t/2) - sqrt((1-cos(t))/2)) < tol + norm(cos(t/2) - sqrt((1+cos(t))/2)) < tol + norm(sqrt(t^2) - abs(t)) < tol + norm(csc(t)^2 - cot(t)^2 - 1) < tol + norm(exp(log(t)) - t) < tol + norm(log(exp(t)) - t) < tol + norm(log(exp(t)) - exp(log(t))) < tol + norm(log(t^2) - 2*log(t)) < tol + norm(5*log(t) - log(t^5)) < tol + norm(t*log(5) - log(5^t)) < tol + norm(sinc(t) - sin(pi*t)/(pi*t)) < tol + norm(sinhc(t/pi) - sinh(t)/t) < tol + norm(exp(im*t) - cos(t) - im*sin(t)) < tol + norm(real(exp(im*t)) - cos(t)) < tol + norm(imag(exp(im*t)) - sin(t)) < tol + norm(sinh(t) - (exp(t) - exp(-t))/2) < tol + norm(cosh(t) - (exp(t) + exp(-t))/2) < tol + norm(tanh(t) - sinh(t)/cosh(t)) < tol + norm(csch(t) - 1/sinh(t)) < tol + norm(sech(t) - 1/cosh(t)) < tol + norm(coth(t) - cosh(t)/sinh(t)) < tol + norm(coth(t) - 1/tanh(t)) < tol + norm(cosh(t)^2 - sinh(t)^2 - 1) < tol + norm(1 - tanh(t)^2 - sech(t)^2) < tol + norm(coth(t)^2 - 1 - csch(t)^2) < tol + norm(asin(sin(t)) - t) < tol + norm(acos(cos(t)) - t) < tol + norm(atan(tan(t)) - t) < tol + norm(acsc(1/t) - asin(t)) < tol + norm(asec(1/t) - acos(t)) < tol + norm(acot(1/t) - atan(t)) < tol + norm(asinh(sinh(t)) - t) < tol + norm(acosh(cosh(t)) - t) < tol + norm(atanh(tanh(t)) - t) < tol + norm(acsch(t) - asinh(1/t)) < tol + norm(asech(t) - acosh(1/t)) < tol + norm(acoth(1/t) - atanh(t)) < tol + norm(asinc(t/pi) - asin(t)/t) < tol + norm(asinhc(t/pi) - asinh(t)/t) < tol + norm(erfc(t) - 1 + erf(t)) < tol + norm(erf(-t) + erf(t)) < tol + norm(angle(t)) < tol + norm(complex(t) - t) < tol + norm(complex(t,t) - (t+im*t)) < tol t = ComplexTPS(t) - t[0] = 0.5+0.5im; t[1] = 2+2im; t[2] = 3+3im; t[3] = 4+4im; t[4] = 5+5im; t[5] = 6+6im - norm(sin(t)^2+cos(t)^2 - 1) - norm(1/sin(t) - csc(t)) - norm(1/cos(t) - sec(t)) - norm(1/tan(t) - cot(t)) - norm(sin(t)/cos(t) - tan(t)) - norm(cos(2*t) - cos(t)^2 + sin(t)^2) - norm(sec(t)^2 - 1 - tan(t)^2) - norm(sin(t/2) - sqrt((1-cos(t))/2)) - norm(cos(t/2) - sqrt((1+cos(t))/2)) - norm(sqrt(t^2) - t) - norm(csc(t)^2 - cot(t)^2 - 1) - norm(exp(log(t)) - t) - norm(log(exp(t)) - t) - norm(log(exp(t)) - exp(log(t))) - norm(log(t^2) - 2*log(t)) - norm(5*log(t) - log(t^5) - 2*pi*im) - norm(t*log(5) - log(5^t)) - norm(sinc(t/pi) - sin(t)/t) - norm(sinhc(t/pi) - sinh(t)/t) - norm(exp(im*t) - cos(t) - im*sin(t)) - norm(sinh(t) - (exp(t) - exp(-t))/2) - norm(cosh(t) - (exp(t) + exp(-t))/2) - norm(tanh(t) - sinh(t)/cosh(t)) - norm(csch(t) - 1/sinh(t)) - norm(sech(t) - 1/cosh(t)) - norm(coth(t) - cosh(t)/sinh(t)) - norm(coth(t) - 1/tanh(t)) - norm(cosh(t)^2 - sinh(t)^2 - 1) - norm(1 - tanh(t)^2 - sech(t)^2) - norm(coth(t)^2 - 1 - csch(t)^2) - - norm(asin(sin(t)) - t) - norm(acos(cos(t)) - t) - norm(atan(tan(t)) - t) - norm(acsc(t) - asin(1/t)) - norm(asec(t) - acos(1/t)) - norm(acot(t) - acot(1/t)) - norm(asinh(sinh(t)) - t) - norm(acosh(cosh(t)) - t) - norm(atanh(tanh(t)) - t) - norm(acsch(t) - asinh(1/t)) - norm(asech(t) - acosh(1/t)) - norm(acoth(t) - acoth(1/t)) - norm(asinc(t) - asin(t)/t) - norm(asinhc(t) - asinh(t)/t) - - norm(erfc(t) - 1 + erf(t)) - norm(erf(-t) + erf(t)) - norm(angle(t) - atan(imag(t),real(t))) - norm(complex(t) - t) + t[0] = 0.5+0.5im; t[[1]] = 2+2im; t[[2]] = 3+3im; t[[3]] = 4+4im; t[[4]] = 5+5im; t[[5]] = 6+6im + norm(sin(t)^2+cos(t)^2 - 1) < tol + norm(1/sin(t) - csc(t)) < tol + norm(1/cos(t) - sec(t)) < tol + norm(1/tan(t) - cot(t)) < tol + norm(sin(t)/cos(t) - tan(t)) < tol + norm(cos(2*t) - cos(t)^2 + sin(t)^2) < tol + norm(sec(t)^2 - 1 - tan(t)^2) < tol + norm(sin(t/2) - sqrt((1-cos(t))/2)) < tol + norm(cos(t/2) - sqrt((1+cos(t))/2)) < tol + norm(sqrt(t^2) - t) < tol + norm(csc(t)^2 - cot(t)^2 - 1) < tol + norm(exp(log(t)) - t) < tol + norm(log(exp(t)) - t) < tol + norm(log(exp(t)) - exp(log(t))) < tol + norm(log(t^2) - 2*log(t)) < tol + norm(5*log(t) - log(t^5) - 2*pi*im) < tol + norm(t*log(5) - log(5^t)) < tol + norm(sinc(t/pi) - sin(t)/t) < tol + norm(sinhc(t/pi) - sinh(t)/t) < tol + norm(exp(im*t) - cos(t) - im*sin(t)) < tol + norm(sinh(t) - (exp(t) - exp(-t))/2) < tol + norm(cosh(t) - (exp(t) + exp(-t))/2) < tol + norm(tanh(t) - sinh(t)/cosh(t)) < tol + norm(csch(t) - 1/sinh(t)) < tol + norm(sech(t) - 1/cosh(t)) < tol + norm(coth(t) - cosh(t)/sinh(t)) < tol + norm(coth(t) - 1/tanh(t)) < tol + norm(cosh(t)^2 - sinh(t)^2 - 1) < tol + norm(1 - tanh(t)^2 - sech(t)^2) < tol + norm(coth(t)^2 - 1 - csch(t)^2) < tol + + norm(asin(sin(t)) - t) < tol + norm(acos(cos(t)) - t) < tol + norm(atan(tan(t)) - t) < tol + norm(acsc(t) - asin(1/t)) < tol + norm(asec(t) - acos(1/t)) < tol + norm(acot(t) - atan(1/t)) < tol + norm(asinh(sinh(t)) - t) < tol + norm(acosh(cosh(t)) - t) < tol + norm(atanh(tanh(t)) - t) < tol + norm(acsch(t) - asinh(1/t)) < tol + norm(asech(t) - acosh(1/t)) < tol + norm(acoth(t) - atanh(1/t)) < tol + norm(asinc(t/pi) - asin(t)/t) < tol + norm(asinhc(t/pi) - asinh(t)/t) < tol + + norm(erfc(t) - 1 + erf(t)) < tol + norm(erf(-t) + erf(t)) < tol + norm(angle(t) - atan(imag(t),real(t))) < tol + norm(complex(t) - t) < tol d = Descriptor(3,10,2,10) v = vars(d) @@ -503,216 +511,216 @@ function type_stable_test() tol = 1e-18 f = sin(v[1]) - abs(f[0] - 0) - abs(f[1] - 1) - abs(f[2] - 0) - abs(f[3] - -1/factorial(3)) - abs(f[4] - 0) - abs(f[5] - 1/factorial(5)) - abs(f[6] - 0) - abs(f[7] - -1/factorial(7)) - abs(f[8] - 0) - abs(f[9] - 1/factorial(9)) - abs(f[10] - 0) - - abs(f[1=>1] - f[1]) - abs(f[1=>2] - f[2]) - abs(f[1=>3] - f[3]) - abs(f[1=>4] - f[4]) - abs(f[1=>5] - f[5]) - abs(f[1=>6] - f[6]) - abs(f[1=>7] - f[7]) - abs(f[1=>8] - f[8]) - abs(f[1=>9] - f[9]) - abs(f[1=>10] - f[10]) + abs(f[[0]] - 0) < tol + abs(f[[1]] - 1) < tol + abs(f[[2]] - 0) < tol + abs(f[[3]] - -1/factorial(3)) < tol + abs(f[[4]] - 0) < tol + abs(f[[5]] - 1/factorial(5)) < tol + abs(f[[6]] - 0) < tol + abs(f[[7]] - -1/factorial(7)) < tol + abs(f[[8]] - 0) < tol + abs(f[[9]] - 1/factorial(9)) < tol + abs(f[[10]] - 0) < tol + + abs(f[[1=>1]] - f[[1]]) < tol + abs(f[[1=>2]] - f[[2]]) < tol + abs(f[[1=>3]] - f[[3]]) < tol + abs(f[[1=>4]] - f[[4]]) < tol + abs(f[[1=>5]] - f[[5]]) < tol + abs(f[[1=>6]] - f[[6]]) < tol + abs(f[[1=>7]] - f[[7]]) < tol + abs(f[[1=>8]] - f[[8]]) < tol + abs(f[[1=>9]] - f[[9]]) < tol + abs(f[[1=>10]] - f[[10]]) < tol fc = complex(f) - abs(fc[0] - 0) - abs(fc[1] - 1) - abs(fc[2] - 0) - abs(fc[3] - -1/factorial(3)) - abs(fc[4] - 0) - abs(fc[5] - 1/factorial(5)) - abs(fc[6] - 0) - abs(fc[7] - -1/factorial(7)) - abs(fc[8] - 0) - abs(fc[9] - 1/factorial(9)) - abs(fc[10] - 0) - - abs(fc[1=>1] - f[1]) - abs(fc[1=>2] - f[2]) - abs(fc[1=>3] - f[3]) - abs(fc[1=>4] - f[4]) - abs(fc[1=>5] - f[5]) - abs(fc[1=>6] - f[6]) - abs(fc[1=>7] - f[7]) - abs(fc[1=>8] - f[8]) - abs(fc[1=>9] - f[9]) - abs(fc[1=>10] - f[10]) + abs(fc[[0]] - 0) < tol + abs(fc[[1]] - 1) < tol + abs(fc[[2]] - 0) < tol + abs(fc[[3]] - -1/factorial(3)) < tol + abs(fc[[4]] - 0) < tol + abs(fc[[5]] - 1/factorial(5)) < tol + abs(fc[[6]] - 0) < tol + abs(fc[[7]] - -1/factorial(7)) < tol + abs(fc[[8]] - 0) < tol + abs(fc[[9]] - 1/factorial(9)) < tol + abs(fc[[10]] - 0) < tol + + abs(fc[[1=>1]] - f[[1]]) < tol + abs(fc[[1=>2]] - f[[2]]) < tol + abs(fc[[1=>3]] - f[[3]]) < tol + abs(fc[[1=>4]] - f[[4]]) < tol + abs(fc[[1=>5]] - f[[5]]) < tol + abs(fc[[1=>6]] - f[[6]]) < tol + abs(fc[[1=>7]] - f[[7]]) < tol + abs(fc[[1=>8]] - f[[8]]) < tol + abs(fc[[1=>9]] - f[[9]]) < tol + abs(fc[[1=>10]] - f[[10]]) < tol f2 = sin(v[1]) + cos(v[2]) - abs(f2[0] - 1) - abs(f2[1] - 1) - abs(f2[2] - 0) - abs(f2[3] - -1/factorial(3)) - abs(f2[4] - 0) - abs(f2[5] - 1/factorial(5)) - abs(f2[6] - 0) - abs(f2[7] - -1/factorial(7)) - abs(f2[8] - 0) - abs(f2[9] - 1/factorial(9)) - abs(f2[10] - 0) - - abs(f2[0,0] - 1) - abs(f2[0,1] - 0) - abs(f2[0,2] - -1/factorial(2)) - abs(f2[0,3] - 0) - abs(f2[0,4] - 1/factorial(4)) - abs(f2[0,5] - 0) - abs(f2[0,6] - -1/factorial(6)) - abs(f2[0,7] - 0) - abs(f2[0,8] - 1/factorial(8)) - abs(f2[0,9] - 0) - abs(f2[0,10] - -1/factorial(10)) - - abs(f2[1=>1] - f2[1]) - abs(f2[1=>2] - f2[2]) - abs(f2[1=>3] - f2[3]) - abs(f2[1=>4] - f2[4]) - abs(f2[1=>5] - f2[5]) - abs(f2[1=>6] - f2[6]) - abs(f2[1=>7] - f2[7]) - abs(f2[1=>8] - f2[8]) - abs(f2[1=>9] - f2[9]) - abs(f2[1=>10] - f2[10]) - - abs(f2[2=>1] - f2[0,1]) - abs(f2[2=>2] - f2[0,2]) - abs(f2[2=>3] - f2[0,3]) - abs(f2[2=>4] - f2[0,4]) - abs(f2[2=>5] - f2[0,5]) - abs(f2[2=>6] - f2[0,6]) - abs(f2[2=>7] - f2[0,7]) - abs(f2[2=>8] - f2[0,8]) - abs(f2[2=>9] - f2[0,9]) - abs(f2[2=>10] - f2[0,10]) + abs(f2[[0]] - 1) < tol + abs(f2[[1]] - 1) < tol + abs(f2[[2]] - 0) < tol + abs(f2[[3]] - -1/factorial(3)) < tol + abs(f2[[4]] - 0) < tol + abs(f2[[5]] - 1/factorial(5)) < tol + abs(f2[[6]] - 0) < tol + abs(f2[[7]] - -1/factorial(7)) < tol + abs(f2[[8]] - 0) < tol + abs(f2[[9]] - 1/factorial(9)) < tol + abs(f2[[10]] - 0) < tol + + abs(f2[[0,0]] - 1) < tol + abs(f2[[0,1]] - 0) < tol + abs(f2[[0,2]] - -1/factorial(2)) < tol + abs(f2[[0,3]] - 0) < tol + abs(f2[[0,4]] - 1/factorial(4)) < tol + abs(f2[[0,5]] - 0) < tol + abs(f2[[0,6]] - -1/factorial(6)) < tol + abs(f2[[0,7]] - 0) < tol + abs(f2[[0,8]] - 1/factorial(8)) < tol + abs(f2[[0,9]] - 0) < tol + abs(f2[[0,10]] - -1/factorial(10)) < tol + + abs(f2[[1=>1]] - f2[[1]]) < tol + abs(f2[[1=>2]] - f2[[2]]) < tol + abs(f2[[1=>3]] - f2[[3]]) < tol + abs(f2[[1=>4]] - f2[[4]]) < tol + abs(f2[[1=>5]] - f2[[5]]) < tol + abs(f2[[1=>6]] - f2[[6]]) < tol + abs(f2[[1=>7]] - f2[[7]]) < tol + abs(f2[[1=>8]] - f2[[8]]) < tol + abs(f2[[1=>9]] - f2[[9]]) < tol + abs(f2[[1=>10]] - f2[[10]]) < tol + + abs(f2[[2=>1]] - f2[[0,1]]) < tol + abs(f2[[2=>2]] - f2[[0,2]]) < tol + abs(f2[[2=>3]] - f2[[0,3]]) < tol + abs(f2[[2=>4]] - f2[[0,4]]) < tol + abs(f2[[2=>5]] - f2[[0,5]]) < tol + abs(f2[[2=>6]] - f2[[0,6]]) < tol + abs(f2[[2=>7]] - f2[[0,7]]) < tol + abs(f2[[2=>8]] - f2[[0,8]]) < tol + abs(f2[[2=>9]] - f2[[0,9]]) < tol + abs(f2[[2=>10]] - f2[[0,10]]) < tol f2c = complex(sin(v[1]) + cos(v[2])) - abs(f2c[0] - 1) - abs(f2c[1] - 1) - abs(f2c[2] - 0) - abs(f2c[3] - -1/factorial(3)) - abs(f2c[4] - 0) - abs(f2c[5] - 1/factorial(5)) - abs(f2c[6] - 0) - abs(f2c[7] - -1/factorial(7)) - abs(f2c[8] - 0) - abs(f2c[9] - 1/factorial(9)) - abs(f2c[10] - 0) - - abs(f2c[0,0] - 1) - abs(f2c[0,1] - 0) - abs(f2c[0,2] - -1/factorial(2)) - abs(f2c[0,3] - 0) - abs(f2c[0,4] - 1/factorial(4)) - abs(f2c[0,5] - 0) - abs(f2c[0,6] - -1/factorial(6)) - abs(f2c[0,7] - 0) - abs(f2c[0,8] - 1/factorial(8)) - abs(f2c[0,9] - 0) - abs(f2c[0,10] - -1/factorial(10)) - - abs(f2c[1=>1] - f2c[1]) - abs(f2c[1=>2] - f2c[2]) - abs(f2c[1=>3] - f2c[3]) - abs(f2c[1=>4] - f2c[4]) - abs(f2c[1=>5] - f2c[5]) - abs(f2c[1=>6] - f2c[6]) - abs(f2c[1=>7] - f2c[7]) - abs(f2c[1=>8] - f2c[8]) - abs(f2c[1=>9] - f2c[9]) - abs(f2c[1=>10] - f2c[10]) - - abs(f2c[2=>1] - f2c[0,1]) - abs(f2c[2=>2] - f2c[0,2]) - abs(f2c[2=>3] - f2c[0,3]) - abs(f2c[2=>4] - f2c[0,4]) - abs(f2c[2=>5] - f2c[0,5]) - abs(f2c[2=>6] - f2c[0,6]) - abs(f2c[2=>7] - f2c[0,7]) - abs(f2c[2=>8] - f2c[0,8]) - abs(f2c[2=>9] - f2c[0,9]) - abs(f2c[2=>10] - f2c[0,10]) + abs(f2c[[0]] - 1) < tol + abs(f2c[[1]] - 1) < tol + abs(f2c[[2]] - 0) < tol + abs(f2c[[3]] - -1/factorial(3)) < tol + abs(f2c[[4]] - 0) < tol + abs(f2c[[5]] - 1/factorial(5)) < tol + abs(f2c[[6]] - 0) < tol + abs(f2c[[7]] - -1/factorial(7)) < tol + abs(f2c[[8]] - 0) < tol + abs(f2c[[9]] - 1/factorial(9)) < tol + abs(f2c[[10]] - 0) < tol + + abs(f2c[[0,0]] - 1) < tol + abs(f2c[[0,1]] - 0) < tol + abs(f2c[[0,2]] - -1/factorial(2)) < tol + abs(f2c[[0,3]] - 0) < tol + abs(f2c[[0,4]] - 1/factorial(4)) < tol + abs(f2c[[0,5]] - 0) < tol + abs(f2c[[0,6]] - -1/factorial(6)) < tol + abs(f2c[[0,7]] - 0) < tol + abs(f2c[[0,8]] - 1/factorial(8)) < tol + abs(f2c[[0,9]] - 0) < tol + abs(f2c[[0,10]] - -1/factorial(10)) < tol + + abs(f2c[[1=>1]] - f2c[[1]]) < tol + abs(f2c[[1=>2]] - f2c[[2]]) < tol + abs(f2c[[1=>3]] - f2c[[3]]) < tol + abs(f2c[[1=>4]] - f2c[[4]]) < tol + abs(f2c[[1=>5]] - f2c[[5]]) < tol + abs(f2c[[1=>6]] - f2c[[6]]) < tol + abs(f2c[[1=>7]] - f2c[[7]]) < tol + abs(f2c[[1=>8]] - f2c[[8]]) < tol + abs(f2c[[1=>9]] - f2c[[9]]) < tol + abs(f2c[[1=>10]] - f2c[[10]]) < tol + + abs(f2c[[2=>1]] - f2c[[0,1]]) < tol + abs(f2c[[2=>2]] - f2c[[0,2]]) < tol + abs(f2c[[2=>3]] - f2c[[0,3]]) < tol + abs(f2c[[2=>4]] - f2c[[0,4]]) < tol + abs(f2c[[2=>5]] - f2c[[0,5]]) < tol + abs(f2c[[2=>6]] - f2c[[0,6]]) < tol + abs(f2c[[2=>7]] - f2c[[0,7]]) < tol + abs(f2c[[2=>8]] - f2c[[0,8]]) < tol + abs(f2c[[2=>9]] - f2c[[0,9]]) < tol + abs(f2c[[2=>10]] - f2c[[0,10]]) < tol f3 = sin(v[1]) + cos(v[2]) + exp(p[1]) - abs(f3[0] - 2) - abs(f3[1] - 1) - abs(f3[2] - 0) - abs(f3[3] - -1/factorial(3)) - abs(f3[4] - 0) - abs(f3[5] - 1/factorial(5)) - abs(f3[6] - 0) - abs(f3[7] - -1/factorial(7)) - abs(f3[8] - 0) - abs(f3[9] - 1/factorial(9)) - abs(f3[10] - 0) - - abs(f3[0,0] - 2) - abs(f3[0,1] - 0) - abs(f3[0,2] - -1/factorial(2)) - abs(f3[0,3] - 0) - abs(f3[0,4] - 1/factorial(4)) - abs(f3[0,5] - 0) - abs(f3[0,6] - -1/factorial(6)) - abs(f3[0,7] - 0) - abs(f3[0,8] - 1/factorial(8)) - abs(f3[0,9] - 0) - abs(f3[0,10] - -1/factorial(10)) - - abs(f3[0,0,0,0] - 2) - abs(f3[0,0,0,1] - 1/factorial(1)) - abs(f3[0,0,0,2] - 1/factorial(2)) - abs(f3[0,0,0,3] - 1/factorial(3)) - abs(f3[0,0,0,4] - 1/factorial(4)) - abs(f3[0,0,0,5] - 1/factorial(5)) - abs(f3[0,0,0,6] - 1/factorial(6)) - abs(f3[0,0,0,7] - 1/factorial(7)) - abs(f3[0,0,0,8] - 1/factorial(8)) - abs(f3[0,0,0,9] - 1/factorial(9)) - abs(f3[0,0,0,10] - 1/factorial(10)) - - abs(f3[1=>1] - f3[1]) - abs(f3[1=>2] - f3[2]) - abs(f3[1=>3] - f3[3]) - abs(f3[1=>4] - f3[4]) - abs(f3[1=>5] - f3[5]) - abs(f3[1=>6] - f3[6]) - abs(f3[1=>7] - f3[7]) - abs(f3[1=>8] - f3[8]) - abs(f3[1=>9] - f3[9]) - abs(f3[1=>10] - f3[10]) - - abs(f3[2=>1] - f3[0,1]) - abs(f3[2=>2] - f3[0,2]) - abs(f3[2=>3] - f3[0,3]) - abs(f3[2=>4] - f3[0,4]) - abs(f3[2=>5] - f3[0,5]) - abs(f3[2=>6] - f3[0,6]) - abs(f3[2=>7] - f3[0,7]) - abs(f3[2=>8] - f3[0,8]) - abs(f3[2=>9] - f3[0,9]) - abs(f3[2=>10] - f3[0,10]) - - abs(f3[params=[1=>1]] - f3[0,0,0,1]) - abs(f3[params=[1=>2]] - f3[0,0,0,2]) - abs(f3[params=[1=>3]] - f3[0,0,0,3]) - abs(f3[params=[1=>4]] - f3[0,0,0,4]) - abs(f3[params=[1=>5]] - f3[0,0,0,5]) - abs(f3[params=[1=>6]] - f3[0,0,0,6]) - abs(f3[params=[1=>7]] - f3[0,0,0,7]) - abs(f3[params=[1=>8]] - f3[0,0,0,8]) - abs(f3[params=[1=>9]] - f3[0,0,0,9]) - abs(f3[params=[1=>10]] - f3[0,0,0,10]) + abs(f3[[0]] - 2) < tol + abs(f3[[1]] - 1) < tol + abs(f3[[2]] - 0) < tol + abs(f3[[3]] - -1/factorial(3)) < tol + abs(f3[[4]] - 0) < tol + abs(f3[[5]] - 1/factorial(5)) < tol + abs(f3[[6]] - 0) < tol + abs(f3[[7]] - -1/factorial(7)) < tol + abs(f3[[8]] - 0) < tol + abs(f3[[9]] - 1/factorial(9)) < tol + abs(f3[[10]] - 0) < tol + + abs(f3[[0,0]] - 2) < tol + abs(f3[[0,1]] - 0) < tol + abs(f3[[0,2]] - -1/factorial(2)) < tol + abs(f3[[0,3]] - 0) < tol + abs(f3[[0,4]] - 1/factorial(4)) < tol + abs(f3[[0,5]] - 0) < tol + abs(f3[[0,6]] - -1/factorial(6)) < tol + abs(f3[[0,7]] - 0) < tol + abs(f3[[0,8]] - 1/factorial(8)) < tol + abs(f3[[0,9]] - 0) < tol + abs(f3[[0,10]] - -1/factorial(10)) < tol + + abs(f3[[0,0,0,0]] - 2) < tol + abs(f3[[0,0,0,1]] - 1/factorial(1)) < tol + abs(f3[[0,0,0,2]] - 1/factorial(2)) < tol + abs(f3[[0,0,0,3]] - 1/factorial(3)) < tol + abs(f3[[0,0,0,4]] - 1/factorial(4)) < tol + abs(f3[[0,0,0,5]] - 1/factorial(5)) < tol + abs(f3[[0,0,0,6]] - 1/factorial(6)) < tol + abs(f3[[0,0,0,7]] - 1/factorial(7)) < tol + abs(f3[[0,0,0,8]] - 1/factorial(8)) < tol + abs(f3[[0,0,0,9]] - 1/factorial(9)) < tol + abs(f3[[0,0,0,10]] - 1/factorial(10)) < tol + + abs(f3[[1=>1]] - f3[[1]]) < tol + abs(f3[[1=>2]] - f3[[2]]) < tol + abs(f3[[1=>3]] - f3[[3]]) < tol + abs(f3[[1=>4]] - f3[[4]]) < tol + abs(f3[[1=>5]] - f3[[5]]) < tol + abs(f3[[1=>6]] - f3[[6]]) < tol + abs(f3[[1=>7]] - f3[[7]]) < tol + abs(f3[[1=>8]] - f3[[8]]) < tol + abs(f3[[1=>9]] - f3[[9]]) < tol + abs(f3[[1=>10]] - f3[[10]]) < tol + + abs(f3[[2=>1]]- f3[[0,1]]) < tol + abs(f3[[2=>2]]- f3[[0,2]]) < tol + abs(f3[[2=>3]]- f3[[0,3]]) < tol + abs(f3[[2=>4]]- f3[[0,4]]) < tol + abs(f3[[2=>5]]- f3[[0,5]]) < tol + abs(f3[[2=>6]]- f3[[0,6]]) < tol + abs(f3[[2=>7]]- f3[[0,7]]) < tol + abs(f3[[2=>8]]- f3[[0,8]]) < tol + abs(f3[[2=>9]]- f3[[0,9]]) < tol + abs(f3[[2=>10]]- f3[[0,10]]) < tol + + abs(f3[params=[1=>1]] - f3[[0,0,0,1]]) < tol + abs(f3[params=[1=>2]] - f3[[0,0,0,2]]) < tol + abs(f3[params=[1=>3]] - f3[[0,0,0,3]]) < tol + abs(f3[params=[1=>4]] - f3[[0,0,0,4]]) < tol + abs(f3[params=[1=>5]] - f3[[0,0,0,5]]) < tol + abs(f3[params=[1=>6]] - f3[[0,0,0,6]]) < tol + abs(f3[params=[1=>7]] - f3[[0,0,0,7]]) < tol + abs(f3[params=[1=>8]] - f3[[0,0,0,8]]) < tol + abs(f3[params=[1=>9]] - f3[[0,0,0,9]]) < tol + abs(f3[params=[1=>10]] - f3[[0,0,0,10]]) < tol d = Descriptor(1, 5) t = TPS(use=d) @@ -738,81 +746,81 @@ function type_stable_test() tol = 1e-14 # TPS: - @FastGTPSA(norm(t1 + t2 - t3)) - @FastGTPSA(norm(t2 + t1 - t3)) - @FastGTPSA(norm(t1 + 2 - t3)) - @FastGTPSA(norm(2 + t1 - t3)) - @FastGTPSA(norm(t3 - t2 - t1)) - @FastGTPSA(norm(t2 - t3 - -t1)) - @FastGTPSA(norm(t3 - 2 - t1)) - @FastGTPSA(norm(2 - t3 - -t1)) - @FastGTPSA(norm(t2 * t3 - 6)) - @FastGTPSA(norm(t3 * t2 - 6)) - @FastGTPSA(norm(t2 * 5 - 10)) - @FastGTPSA(norm(5 * t2 - 10 * t1)) - @FastGTPSA(norm(t1 / t2 - 1/2)) - @FastGTPSA(norm(t2 / t1 - 2)) - @FastGTPSA(norm(1 / t2 - 1/2)) - @FastGTPSA(norm(t2 / 3 - 2/3)) - @FastGTPSA(norm(t2 / t2 - t1)) - @FastGTPSA(norm(t2 / t2 - 1)) - @FastGTPSA(norm(t2 ^ t3 - 8)) - @FastGTPSA(norm(t3 ^ t2 - 9)) - @FastGTPSA(norm(t2 ^ 3 - 8)) - @FastGTPSA(norm(t2 ^ (1/2) - sqrt(2))) - @FastGTPSA(norm(t2 ^ (1/2) - sqrt(t2))) - @FastGTPSA(norm(2 ^ t3 - 8)) - @FastGTPSA(norm(inv(t3) - 1/t3)) - @FastGTPSA(norm(inv(t3) - 1/3)) + @FastGTPSA(norm(t1 + t2 - t3)) < tol + @FastGTPSA(norm(t2 + t1 - t3)) < tol + @FastGTPSA(norm(t1 + 2 - t3)) < tol + @FastGTPSA(norm(2 + t1 - t3)) < tol + @FastGTPSA(norm(t3 - t2 - t1)) < tol + @FastGTPSA(norm(t2 - t3 - -t1)) < tol + @FastGTPSA(norm(t3 - 2 - t1)) < tol + @FastGTPSA(norm(2 - t3 - -t1)) < tol + @FastGTPSA(norm(t2 * t3 - 6)) < tol + @FastGTPSA(norm(t3 * t2 - 6)) < tol + @FastGTPSA(norm(t2 * 5 - 10)) < tol + @FastGTPSA(norm(5 * t2 - 10 * t1)) < tol + @FastGTPSA(norm(t1 / t2 - 1/2)) < tol + @FastGTPSA(norm(t2 / t1 - 2)) < tol + @FastGTPSA(norm(1 / t2 - 1/2)) < tol + @FastGTPSA(norm(t2 / 3 - 2/3)) < tol + @FastGTPSA(norm(t2 / t2 - t1)) < tol + @FastGTPSA(norm(t2 / t2 - 1)) < tol + @FastGTPSA(norm(t2 ^ t3 - 8)) < tol + @FastGTPSA(norm(t3 ^ t2 - 9)) < tol + @FastGTPSA(norm(t2 ^ 3 - 8)) < tol + @FastGTPSA(norm(t2 ^ (1/2) - sqrt(2))) < tol + @FastGTPSA(norm(t2 ^ (1/2) - sqrt(t2))) < tol + @FastGTPSA(norm(2 ^ t3 - 8)) < tol + @FastGTPSA(norm(inv(t3) - 1/t3)) < tol + @FastGTPSA(norm(inv(t3) - 1/3)) < tol # ComplexTPS: - @FastGTPSA(norm(ct1 + ct2 - ct3)) - @FastGTPSA(norm(ct2 + ct1 - ct3)) - @FastGTPSA(norm(ct1 + (2+2im) - ct3)) - @FastGTPSA(norm((2+2im) + ct1 - ct3)) - @FastGTPSA(norm(ct3 - ct2 - ct1)) - @FastGTPSA(norm(ct2 - ct3 - -ct1)) - @FastGTPSA(norm(ct3 - (2+2im) - ct1)) - @FastGTPSA(norm((2+2im) - ct3 - -ct1)) - @FastGTPSA(norm(ct2 * ct3 - (2+2im)*(3+3im))) - @FastGTPSA(norm(ct3 * ct2 - (2+2im)*(3+3im))) - @FastGTPSA(norm(ct2 * 5 - (10+10im))) - @FastGTPSA(norm(5 * ct2 - (10 * ct1))) - @FastGTPSA(norm(ct1 / ct2 - (1+im)/(2+2im))) - @FastGTPSA(norm(ct2 / ct1 - 2)) - @FastGTPSA(norm(1 / ct2 - 1/(2+2im))) - @FastGTPSA(norm(ct2 / 3 - (2+2im)/3)) - @FastGTPSA(norm(ct2 / ct2 - 1)) - @FastGTPSA(norm(ct2 ^ ct3 - (2+2im)^(3+3im))) - @FastGTPSA(norm(ct3 ^ ct2 - (3+3im)^(2+2im))) - @FastGTPSA(norm(ct2 ^ 3 - (2+2im)^3)) - @FastGTPSA(norm(ct2 ^ (1/2) - sqrt(2+2im))) - @FastGTPSA(norm(ct2 ^ (1/2) - sqrt(ct2))) - @FastGTPSA(norm(2 ^ ct3 - 2^(3+3im))) - @FastGTPSA(norm(inv(ct3) - 1/ct3)) - @FastGTPSA(norm(inv(ct3) - 1/(3+3im))) + @FastGTPSA(norm(ct1 + ct2 - ct3)) < tol + @FastGTPSA(norm(ct2 + ct1 - ct3)) < tol + @FastGTPSA(norm(ct1 + (2+2im) - ct3)) < tol + @FastGTPSA(norm((2+2im) + ct1 - ct3)) < tol + @FastGTPSA(norm(ct3 - ct2 - ct1)) < tol + @FastGTPSA(norm(ct2 - ct3 - -ct1)) < tol + @FastGTPSA(norm(ct3 - (2+2im) - ct1)) < tol + @FastGTPSA(norm((2+2im) - ct3 - -ct1)) < tol + @FastGTPSA(norm(ct2 * ct3 - (2+2im)*(3+3im))) < tol + @FastGTPSA(norm(ct3 * ct2 - (2+2im)*(3+3im))) < tol + @FastGTPSA(norm(ct2 * 5 - (10+10im))) < tol + @FastGTPSA(norm(5 * ct2 - (10 * ct1))) < tol + @FastGTPSA(norm(ct1 / ct2 - (1+im)/(2+2im))) < tol + @FastGTPSA(norm(ct2 / ct1 - 2)) < tol + @FastGTPSA(norm(1 / ct2 - 1/(2+2im))) < tol + @FastGTPSA(norm(ct2 / 3 - (2+2im)/3)) < tol + @FastGTPSA(norm(ct2 / ct2 - 1)) < tol + @FastGTPSA(norm(ct2 ^ ct3 - (2+2im)^(3+3im))) < tol + @FastGTPSA(norm(ct3 ^ ct2 - (3+3im)^(2+2im))) < tol + @FastGTPSA(norm(ct2 ^ 3 - (2+2im)^3)) < tol + @FastGTPSA(norm(ct2 ^ (1/2) - sqrt(2+2im))) < tol + @FastGTPSA(norm(ct2 ^ (1/2) - sqrt(ct2))) < tol + @FastGTPSA(norm(2 ^ ct3 - 2^(3+3im))) < tol + @FastGTPSA(norm(inv(ct3) - 1/ct3)) < tol + @FastGTPSA(norm(inv(ct3) - 1/(3+3im))) < tol # Promotion of TPS to ComplexTPS - @FastGTPSA(norm(t1 + ct2 - (1 + (2+2im)))) - @FastGTPSA(norm(ct2 + t1 - (1 + (2+2im)))) - @FastGTPSA(norm(t1 + (2+2im) - (1 + (2+2im)))) - @FastGTPSA(norm((2+2im) + t1 - (1 + (2+2im)))) - @FastGTPSA(norm(t3 - ct2 - (3 - (2+2im)))) - @FastGTPSA(norm(ct2 - t3 - ((2+2im) - 3))) - @FastGTPSA(norm(t3 - (2+2im) - (3 - (2+2im)))) - @FastGTPSA(norm((2+2im) - t3 - ((2+2im) - 3))) - @FastGTPSA(norm(t2 * ct3 - 2 * (3+3im))) - @FastGTPSA(norm(ct3 * t2 - 2 * (3+3im))) - @FastGTPSA(norm(t2 * (3+3im) - 2 * (3+3im))) - @FastGTPSA(norm((3+3im) * t2 - 2 * (3+3im))) - @FastGTPSA(norm(t2 / ct3 - 2/(3+3im))) - @FastGTPSA(norm(ct3 / t2 - (3+3im)/2)) - @FastGTPSA(norm(t2 / (3+3im) - 2/(3+3im))) - @FastGTPSA(norm((3+3im) / t2 - (3+3im)/2)) - @FastGTPSA(norm(t2 ^ ct3 - 2^(3+3im))) - @FastGTPSA(norm(ct3 ^ t2 - (3+3im)^2)) - @FastGTPSA(norm(t2 ^ (3+3im) - 2^(3+3im))) - @FastGTPSA(norm((3+3im)^t2 - (3+3im)^2)) + @FastGTPSA(norm(t1 + ct2 - (1 + (2+2im)))) < tol + @FastGTPSA(norm(ct2 + t1 - (1 + (2+2im)))) < tol + @FastGTPSA(norm(t1 + (2+2im) - (1 + (2+2im)))) < tol + @FastGTPSA(norm((2+2im) + t1 - (1 + (2+2im)))) < tol + @FastGTPSA(norm(t3 - ct2 - (3 - (2+2im)))) < tol + @FastGTPSA(norm(ct2 - t3 - ((2+2im) - 3))) < tol + @FastGTPSA(norm(t3 - (2+2im) - (3 - (2+2im)))) < tol + @FastGTPSA(norm((2+2im) - t3 - ((2+2im) - 3))) < tol + @FastGTPSA(norm(t2 * ct3 - 2 * (3+3im))) < tol + @FastGTPSA(norm(ct3 * t2 - 2 * (3+3im))) < tol + @FastGTPSA(norm(t2 * (3+3im) - 2 * (3+3im))) < tol + @FastGTPSA(norm((3+3im) * t2 - 2 * (3+3im))) < tol + @FastGTPSA(norm(t2 / ct3 - 2/(3+3im))) < tol + @FastGTPSA(norm(ct3 / t2 - (3+3im)/2)) < tol + @FastGTPSA(norm(t2 / (3+3im) - 2/(3+3im))) < tol + @FastGTPSA(norm((3+3im) / t2 - (3+3im)/2)) < tol + @FastGTPSA(norm(t2 ^ ct3 - 2^(3+3im))) < tol + @FastGTPSA(norm(ct3 ^ t2 - (3+3im)^2)) < tol + @FastGTPSA(norm(t2 ^ (3+3im) - 2^(3+3im))) < tol + @FastGTPSA(norm((3+3im)^t2 - (3+3im)^2)) < tol # Make sure stack is 0: desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)) @@ -834,76 +842,78 @@ function type_stable_test() t3[0] = 3 - @FastGTPSA(norm(abs(-t) - abs(-v) )) - @FastGTPSA(norm(sqrt(t) - sqrt(v))) - @FastGTPSA(norm(exp(t) - exp(v))) - @FastGTPSA(norm(log(t) - log(v))) - @FastGTPSA(norm(sin(t) - sin(v))) - @FastGTPSA(norm(cos(t) - cos(v))) - @FastGTPSA(norm(tan(t) - tan(v))) - @FastGTPSA(norm(csc(t) - csc(v))) - @FastGTPSA(norm(sec(t) - sec(v))) - @FastGTPSA(norm(cot(t) - cot(v))) - @FastGTPSA(norm(sinc(t) - sinc(v))) - @FastGTPSA(norm(sinh(t) - sinh(v))) - @FastGTPSA(norm(cosh(t) - cosh(v))) - @FastGTPSA(norm(tanh(t) - tanh(v))) - @FastGTPSA(norm(csch(t) - csch(v))) - @FastGTPSA(norm(sech(t) - sech(v))) - @FastGTPSA(norm(coth(t) - coth(v))) - @FastGTPSA(norm(asin(t) - asin(v))) - @FastGTPSA(norm(acos(t) - acos(v))) - @FastGTPSA(norm(atan(t) - atan(v))) - @FastGTPSA(norm(acsc(1/t) - acsc(1/v))) - @FastGTPSA(norm(asec(1/t) - asec(1/v))) - @FastGTPSA(norm(acot(1/t) - acot(1/v))) - @FastGTPSA(norm(asinh(t) - asinh(v))) - @FastGTPSA(norm(acosh(1/t) - acosh(1/v))) - @FastGTPSA(norm(atanh(t) - atanh(v))) - @FastGTPSA(norm(acsch(1/t) - acsch(1/v))) - @FastGTPSA(norm(asech(t) - asech(v))) - @FastGTPSA(norm(acoth(1/t) - acoth(1/v))) - @FastGTPSA(norm(asinc(t/pi) - asin(v)/(v))) - @FastGTPSA(norm(asinhc(t/pi) - asinh(v)/(v))) - @FastGTPSA(norm(zero(t) - zero(v))) - @FastGTPSA(norm(real(t) - real(v))) - @FastGTPSA(norm(imag(t) - imag(v))) - @FastGTPSA(norm(conj(t) - conj(v))) - @FastGTPSA(norm(sinhc(t/pi) - sinh(v)/v)) - @FastGTPSA(norm(erf(t) - erf(v))) - @FastGTPSA(norm(erfc(t) - erfc(v))) - @FastGTPSA(norm(-im*erf(t*im) - erfi(v))) - @FastGTPSA(norm(atan(t3,t2) - atan(3,2))) - @FastGTPSA(norm(atan(t3,2) - atan(3,2))) - @FastGTPSA(norm(atan(3,t2) - atan(3,2))) - @FastGTPSA(norm(atan(t3,-t2) - atan(3,-2))) - @FastGTPSA(norm(atan(t3,-2) - atan(3,-2))) - @FastGTPSA(norm(atan(3,-t2) - atan(3,-2))) - @FastGTPSA(norm(atan(-t3,-t2) - atan(-3,-2))) - @FastGTPSA(norm(atan(-t3,-2) - atan(-3,-2))) - @FastGTPSA(norm(atan(-3,-t2) - atan(-3,-2))) - @FastGTPSA(norm(atan(-t3,t2) - atan(-3,2))) - @FastGTPSA(norm(atan(-t3,2) - atan(-3,2))) - @FastGTPSA(norm(atan(-3,t2) - atan(-3,2))) - @FastGTPSA(norm(hypot(t2,t3) - hypot(2,3))) - @FastGTPSA(norm(hypot(2,t3) - hypot(2,3))) - @FastGTPSA(norm(hypot(t2,3) - hypot(2,3))) - @FastGTPSA(norm(hypot(t1,t2,t3) - hypot(1,2,3))) - @FastGTPSA(norm(hypot(1, t2, t3) - hypot(1,2,3))) - @FastGTPSA(norm(hypot(t1, 2, t3) - hypot(1,2,3))) - @FastGTPSA(norm(hypot(t1, t2, 3) - hypot(1,2,3))) - @FastGTPSA(norm(hypot(1, 2, t3) - hypot(1,2,3))) - @FastGTPSA(norm(hypot(1, t2, 3) - hypot(1,2,3))) - @FastGTPSA(norm(hypot(t1, 2, 3) - hypot(1,2,3))) - - @FastGTPSA(norm(angle(t2) - angle(2))) - @FastGTPSA(norm(angle(-t2) - angle(-2))) - @FastGTPSA(norm(complex(t3) - complex(3))) - @FastGTPSA(norm(complex(t2,t3) - complex(2,3))) - @FastGTPSA(norm(polar(t2) - (abs(2)+im*atan(0,2)))) - @FastGTPSA(norm(polar(-t1) - (abs(-1)+im*atan(0,-1)))) - @FastGTPSA(norm(rect(t2) - (2*cos(0) + 2*sin(0)))) - @FastGTPSA(norm(rect(-t1) - (-1*cos(0) + -1*sin(0)))) + @FastGTPSA(norm(abs(-t) - abs(-v) )) < tol + @FastGTPSA(norm(sqrt(t) - sqrt(v))) < tol + @FastGTPSA(norm(exp(t) - exp(v))) < tol + @FastGTPSA(norm(log(t) - log(v))) < tol + @FastGTPSA(norm(sin(t) - sin(v))) < tol + @FastGTPSA(norm(cos(t) - cos(v))) < tol + @FastGTPSA(norm(tan(t) - tan(v))) < tol + @FastGTPSA(norm(csc(t) - csc(v))) < tol + @FastGTPSA(norm(sec(t) - sec(v))) < tol + @FastGTPSA(norm(cot(t) - cot(v))) < tol + @FastGTPSA(norm(sinc(t) - sinc(v))) < tol + @FastGTPSA(norm(sinh(t) - sinh(v))) < tol + @FastGTPSA(norm(cosh(t) - cosh(v))) < tol + @FastGTPSA(norm(tanh(t) - tanh(v))) < tol + @FastGTPSA(norm(csch(t) - csch(v))) < tol + @FastGTPSA(norm(sech(t) - sech(v))) < tol + @FastGTPSA(norm(coth(t) - coth(v))) < tol + @FastGTPSA(norm(asin(t) - asin(v))) < tol + @FastGTPSA(norm(acos(t) - acos(v))) < tol + @FastGTPSA(norm(atan(t) - atan(v))) < tol + @FastGTPSA(norm(acsc(1/t) - acsc(1/v))) < tol + @FastGTPSA(norm(asec(1/t) - asec(1/v))) < tol + @FastGTPSA(norm(acot(1/t) - acot(1/v))) < tol + @FastGTPSA(norm(asinh(t) - asinh(v))) < tol + @FastGTPSA(norm(acosh(1/t) - acosh(1/v))) < tol + @FastGTPSA(norm(atanh(t) - atanh(v))) < tol + @FastGTPSA(norm(acsch(1/t) - acsch(1/v))) < tol + @FastGTPSA(norm(asech(t) - asech(v))) < tol + @FastGTPSA(norm(acoth(1/t) - acoth(1/v))) < tol + @FastGTPSA(norm(asinc(t/pi) - asin(v)/(v))) < tol + @FastGTPSA(norm(asinhc(t/pi) - asinh(v)/(v))) < tol + @FastGTPSA(norm(zero(t) - zero(v))) < tol + @FastGTPSA(norm(real(t) - real(v))) < tol + @FastGTPSA(norm(imag(t) - imag(v))) < tol + @FastGTPSA(norm(conj(t) - conj(v))) < tol + @FastGTPSA(norm(sinhc(t/pi) - sinh(v)/v)) < tol + @FastGTPSA(norm(erf(t) - erf(v))) < tol + @FastGTPSA(norm(erfc(t) - erfc(v))) < tol + @FastGTPSA(norm(-im*erf(t*im) - erfi(v))) < tol + @FastGTPSA(norm(atan(t3,t2) - atan(3,2))) < tol + @FastGTPSA(norm(atan(t3,2) - atan(3,2))) < tol + @FastGTPSA(norm(atan(3,t2) - atan(3,2))) < tol + @FastGTPSA(norm(atan(t3,-t2) - atan(3,-2))) < tol + @FastGTPSA(norm(atan(t3,-2) - atan(3,-2))) < tol + @FastGTPSA(norm(atan(3,-t2) - atan(3,-2))) < tol + @FastGTPSA(norm(atan(-t3,-t2) - atan(-3,-2))) < tol + @FastGTPSA(norm(atan(-t3,-2) - atan(-3,-2))) < tol + @FastGTPSA(norm(atan(-3,-t2) - atan(-3,-2))) < tol + @FastGTPSA(norm(atan(-t3,t2) - atan(-3,2))) < tol + @FastGTPSA(norm(atan(-t3,2) - atan(-3,2))) < tol + @FastGTPSA(norm(atan(-3,t2) - atan(-3,2))) < tol + + @FastGTPSA(norm(hypot(t2,t3) - hypot(2,3))) < tol + @FastGTPSA(norm(hypot(2,t3) - hypot(2,3))) < tol + @FastGTPSA(norm(hypot(t2,3) - hypot(2,3))) < tol + @FastGTPSA(norm(hypot(t1,t2,t3) - hypot(1,2,3))) < tol + @FastGTPSA(norm(hypot(1, t2, t3) - hypot(1,2,3))) < tol + @FastGTPSA(norm(hypot(t1, 2, t3) - hypot(1,2,3))) < tol + @FastGTPSA(norm(hypot(t1, t2, 3) - hypot(1,2,3))) < tol + @FastGTPSA(norm(hypot(1, 2, t3) - hypot(1,2,3))) < tol + @FastGTPSA(norm(hypot(1, t2, 3) - hypot(1,2,3))) < tol + @FastGTPSA(norm(hypot(t1, 2, 3) - hypot(1,2,3))) < tol + + @FastGTPSA(norm(angle(t2) - angle(2))) < tol + @FastGTPSA(norm(angle(-t2) - angle(-2))) < tol + @FastGTPSA(norm(complex(t3) - complex(3))) < tol + @FastGTPSA(norm(complex(t2,t3) - complex(2,3))) < tol + @FastGTPSA(norm(polar(t2) - (abs(2)+im*atan(0,2)))) < tol + @FastGTPSA(norm(polar(-t1) - (abs(-1)+im*atan(0,-1)))) < tol + @FastGTPSA(norm(rect(t2) - (2*cos(0) + im*2*sin(0)))) < tol + @FastGTPSA(norm(rect(-t1) - (-1*cos(0) + im*-1*sin(0)))) < tol + v = 0.5+0.5im t = ComplexTPS(t) @@ -914,86 +924,89 @@ function type_stable_test() ct2[0] = 2 + 2im ct3 = zero(ct1) ct3[0] = 3 + 3im - @FastGTPSA(norm(abs(-t) - abs(-v) )) - @FastGTPSA(norm(sqrt(t) - sqrt(v))) - @FastGTPSA(norm(exp(t) - exp(v))) - @FastGTPSA(norm(log(t) - log(v))) - @FastGTPSA(norm(sin(t) - sin(v))) - @FastGTPSA(norm(cos(t) - cos(v))) - @FastGTPSA(norm(tan(t) - tan(v))) - @FastGTPSA(norm(csc(t) - csc(v))) - @FastGTPSA(norm(sec(t) - sec(v))) - @FastGTPSA(norm(cot(t) - cot(v))) - @FastGTPSA(norm(sinc(t) - sinc(v))) - @FastGTPSA(norm(sinh(t) - sinh(v))) - @FastGTPSA(norm(cosh(t) - cosh(v))) - @FastGTPSA(norm(tanh(t) - tanh(v))) - @FastGTPSA(norm(csch(t) - csch(v))) - @FastGTPSA(norm(sech(t) - sech(v))) - @FastGTPSA(norm(coth(t) - coth(v))) - @FastGTPSA(norm(asin(t) - asin(v))) - @FastGTPSA(norm(acos(t) - acos(v))) - @FastGTPSA(norm(atan(t) - atan(v))) - @FastGTPSA(norm(acsc(t) - acsc(v))) - @FastGTPSA(norm(asec(t) - asec(v))) - @FastGTPSA(norm(acot(t) - acot(v))) - @FastGTPSA(norm(asinh(t) - asinh(v))) - @FastGTPSA(norm(acosh(t) - acosh(v))) - @FastGTPSA(norm(atanh(t) - atanh(v))) - @FastGTPSA(norm(acsch(t) - acsch(v))) - @FastGTPSA(norm(asech(t) - asech(v))) - @FastGTPSA(norm(acoth(t) - acoth(v))) - @FastGTPSA(norm(asinc(t) - asin(v)/v)) - @FastGTPSA(norm(asinhc(t) - asinh(v)/v)) - @FastGTPSA(norm(zero(t) - zero(v))) - @FastGTPSA(norm(real(t) - real(v))) - @FastGTPSA(norm(imag(t) - imag(v))) - @FastGTPSA(norm(conj(t) - conj(v))) - @FastGTPSA(norm(sinhc(t/pi) - sinh(v)/v)) - @FastGTPSA(norm(erf(t) - erf(v))) - @FastGTPSA(norm(erfc(t) - erfc(v))) - @FastGTPSA(norm(-im*erf(t*im) - erfi(v))) - @FastGTPSA(norm(hypot(ct2,ct3) - hypot(2+2im,3+3im))) - @FastGTPSA(norm(hypot(2+2im,ct3) - hypot(2+2im,3+3im))) - @FastGTPSA(norm(hypot(ct2,3+3im) - hypot(2+2im,3+3im))) - @FastGTPSA(norm(hypot(ct1,ct2,ct3) - hypot(1+1im,2+2im,3+3im))) - @FastGTPSA(norm(hypot(1+1im, ct2, ct3) - hypot(1+1im,2+2im,3+3im))) - @FastGTPSA(norm(hypot(ct1, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im))) - @FastGTPSA(norm(hypot(ct1, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im))) - @FastGTPSA(norm(hypot(1+1im, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im))) - @FastGTPSA(norm(hypot(1+1im, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im))) - @FastGTPSA(norm(hypot(ct1, 2+2im, 3+3im) - hypot(1+1im,2+2im,3+3im))) - - @FastGTPSA(norm(angle(t2+im*t3) - angle(2+3im))) - @FastGTPSA(norm(angle(t2-im*t3) - angle(2-3im))) - @FastGTPSA(norm(angle(-t2-im*t3) - angle(-2-3im))) - @FastGTPSA(norm(angle(-t2+im*t3) - angle(-2+3im))) - @FastGTPSA(norm(angle(ct2) - angle(2+2im))) - @FastGTPSA(norm(angle(-ct2) - angle(-2-2im))) - @FastGTPSA(norm(complex(ct3) - complex(3+3im))) - @FastGTPSA(norm(polar(ct2) - (abs(2+2im)+im*angle(2+2im)))) - @FastGTPSA(norm(polar(-ct1) - (abs(-1-im)+im*angle(-1-im)))) - @FastGTPSA(norm(rect(ct2) - (2*cos(2) + 2*sin(2)))) - @FastGTPSA(norm(rect(-ct1) - (-1*cos(-1) + -1*sin(-1)))) + @FastGTPSA(norm(abs(-t) - abs(-v) )) < tol + @FastGTPSA(norm(sqrt(t) - sqrt(v))) < tol + @FastGTPSA(norm(exp(t) - exp(v))) < tol + @FastGTPSA(norm(log(t) - log(v))) < tol + @FastGTPSA(norm(sin(t) - sin(v))) < tol + @FastGTPSA(norm(cos(t) - cos(v))) < tol + @FastGTPSA(norm(tan(t) - tan(v))) < tol + @FastGTPSA(norm(csc(t) - csc(v))) < tol + @FastGTPSA(norm(sec(t) - sec(v))) < tol + @FastGTPSA(norm(cot(t) - cot(v))) < tol + @FastGTPSA(norm(sinc(t) - sinc(v))) < tol + @FastGTPSA(norm(sinh(t) - sinh(v))) < tol + @FastGTPSA(norm(cosh(t) - cosh(v))) < tol + @FastGTPSA(norm(tanh(t) - tanh(v))) < tol + @FastGTPSA(norm(csch(t) - csch(v))) < tol + @FastGTPSA(norm(sech(t) - sech(v))) < tol + @FastGTPSA(norm(coth(t) - coth(v))) < tol + + @FastGTPSA(norm(asin(t) - asin(v))) < tol + @FastGTPSA(norm(acos(t) - acos(v))) < tol + @FastGTPSA(norm(atan(t) - atan(v))) < tol + @FastGTPSA(norm(acsc(t) - acsc(v))) < tol + @FastGTPSA(norm(asec(t) - asec(v))) < tol + @FastGTPSA(norm(acot(t) - acot(v))) < tol + @FastGTPSA(norm(asinh(t) - asinh(v))) < tol + @FastGTPSA(norm(acosh(t) - acosh(v))) < tol + @FastGTPSA(norm(atanh(t) - atanh(v))) < tol + @FastGTPSA(norm(acsch(t) - acsch(v))) < tol + @FastGTPSA(norm(asech(t) - asech(v))) < tol + @FastGTPSA(norm(acoth(t) - acoth(v))) < tol + @FastGTPSA(norm(asinc(t/pi) - asin(v)/v)) < tol + @FastGTPSA(norm(asinhc(t/pi) - asinh(v)/v)) < tol + + @FastGTPSA(norm(zero(t) - zero(v))) < tol + @FastGTPSA(norm(real(t) - real(v))) < tol + @FastGTPSA(norm(imag(t) - imag(v))) < tol + @FastGTPSA(norm(conj(t) - conj(v))) < tol + @FastGTPSA(norm(sinhc(t/pi) - sinh(v)/v)) < tol + @FastGTPSA(norm(erf(t) - erf(v))) < tol + @FastGTPSA(norm(erfc(t) - erfc(v))) < tol + @FastGTPSA(norm(-im*erf(t*im) - erfi(v))) < tol + @FastGTPSA(norm(hypot(ct2,ct3) - hypot(2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(2+2im,ct3) - hypot(2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(ct2,3+3im) - hypot(2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(ct1,ct2,ct3) - hypot(1+1im,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(1+1im, ct2, ct3) - hypot(1+1im,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(ct1, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(ct1, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(1+1im, 2+2im, ct3) - hypot(1+1im,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(1+1im, ct2, 3+3im) - hypot(1+1im,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(ct1, 2+2im, 3+3im) - hypot(1+1im,2+2im,3+3im))) < tol + + @FastGTPSA(norm(angle(t2+im*t3) - angle(2+3im))) < tol + @FastGTPSA(norm(angle(t2-im*t3) - angle(2-3im))) < tol + @FastGTPSA(norm(angle(-t2-im*t3) - angle(-2-3im))) < tol + @FastGTPSA(norm(angle(-t2+im*t3) - angle(-2+3im))) < tol + @FastGTPSA(norm(angle(ct2) - angle(2+2im))) < tol + @FastGTPSA(norm(angle(-ct2) - angle(-2-2im))) < tol + @FastGTPSA(norm(complex(ct3) - complex(3+3im))) < tol + @FastGTPSA(norm(polar(ct2) - (abs(2+2im)+im*angle(2+2im)))) < tol + @FastGTPSA(norm(polar(-ct1) - (abs(-1-im)+im*angle(-1-im)))) < tol + @FastGTPSA(norm(rect(ct2) - (2*cos(2) + im*2*sin(2)))) < tol + @FastGTPSA(norm(rect(-ct1) - (-1*cos(-1) + im*-1*sin(-1)))) < tol + # Hypot, mixing TPS with ComplexTPS - @FastGTPSA(norm(hypot(ct1, ct2, t3) - hypot(1+1im,2+2im,3))) - @FastGTPSA(norm(hypot(ct1, t2, ct3) - hypot(1+1im,2,3+3im))) - @FastGTPSA(norm(hypot(t1, ct2, ct3) - hypot(1,2+2im,3+3im))) - @FastGTPSA(norm(hypot(ct1, t2, t3) - hypot(1+1im,2,3))) - @FastGTPSA(norm(hypot(t1, ct2, t3) - hypot(1,2+2im,3))) - @FastGTPSA(norm(hypot(t1, t2, ct3) - hypot(1,2,3+3im))) - @FastGTPSA(norm(hypot(ct1,t2,3+3im) - hypot(1+1im,2,3+3im))) - @FastGTPSA(norm(hypot(t1, ct2, 3+3im) - hypot(1,2+2im,3+3im))) - @FastGTPSA(norm(hypot(ct1,2+2im,t3) - hypot(1+1im,2+2im,3))) - @FastGTPSA(norm(hypot(t1,2+2im,ct3) - hypot(1,2+2im,3+3im))) - @FastGTPSA(norm(hypot(1+1im,ct2,t3) - hypot(1+1im,2+2im,3))) - @FastGTPSA(norm(hypot(1+1im, t2, ct3) - hypot(1+1im,2,3+3im))) - @FastGTPSA(norm(hypot(t1,t2,3+3im) - hypot(1,2,3+3im))) - @FastGTPSA(norm(hypot(t1,2+2im,t3) - hypot(1,2+2im,3))) - @FastGTPSA(norm(hypot(1+1im,t2,t3) - hypot(1+1im,2,3))) - @FastGTPSA(norm(hypot(t1,2,3+3im) - hypot(1,2,3+3im))) - @FastGTPSA(norm(hypot(1,t2,3+3im) - hypot(1,2,3+3im))) - @FastGTPSA(norm(hypot(1+1im,2,t3) - hypot(1+1im,2,3))) + @FastGTPSA(norm(hypot(ct1, ct2, t3) - hypot(1+1im,2+2im,3))) < tol + @FastGTPSA(norm(hypot(ct1, t2, ct3) - hypot(1+1im,2,3+3im))) < tol + @FastGTPSA(norm(hypot(t1, ct2, ct3) - hypot(1,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(ct1, t2, t3) - hypot(1+1im,2,3))) < tol + @FastGTPSA(norm(hypot(t1, ct2, t3) - hypot(1,2+2im,3))) < tol + @FastGTPSA(norm(hypot(t1, t2, ct3) - hypot(1,2,3+3im))) < tol + @FastGTPSA(norm(hypot(ct1,t2,3+3im) - hypot(1+1im,2,3+3im))) < tol + @FastGTPSA(norm(hypot(t1, ct2, 3+3im) - hypot(1,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(ct1,2+2im,t3) - hypot(1+1im,2+2im,3))) < tol + @FastGTPSA(norm(hypot(t1,2+2im,ct3) - hypot(1,2+2im,3+3im))) < tol + @FastGTPSA(norm(hypot(1+1im,ct2,t3) - hypot(1+1im,2+2im,3))) < tol + @FastGTPSA(norm(hypot(1+1im, t2, ct3) - hypot(1+1im,2,3+3im))) < tol + @FastGTPSA(norm(hypot(t1,t2,3+3im) - hypot(1,2,3+3im))) < tol + @FastGTPSA(norm(hypot(t1,2+2im,t3) - hypot(1,2+2im,3))) < tol + @FastGTPSA(norm(hypot(1+1im,t2,t3) - hypot(1+1im,2,3))) < tol + @FastGTPSA(norm(hypot(t1,2,3+3im) - hypot(1,2,3+3im))) < tol + @FastGTPSA(norm(hypot(1,t2,3+3im) - hypot(1,2,3+3im))) < tol + @FastGTPSA(norm(hypot(1+1im,2,t3) - hypot(1+1im,2,3))) < tol # Make sure stack is 0: desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t1.tpsa).d)) @@ -1001,115 +1014,117 @@ function type_stable_test() ctmpidx = unsafe_load(desc.cti) ctmpidx == 0 tmpidx == 0 + d = Descriptor(1, 5) t = TPS(use=d) - t[0] = 0.5; t[1] = 2; t[2] = 3; t[3] = 4; t[4] = 5; t[5] = 6 + t[0] = 0.5; t[[1]] = 2; t[[2]] = 3; t[[3]] = 4; t[[4]] = 5; t[[5]] = 6 tol = 1e-10 - @FastGTPSA(norm(sin(t)^2+cos(t)^2 - 1)) - @FastGTPSA(norm(1/sin(t) - csc(t))) - @FastGTPSA(norm(1/cos(t) - sec(t))) - @FastGTPSA(norm(1/tan(t) - cot(t))) - @FastGTPSA(norm(sin(t)/cos(t) - tan(t))) - @FastGTPSA(norm(cos(2*t) - cos(t)^2 + sin(t)^2)) - @FastGTPSA(norm(sec(t)^2 - 1 - tan(t)^2)) - @FastGTPSA(norm(sin(t/2) - sqrt((1-cos(t))/2))) - @FastGTPSA(norm(cos(t/2) - sqrt((1+cos(t))/2))) - @FastGTPSA(norm(sqrt(t^2) - abs(t))) - @FastGTPSA(norm(csc(t)^2 - cot(t)^2 - 1)) - @FastGTPSA(norm(exp(log(t)) - t)) - @FastGTPSA(norm(log(exp(t)) - t)) - @FastGTPSA(norm(log(exp(t)) - exp(log(t)))) - @FastGTPSA(norm(log(t^2) - 2*log(t))) - @FastGTPSA(norm(5*log(t) - log(t^5))) - @FastGTPSA(norm(t*log(5) - log(5^t))) - @FastGTPSA(norm(sinc(t) - sin(pi*t)/(pi*t))) - @FastGTPSA(norm(sinhc(t/pi) - sinh(t)/t)) - @FastGTPSA(norm(exp(im*t) - cos(t) - im*sin(t))) - @FastGTPSA(norm(real(exp(im*t)) - cos(t))) - @FastGTPSA(norm(imag(exp(im*t)) - sin(t))) - @FastGTPSA(norm(sinh(t) - (exp(t) - exp(-t))/2)) - @FastGTPSA(norm(cosh(t) - (exp(t) + exp(-t))/2)) - @FastGTPSA(norm(tanh(t) - sinh(t)/cosh(t))) - @FastGTPSA(norm(csch(t) - 1/sinh(t))) - @FastGTPSA(norm(sech(t) - 1/cosh(t))) - @FastGTPSA(norm(coth(t) - cosh(t)/sinh(t))) - @FastGTPSA(norm(coth(t) - 1/tanh(t))) - @FastGTPSA(norm(cosh(t)^2 - sinh(t)^2 - 1)) - @FastGTPSA(norm(1 - tanh(t)^2 - sech(t)^2)) - @FastGTPSA(norm(coth(t)^2 - 1 - csch(t)^2)) - @FastGTPSA(norm(asin(sin(t)) - t)) - @FastGTPSA(norm(acos(cos(t)) - t)) - @FastGTPSA(norm(atan(tan(t)) - t)) - @FastGTPSA(norm(acsc(1/t) - asin(t))) - @FastGTPSA(norm(asec(1/t) - acos(t))) - @FastGTPSA(norm(acot(1/t) - atan(t))) - @FastGTPSA(norm(asinh(sinh(t)) - t)) - @FastGTPSA(norm(acosh(cosh(t)) - t)) - @FastGTPSA(norm(atanh(tanh(t)) - t)) - @FastGTPSA(norm(acsch(t) - asinh(1/t))) - @FastGTPSA(norm(asech(t) - acosh(1/t))) - @FastGTPSA(norm(acoth(1/t) - atanh(t))) - @FastGTPSA(norm(asinc(t/pi) - asin(t)/t)) - @FastGTPSA(norm(asinhc(t/pi) - asinh(t)/t)) - @FastGTPSA(norm(erfc(t) - 1 + erf(t))) - @FastGTPSA(norm(erf(-t) + erf(t))) - @FastGTPSA(norm(angle(t))) - @FastGTPSA(norm(complex(t) - t)) - @FastGTPSA(norm(complex(t,t) - (t+im*t))) + @FastGTPSA(norm(sin(t)^2+cos(t)^2 - 1)) < tol + @FastGTPSA(norm(1/sin(t) - csc(t))) < tol + @FastGTPSA(norm(1/cos(t) - sec(t))) < tol + @FastGTPSA(norm(1/tan(t) - cot(t))) < tol + @FastGTPSA(norm(sin(t)/cos(t) - tan(t))) < tol + @FastGTPSA(norm(cos(2*t) - cos(t)^2 + sin(t)^2)) < tol + @FastGTPSA(norm(sec(t)^2 - 1 - tan(t)^2)) < tol + @FastGTPSA(norm(sin(t/2) - sqrt((1-cos(t))/2))) < tol + @FastGTPSA(norm(cos(t/2) - sqrt((1+cos(t))/2))) < tol + @FastGTPSA(norm(sqrt(t^2) - abs(t))) < tol + @FastGTPSA(norm(csc(t)^2 - cot(t)^2 - 1)) < tol + @FastGTPSA(norm(exp(log(t)) - t)) < tol + @FastGTPSA(norm(log(exp(t)) - t)) < tol + @FastGTPSA(norm(log(exp(t)) - exp(log(t)))) < tol + @FastGTPSA(norm(log(t^2) - 2*log(t))) < tol + @FastGTPSA(norm(5*log(t) - log(t^5))) < tol + @FastGTPSA(norm(t*log(5) - log(5^t))) < tol + @FastGTPSA(norm(sinc(t) - sin(pi*t)/(pi*t))) < tol + @FastGTPSA(norm(sinhc(t/pi) - sinh(t)/t)) < tol + @FastGTPSA(norm(exp(im*t) - cos(t) - im*sin(t))) < tol + @FastGTPSA(norm(real(exp(im*t)) - cos(t))) < tol + @FastGTPSA(norm(imag(exp(im*t)) - sin(t))) < tol + @FastGTPSA(norm(sinh(t) - (exp(t) - exp(-t))/2)) < tol + @FastGTPSA(norm(cosh(t) - (exp(t) + exp(-t))/2)) < tol + @FastGTPSA(norm(tanh(t) - sinh(t)/cosh(t))) < tol + @FastGTPSA(norm(csch(t) - 1/sinh(t))) < tol + @FastGTPSA(norm(sech(t) - 1/cosh(t))) < tol + @FastGTPSA(norm(coth(t) - cosh(t)/sinh(t))) < tol + @FastGTPSA(norm(coth(t) - 1/tanh(t))) < tol + @FastGTPSA(norm(cosh(t)^2 - sinh(t)^2 - 1)) < tol + @FastGTPSA(norm(1 - tanh(t)^2 - sech(t)^2)) < tol + @FastGTPSA(norm(coth(t)^2 - 1 - csch(t)^2)) < tol + @FastGTPSA(norm(asin(sin(t)) - t)) < tol + @FastGTPSA(norm(acos(cos(t)) - t)) < tol + @FastGTPSA(norm(atan(tan(t)) - t)) < tol + @FastGTPSA(norm(acsc(1/t) - asin(t))) < tol + @FastGTPSA(norm(asec(1/t) - acos(t))) < tol + @FastGTPSA(norm(acot(1/t) - atan(t))) < tol + @FastGTPSA(norm(asinh(sinh(t)) - t)) < tol + @FastGTPSA(norm(acosh(cosh(t)) - t)) < tol + @FastGTPSA(norm(atanh(tanh(t)) - t)) < tol + @FastGTPSA(norm(acsch(t) - asinh(1/t))) < tol + @FastGTPSA(norm(asech(t) - acosh(1/t))) < tol + @FastGTPSA(norm(acoth(1/t) - atanh(t))) < tol + @FastGTPSA(norm(asinc(t/pi) - asin(t)/t)) < tol + @FastGTPSA(norm(asinhc(t/pi) - asinh(t)/t)) < tol + @FastGTPSA(norm(erfc(t) - 1 + erf(t))) < tol + @FastGTPSA(norm(erf(-t) + erf(t))) < tol + @FastGTPSA(norm(angle(t))) < tol + @FastGTPSA(norm(complex(t) - t)) < tol + @FastGTPSA(norm(complex(t,t) - (t+im*t))) < tol t = ComplexTPS(t) - t[0] = 0.5+0.5im; t[1] = 2+2im; t[2] = 3+3im; t[3] = 4+4im; t[4] = 5+5im; t[5] = 6+6im - @FastGTPSA(norm(sin(t)^2+cos(t)^2 - 1)) - @FastGTPSA(norm(1/sin(t) - csc(t))) - @FastGTPSA(norm(1/cos(t) - sec(t))) - @FastGTPSA(norm(1/tan(t) - cot(t))) - @FastGTPSA(norm(sin(t)/cos(t) - tan(t))) - @FastGTPSA(norm(cos(2*t) - cos(t)^2 + sin(t)^2)) - @FastGTPSA(norm(sec(t)^2 - 1 - tan(t)^2)) - @FastGTPSA(norm(sin(t/2) - sqrt((1-cos(t))/2))) - @FastGTPSA(norm(cos(t/2) - sqrt((1+cos(t))/2))) - @FastGTPSA(norm(sqrt(t^2) - t)) - @FastGTPSA(norm(csc(t)^2 - cot(t)^2 - 1)) - @FastGTPSA(norm(exp(log(t)) - t)) - @FastGTPSA(norm(log(exp(t)) - t)) - @FastGTPSA(norm(log(exp(t)) - exp(log(t)))) - @FastGTPSA(norm(log(t^2) - 2*log(t))) - @FastGTPSA(norm(5*log(t) - log(t^5) - 2*pi*im)) - @FastGTPSA(norm(t*log(5) - log(5^t))) - @FastGTPSA(norm(sinc(t/pi) - sin(t)/t)) - @FastGTPSA(norm(sinhc(t/pi) - sinh(t)/t)) - @FastGTPSA(norm(exp(im*t) - cos(t) - im*sin(t))) - @FastGTPSA(norm(sinh(t) - (exp(t) - exp(-t))/2)) - @FastGTPSA(norm(cosh(t) - (exp(t) + exp(-t))/2)) - @FastGTPSA(norm(tanh(t) - sinh(t)/cosh(t))) - @FastGTPSA(norm(csch(t) - 1/sinh(t))) - @FastGTPSA(norm(sech(t) - 1/cosh(t))) - @FastGTPSA(norm(coth(t) - cosh(t)/sinh(t))) - @FastGTPSA(norm(coth(t) - 1/tanh(t))) - @FastGTPSA(norm(cosh(t)^2 - sinh(t)^2 - 1)) - @FastGTPSA(norm(1 - tanh(t)^2 - sech(t)^2)) - @FastGTPSA(norm(coth(t)^2 - 1 - csch(t)^2)) - - @FastGTPSA(norm(asin(sin(t)) - t)) - @FastGTPSA(norm(acos(cos(t)) - t)) - @FastGTPSA(norm(atan(tan(t)) - t)) - @FastGTPSA(norm(acsc(t) - asin(1/t))) - @FastGTPSA(norm(asec(t) - acos(1/t))) - @FastGTPSA(norm(acot(t) - acot(1/t))) - @FastGTPSA(norm(asinh(sinh(t)) - t)) - @FastGTPSA(norm(acosh(cosh(t)) - t)) - @FastGTPSA(norm(atanh(tanh(t)) - t)) - @FastGTPSA(norm(acsch(t) - asinh(1/t))) - @FastGTPSA(norm(asech(t) - acosh(1/t))) - @FastGTPSA(norm(acoth(t) - acoth(1/t))) - @FastGTPSA(norm(asinc(t) - asin(t)/t)) - @FastGTPSA(norm(asinhc(t) - asinh(t)/t)) - @FastGTPSA(norm(erfc(t) - 1 + erf(t))) - @FastGTPSA(norm(erf(-t) + erf(t))) - @FastGTPSA(norm(angle(t) - atan(imag(t),real(t)))) - @FastGTPSA(norm(complex(t) - t)) + t[0] = 0.5+0.5im; t[[1]] = 2+2im; t[[2]] = 3+3im; t[[3]] = 4+4im; t[[4]] = 5+5im; t[[5]] = 6+6im + @FastGTPSA(norm(sin(t)^2+cos(t)^2 - 1)) < tol + @FastGTPSA(norm(1/sin(t) - csc(t))) < tol + @FastGTPSA(norm(1/cos(t) - sec(t))) < tol + @FastGTPSA(norm(1/tan(t) - cot(t))) < tol + @FastGTPSA(norm(sin(t)/cos(t) - tan(t))) < tol + @FastGTPSA(norm(cos(2*t) - cos(t)^2 + sin(t)^2)) < tol + @FastGTPSA(norm(sec(t)^2 - 1 - tan(t)^2)) < tol + @FastGTPSA(norm(sin(t/2) - sqrt((1-cos(t))/2))) < tol + @FastGTPSA(norm(cos(t/2) - sqrt((1+cos(t))/2))) < tol + @FastGTPSA(norm(sqrt(t^2) - t)) < tol + @FastGTPSA(norm(csc(t)^2 - cot(t)^2 - 1)) < tol + @FastGTPSA(norm(exp(log(t)) - t)) < tol + @FastGTPSA(norm(log(exp(t)) - t)) < tol + @FastGTPSA(norm(log(exp(t)) - exp(log(t)))) < tol + @FastGTPSA(norm(log(t^2) - 2*log(t))) < tol + @FastGTPSA(norm(5*log(t) - log(t^5) - 2*pi*im)) < tol + @FastGTPSA(norm(t*log(5) - log(5^t))) < tol + @FastGTPSA(norm(sinc(t/pi) - sin(t)/t)) < tol + @FastGTPSA(norm(sinhc(t/pi) - sinh(t)/t)) < tol + @FastGTPSA(norm(exp(im*t) - cos(t) - im*sin(t))) < tol + @FastGTPSA(norm(sinh(t) - (exp(t) - exp(-t))/2)) < tol + @FastGTPSA(norm(cosh(t) - (exp(t) + exp(-t))/2)) < tol + @FastGTPSA(norm(tanh(t) - sinh(t)/cosh(t))) < tol + @FastGTPSA(norm(csch(t) - 1/sinh(t))) < tol + @FastGTPSA(norm(sech(t) - 1/cosh(t))) < tol + @FastGTPSA(norm(coth(t) - cosh(t)/sinh(t))) < tol + @FastGTPSA(norm(coth(t) - 1/tanh(t))) < tol + @FastGTPSA(norm(cosh(t)^2 - sinh(t)^2 - 1)) < tol + @FastGTPSA(norm(1 - tanh(t)^2 - sech(t)^2)) < tol + @FastGTPSA(norm(coth(t)^2 - 1 - csch(t)^2)) < tol + + @FastGTPSA(norm(asin(sin(t)) - t)) < tol + @FastGTPSA(norm(acos(cos(t)) - t)) < tol + @FastGTPSA(norm(atan(tan(t)) - t)) < tol + @FastGTPSA(norm(acsc(t) - asin(1/t))) < tol + @FastGTPSA(norm(asec(t) - acos(1/t))) < tol + @FastGTPSA(norm(acot(t) - atan(1/t))) < tol + @FastGTPSA(norm(asinh(sinh(t)) - t)) < tol + @FastGTPSA(norm(acosh(cosh(t)) - t)) < tol + @FastGTPSA(norm(atanh(tanh(t)) - t)) < tol + @FastGTPSA(norm(acsch(t) - asinh(1/t))) < tol + @FastGTPSA(norm(asech(t) - acosh(1/t))) < tol + @FastGTPSA(norm(acoth(t) - atanh(1/t))) < tol + @FastGTPSA(norm(asinc(t/pi) - asin(t)/t)) < tol + @FastGTPSA(norm(asinhc(t/pi) - asinh(t)/t)) < tol + + @FastGTPSA(norm(erfc(t) - 1 + erf(t))) < tol + @FastGTPSA(norm(erf(-t) + erf(t))) < tol + @FastGTPSA(norm(angle(t) - atan(imag(t),real(t)))) < tol + @FastGTPSA(norm(complex(t) - t)) < tol # Make sure stack is 0: desc = unsafe_load(Base.unsafe_convert(Ptr{Desc}, unsafe_load(t.tpsa).d))