Releases: tidyfun/tf
Releases · tidyfun/tf
Release list
tf 0.5.0
Internal
tf_rgp()no longer depends onmvtnormorpracma. GP draws are now
generated by a direct eigen-based sampler (the symmetric square root
V D^{1/2} V^Tof the covariance) that reproduces the previous
mvtnorm::rmvnorm(method = "eigen")draws bit-for-bit underset.seed()and
handles rank-deficient kernels (e.g. squared-exp with zero nugget) correctly.
tf_smooth.tfd(method = "savgol")now inlines a small Savitzky–Golay filter
in place of thepracma::savgol()dependency.
Bug fixes
tf_evaluate()no longer returns values at the wrong positions when the
requested arg contains duplicates (#236).tf_integrate(f, definite = FALSE)for irregulartfdwith n > 1 no longer
crashes; the antiderivative's per-curve grids are kept as a list (#237).Math.tfd()/Math.tfb()now forward...to the underlying op so
round(x, digits),log(x, base),signif(x, digits), etc. honor their
extra arguments instead of silently dropping them (#246).tf_integrate()on irregulartfdno longer silently returnsNAunder
default limits; for irregular input the defaults are now each curve's own
observed arg range (i.e., the range of itstf_arg()values). Pass explicit
lower/upper(or an extrapolating evaluator) to override (#253).
Vector-valued functional data
This release introduces first-class support for vector-valued (multivariate)
functional data -- functions whose codomain is R^d -- alongside the existing
univariate tfd/tfb classes.
tfd_mv()andtfb_mv(): newvctrs-based S3 classes for vector-valued
functional data, holding several component functions per observation on a
shared domain. Constructors accept named lists oftfd/tfbvectors or
list-columns of matrices.tfb_mfpc()implements multivariate functional principal component analysis
(Happ & Greven, 2018) fortf_mvdata: a single set of scalar scores per
curve shared across all components, with vector-valued eigenfunctions.
Component weighting is configurable ("inverse_variance"default,"snr",
"equal", or user-supplied). New data can be projected onto a fitted basis
viatf_rebase()/vec_cast(). Accessorstf_mfpc_scores(),
tf_mfpc_efunctions()and the predicateis_tfb_mfpc().- Multivariate registration:
tf_register()gainsmethod = "srvf_mv"for
jointly aligning the components oftf_mvcurves via the multivariate SRVF
framework, andtf_register_shape()provides elastic shape registration
(rotation/translation/scale-invariant) viafdasrvf. - New geometry verbs for
tf_mv(and where meaningful for univariatetf):
tf_norm(),tf_inner(),tf_tangent(),tf_arclength(). - Component accessors (
tf_ncomp(),tf_components(),tf_component()),
tf_split()/tf_combine()extensions and[/[[methods for extracting,
replacing and recombining components. - Function-wise scalar summaries
tf_fmean(),tf_fvar()andtf_fsd()
return component-wise matrices fortf_mvobjects. tf_interpolate(),tf_fwise(),tf_sparsify()andtf_jiggle()now have
component-wisetf_mvmethods;tf_sparsify()andtf_jiggle()keep shared
component grids by default viasame_arg = TRUE.tf_where()/tf_anywhere()work ontf_mvobjects with joint
conditions across components, referenced by name (e.g.
tf_where(f, x > 0 & y < 1)); there is novaluecolumn fortf_mvinput.
Components must share a common grid, orargmust be supplied explicitly.quantile()works ontf_mvobjects, returning the component-wise
pointwise quantiles: atf_mvwith one curve per requested probability in
probs, exactly asquantile.tf()does per component (na.rm/probs/
typeare forwarded).points()works ontf_mvobjects, mirroringlines.tf_mv(): in
"trajectory"mode (d == 2) it overlays the paired(x(t), y(t))points
with per-curve graphical-parameter recycling; in"facet"mode it overlays
each component onto the current device.tf_depth()gains atf_mvmethod: a weighted componentwise aggregation of
the (centrality) univariate depths, with aweightsargument mirroring
tfb_mfpc()("equal"default,"inverse_variance", or a numeric vector).
The up-down ordering index"MHI"has no canonical vector-valued analogue and
aborts with a pointer totf_order()(#273).median(),summary()andfivenum()ontf_mvnow select observed
vector-valued curves via a single joint-depth index (one curve across all
components), fixing the previous component-wise "chimera" where each component
could come from a different observation. Pointwise entries (mean, min/max, the
central-half range) remain component-wise (#273).- New generic
tf_order()with atf_mvmethod:tf_order(f, by = "norm")
(orby = <component name>) orders vector-valued curves by an explicit
scalar reduction.sort(),rank()andxtfrm()remain permanently
undefined fortf_mv-- there is no canonical total order onR^d-- so
basesort()/order()/rank()fail fast rather than fabricate an order
(#273).
Contract change
is_tf()now returnsTRUEfortf_mvas well as univariatetfd/tfb.
Code that branched onis_tf()to mean "univariatetf" should switch to
the new predicateis_tf_1d()."arg"and"id"are reserved and cannot be used as component names --
they collide with the grid and curve-id columns of long-format conversions.- Constructing a
tf_mvfrom components with differing domains now warns
when wideningtfdcomponents to the union domain (evaluations outside the
observed range areNA) and aborts fortfbcomponents, where basis
evaluation outside the fitted range would extrapolate, i.e. fabricate
values. - Component-wise operations on a
tfb_mfpc(tf_smooth(),tf_derive(),
tf_zoom(),tf_integrate(),mean()/sd()/var(),Summarygroup
generics) now consistently demote to valid per-componenttfb_fpc
representations with a one-time warning, like arithmetic already did --
previously they silently produced objects that abort on later use. tf_fmax(),tf_fmin()andtf_fmedian()ontf_mvreturn ann x d
curves-x-components matrix liketf_fmean()/tf_fsd()(previously: a
misnamed interleaved vector).tfb_fpc()andtfb_mfpc()abort informatively when the input contains
completely missing curves (partially missing evaluations continue to be
handled by the soft-impute SVD); re-scoring new data withNAcurves via
tf_rebase()/vec_cast()yieldsNAscores andNAentries.
Tabular export of components on differing grids
as.data.frame.tf_mv(unnest = TRUE)gains agridsargument controlling
where components are evaluated when they live on different argument grids:
"union"(default, previous behavior) evaluates every component on each
curve's union grid, interpolating inside the observed range;"component"
evaluates each component strictly on its own grid (or onarg), so no
values are fabricated where a component was not observed -- the faithful
export used bytidyfun::tf_unnest(). For shared grids both agree.
More bug fixes (pre-release review)
- Empty prototypes (
tfd(),tfb(),tfd_mv(list())and friends) carry the
sentinel domainc(NA, NA)and now combine cleanly with populated vectors
in allvctrspaths (vec_c(),vec_rbind(),c(), casts) -- binding
rows onto an initially emptytfcolumn works again. tfb_mv()on an existingtfb_mvwith an explicitbasisargument re-fits
in the requested basis instead of silently returning the old one; changing
the basis kind converts throughtfd().tfb_mv()/tfb_mfpc()on raw lists/arrays route constructor arguments
(arg,domain) and basis arguments to the right place instead of
forwarding everything everywhere.tfd_mv()on 3-d arrays keeps length-1 curve/arg margins and curve names.tf_derive()andtf_integrate()ontf_mvaccept per-componentarg
lists, consistent withtf_interpolate().Summarygroup generics ontf_mvno longer recycleNAmasks across
operands of different lengths.tf_arclength():method = "polyline"honorslower/upperwithout
creating near-duplicate vertices, andmethod = "derive"no longer
NA-poisons irregular curves that do not span the full domain.- Indefinite
tf_integrate()on irregulartfdsnaps user-supplied limits
to (almost-)coinciding grid points instead of constructing invalid objects. tf_register()works fortf_mvinputs whose components live on different
grids;tf_register_shape()returns a user-suppliedtemplateunchanged
fromtf_template(); single-componentsrvf_mvdelegates to univariate
elastic registration and template-free single-curve registration is
rejected with an explanation instead of crashing insidefdasrvf.
v0.4.1
tf 0.4.0
New features
tf_register()& co implement registration methods (SRVF, affine, landmark,
continuous-criterion) for aligning functions and analyzing phase variability.
Returns a newtf_registrationclass with accessorstf_aligned(),
tf_inv_warps(),tf_template().tf_depth()now implements five functional depth methods: MBD (default), MHI,
FM (Fraiman-Muniz), FSD (Functional Spatial Depth), and RPD (Regularized
Projection Depth). MHI ranks functions from lowest (0) to highest (1); all
other depths are scaled from 0 (most extreme) to 1 (most central).
MBD is now scaled to [0, 1] instead of [0, 0.5].tf_split()/tf_combine()for splitting functions into sub-domain
fragments and re-combining themtf_rgp()gains a"brownian_bridge"covariance option and can generate
irregular data via the newirregargumenttfb_spline()now convertsfda::fdandfda::fdSmoothobjects directlymgcv-style Fourier basis constructor for use intfb_spline()- sparklines in
print()/format()for alltfsubtypes tf_where()now defaults toarg = tf_arg(x), consistent with other functionsas.matrix()for irregulartfdnow always interpolates to a common grid
Bug fixes
tf_derive()fortfdobjects now uses second-order accurate finite
differences, preserving the original domain and grid (#59)- major overhaul of NA handling: NA entries are now consistently represented as
NULLinternally; fixes fortf_arg(),tf_evaluate(),tf_smooth(),
tfd()conversion,is.na(), printing, and arithmetic with NA entries - fix
summary.tf()returning wrong central range - fix
tfddomain enforcement for length-1 data (#139) - fix printing for empty
tfbobjects and all-NA vectors
Other changes
tf_deriveandtf_integratecan now handletfbwith non-identity link functions
by falling back totfd-calculus methods (and returningtfdobjects).tfd_irregarithmetic now operates on intersection of arg-values instead
of failing when arg-values are not identicaltfbarithmetic fix- dropped
gluedependency in favour ofcli/sprintf;
replacedstopifnot()with informativecli::cli_abort()throughout - use
vctrs::vec_arith()for group generics,vctrsutils in[.tf - various internal performance improvements
- use
airformatter for all R code