Skip to content
Merged

Devel #249

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
3bda87d
Project.toml: update Symbolics deps
Sep 14, 2024
70a4e1f
tests/examples: import -> using
alyst Mar 15, 2024
56a1b04
add ParamsArray
alyst Nov 22, 2024
81d0ab7
materialize!(Symm/LowTri/UpTri)
Mar 22, 2024
fd13c74
ParamsArray: faster sparse materialize!
Mar 22, 2024
19497d5
ParamsArray: use Iterators.flatten() (faster)
Jul 3, 2024
139338d
Base.hash(::ParamsArray)
alyst Aug 11, 2024
5850784
colnames -> vars
alyst Aug 11, 2024
0f747b7
update_partable!(): better params unique check
Apr 4, 2024
aa34d53
start_fabin3: check obs_mean data & meanstructure
alyst Aug 1, 2024
13aacd0
params/vars API tweaks and tests
alyst Nov 22, 2024
8c26c35
generic imply: keep F sparse
Mar 22, 2024
5b9327e
Merge pull request #219 from alyst/params_array
Maximilian-Stefan-Ernst Nov 23, 2024
3816539
tests helper: is_extended_tests()
Mar 12, 2024
b8d9a8f
Optim sem_fit(): use provided optimizer
May 26, 2024
dd275d5
prepare_start_params(): arg-dependent dispatch
alyst Dec 19, 2024
0131bb7
prepare_param_bounds() API for optim
alyst Dec 19, 2024
fbdcc7f
u/l_bounds support for Optim.jl
alyst Dec 19, 2024
d1f323a
SemOptimizer(engine = ...) ctor
alyst Apr 14, 2024
0a6b073
SEMNLOptExt for NLopt
Apr 3, 2024
730eadc
NLopt: sem_fit(): use provided optimizer
alyst Nov 24, 2024
23e2265
SEMProximalOptExt for Proximal opt
alyst Dec 19, 2024
8a98831
merge diff/*.jl optimizer code into optimizer/*.jl
alyst Dec 20, 2024
9e2672d
Optim: document u/l bounds
alyst Dec 20, 2024
d618898
remove unused options field from Proximal optimizer
Maximilian-Stefan-Ernst Dec 19, 2024
d055c78
decouple optimizer from Sem model
alyst Dec 20, 2024
71bced7
fix inequality constraints test
alyst Nov 24, 2024
928af39
add ProximalSEM tests
Maximilian-Stefan-Ernst Dec 20, 2024
c19c4a7
optim/documentation.jl: rename to abstract.jl
alyst Dec 20, 2024
c5b48c7
ext: change folder layout
alyst Dec 20, 2024
b839635
Merge pull request #228 from alyst/optim_extensions
Maximilian-Stefan-Ernst Dec 22, 2024
d5357f0
Project.toml: fix ProximalOperators ID
alyst Dec 24, 2024
48a744f
docs: fix nsamples, nobserved_vars
alyst Aug 1, 2024
5faf116
cleanup data columns reordering
alyst Mar 20, 2024
30e0b24
SemObservedCov: def as an alias of SemObservedData
alyst Jan 1, 2025
86c5e2d
SemObserved: store observed_vars
May 9, 2024
ef1861e
nsamples(observed::SemObserved): unify
May 9, 2024
1d573a3
FIML: simplify index generation
alyst Dec 25, 2024
b825667
SemObservedMissing: refactor
alyst Dec 25, 2024
a848ed3
remove cov_and_mean(): not used anymore
alyst Mar 18, 2024
c952792
SemObserved: unify data preparation
alyst Jan 1, 2025
2596c61
tests: update SemObserved tests
alyst Dec 28, 2024
80a64c9
prep_data: warn if obs_vars order don't match spec
alyst Jan 1, 2025
673aa2b
SemObsData: observed_var_prefix kwarg
alyst Dec 25, 2024
8c7cd14
ParTable: add graph-based kw-only constructor
Maximilian-Stefan-Ernst Jan 2, 2025
ff67cf7
Project.toml: fix ProximalAlgorithms to 0.5
alyst Jan 6, 2025
d3915c1
Merge pull request #230 from alyst/enhance_data_import
Maximilian-Stefan-Ernst Jan 9, 2025
e63d5d8
switch to ProximalAlgorithms.jl v0.7
alyst Jan 6, 2025
e2d6aa1
move params() to common.jl
alyst Aug 11, 2024
92b5741
RAM ctor: use random parameters instead of NaNs
Apr 1, 2024
ae2291a
move check_acyclic() to abstract.jl
alyst Jun 13, 2024
3175257
AbstractSem: improve imply/observed API redirect
alyst Dec 22, 2024
c8b1645
imply -> implied, SemImply -> SemImplied
alyst Jan 9, 2025
39aee3d
imply -> implied: file renames
alyst Dec 23, 2024
1fe165b
close #158
Maximilian-Stefan-Ernst Feb 2, 2025
e051d71
close #232
Maximilian-Stefan-Ernst Feb 2, 2025
03416eb
Merge pull request #240 from StructuralEquationModels/rename_sem_summary
Maximilian-Stefan-Ernst Feb 2, 2025
ba9390f
Merge pull request #235 from alyst/implied_rename
Maximilian-Stefan-Ernst Feb 2, 2025
8b0f880
Update ext/SEMProximalOptExt/ProximalAlgorithms.jl
Maximilian-Stefan-Ernst Feb 2, 2025
351fd70
Merge pull request #234 from alyst/prox_algo_07
Maximilian-Stefan-Ernst Feb 2, 2025
8c703d6
suppress uninformative warnings during package testing
Maximilian-Stefan-Ernst Feb 2, 2025
ba9d2c9
turn simplification of symbolic terms by default off
Maximilian-Stefan-Ernst Feb 3, 2025
cd6413b
new version of StenoGraph results in fewer deprication notices
aaronpeikert Feb 3, 2025
5bebe4e
Merge pull request #241 from StructuralEquationModels/test_warnings
Maximilian-Stefan-Ernst Feb 3, 2025
9244edf
Merge pull request #244 from StructuralEquationModels/make_simplify_o…
Maximilian-Stefan-Ernst Feb 3, 2025
f0df653
fix exporting structs from package extensions
Maximilian-Stefan-Ernst Feb 4, 2025
81a4bd9
fix NLopt extension
Maximilian-Stefan-Ernst Feb 4, 2025
9729819
fix Proximal extension
Maximilian-Stefan-Ernst Feb 4, 2025
127da26
fix printing
Maximilian-Stefan-Ernst Feb 4, 2025
f67d48c
fix regularization docs
Maximilian-Stefan-Ernst Feb 4, 2025
bcfae6a
Merge pull request #246 from StructuralEquationModels/fix_extensions
Maximilian-Stefan-Ernst Feb 4, 2025
0659738
Merge pull request #247 from StructuralEquationModels/devel
Maximilian-Stefan-Ernst Feb 4, 2025
e9dbb62
start reworking docs
Maximilian-Stefan-Ernst Feb 4, 2025
cca2496
finish rewriting docs
Maximilian-Stefan-Ernst Feb 4, 2025
b91f25a
rm ProximalSEM from docs deps
Maximilian-Stefan-Ernst Feb 4, 2025
56650e7
fix docs
Maximilian-Stefan-Ernst Feb 4, 2025
0f09635
fix docs
Maximilian-Stefan-Ernst Feb 4, 2025
5cc61bb
try to fix svgs for docs
Maximilian-Stefan-Ernst Feb 4, 2025
a4b7fe6
try to fix svgs for docs
Maximilian-Stefan-Ernst Feb 4, 2025
a8ae75c
Merge pull request #248 from StructuralEquationModels/documentation/0…
Maximilian-Stefan-Ernst Feb 4, 2025
b327012
update README
Maximilian-Stefan-Ernst Feb 4, 2025
4091804
bump version
Maximilian-Stefan-Ernst Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "StructuralEquationModels"
uuid = "383ca8c5-e4ff-4104-b0a9-f7b279deed53"
authors = ["Maximilian Ernst", "Aaron Peikert"]
version = "0.2.4"
version = "0.3.0"

[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Expand All @@ -12,7 +12,6 @@ LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
NLSolversBase = "d41bc354-129a-5804-8e4c-c37616107c6c"
NLopt = "76087f3c-5699-56af-9a33-bf431cd00edd"
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
Expand All @@ -25,8 +24,8 @@ Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"

[compat]
julia = "1.9, 1.10"
StenoGraphs = "0.2, 0.3"
julia = "1.9, 1.10, 1.11"
StenoGraphs = "0.2 - 0.3, 0.4.1 - 0.5"
DataFrames = "1"
Distributions = "0.25"
FiniteDiff = "2"
Expand All @@ -35,12 +34,21 @@ NLSolversBase = "7"
NLopt = "0.6, 1"
Optim = "1"
PrettyTables = "2"
ProximalAlgorithms = "0.7"
StatsBase = "0.33, 0.34"
Symbolics = "4, 5"
SymbolicUtils = "1.4 - 1.5"
Symbolics = "4, 5, 6"
SymbolicUtils = "1.4 - 1.5, 1.7, 2, 3"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]

[weakdeps]
NLopt = "76087f3c-5699-56af-9a33-bf431cd00edd"
ProximalAlgorithms = "140ffc9f-1907-541a-a177-7475e0a401e9"

[extensions]
SEMNLOptExt = "NLopt"
SEMProximalOptExt = "ProximalAlgorithms"
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ It is still *in development*.
Models you can fit include
- Linear SEM that can be specified in RAM (or LISREL) notation
- ML, GLS and FIML estimation
- Regularization
- Regularized SEM (Ridge, Lasso, L0, ...)
- Multigroup SEM
- Sums of arbitrary loss functions (everything the optimizer can handle).

Expand All @@ -35,6 +35,7 @@ The package makes use of
- Symbolics.jl for symbolically precomputing parts of the objective and gradients to generate fast, specialized functions.
- SparseArrays.jl to speed up symbolic computations.
- Optim.jl and NLopt.jl to provide a range of different Optimizers/Linesearches.
- ProximalAlgorithms.jl for regularization.
- FiniteDiff.jl and ForwardDiff.jl to provide gradients for user-defined loss functions.

# At the moment, we are still working on:
Expand Down
2 changes: 2 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
NLopt = "76087f3c-5699-56af-9a33-bf431cd00edd"
ProximalAlgorithms = "140ffc9f-1907-541a-a177-7475e0a401e9"
ProximalOperators = "a725b495-10eb-56fe-b38b-717eba820537"
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ makedocs(
"Developer documentation" => [
"Extending the package" => "developer/extending.md",
"Custom loss functions" => "developer/loss.md",
"Custom imply types" => "developer/imply.md",
"Custom implied types" => "developer/implied.md",
"Custom optimizer types" => "developer/optimizer.md",
"Custom observed types" => "developer/observed.md",
"Custom model types" => "developer/sem.md",
Expand Down
26 changes: 0 additions & 26 deletions docs/src/assets/concept.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 0 additions & 26 deletions docs/src/assets/concept_typed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/src/developer/extending.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Extending the package

As discussed in the section on [Model Construction](@ref), every Structural Equation Model (`Sem`) consists of four parts:
As discussed in the section on [Model Construction](@ref), every Structural Equation Model (`Sem`) consists of three (four with the optimizer) parts:

![SEM concept typed](../assets/concept_typed.svg)

Expand Down
98 changes: 98 additions & 0 deletions docs/src/developer/implied.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Custom implied types

We recommend to first read the part [Custom loss functions](@ref), as the overall implementation is the same and we will describe it here more briefly.

Implied types are of subtype `SemImplied`. To implement your own implied type, you should define a struct

```julia
struct MyImplied <: SemImplied
...
end
```

and a method to update!:

```julia
import StructuralEquationModels: objective!

function update!(targets::EvaluationTargets, implied::MyImplied, model::AbstractSemSingle, params)

if is_objective_required(targets)
...
end

if is_gradient_required(targets)
...
end
if is_hessian_required(targets)
...
end

end
```

As you can see, `update` gets passed as a first argument `targets`, which is telling us whether the objective value, gradient, and/or hessian are needed.
We can then use the functions `is_..._required` and conditional on what the optimizer needs, we can compute and store things we want to make available to the loss functions. For example, as we have seen in [Second example - maximum likelihood](@ref), the `RAM` implied type computes the model-implied covariance matrix and makes it available via `implied.Σ`.



Just as described in [Custom loss functions](@ref), you may define a constructor. Typically, this will depend on the `specification = ...` argument that can be a `ParameterTable` or a `RAMMatrices` object.

We implement an `ImpliedEmpty` type in our package that does nothing but serving as an `implied` field in case you are using a loss function that does not need any implied type at all. You may use it as a template for defining your own implied type, as it also shows how to handle the specification objects:

```julia
############################################################################################
### Types
############################################################################################
"""
Empty placeholder for models that don't need an implied part.
(For example, models that only regularize parameters.)

# Constructor

ImpliedEmpty(;specification, kwargs...)

# Arguments
- `specification`: either a `RAMMatrices` or `ParameterTable` object

# Examples
A multigroup model with ridge regularization could be specified as a `SemEnsemble` with one
model per group and an additional model with `ImpliedEmpty` and `SemRidge` for the regularization part.

# Extended help

## Interfaces
- `params(::RAMSymbolic) `-> Vector of parameter labels
- `nparams(::RAMSymbolic)` -> Number of parameters

## Implementation
Subtype of `SemImplied`.
"""
struct ImpliedEmpty{A, B, C} <: SemImplied
hessianeval::A
meanstruct::B
ram_matrices::C
end

############################################################################################
### Constructors
############################################################################################

function ImpliedEmpty(;specification, meanstruct = NoMeanStruct(), hessianeval = ExactHessian(), kwargs...)
return ImpliedEmpty(hessianeval, meanstruct, convert(RAMMatrices, specification))
end

############################################################################################
### methods
############################################################################################

update!(targets::EvaluationTargets, implied::ImpliedEmpty, par, model) = nothing

############################################################################################
### Recommended methods
############################################################################################

update_observed(implied::ImpliedEmpty, observed::SemObserved; kwargs...) = implied
```

As you see, similar to [Custom loss functions](@ref) we implement a method for `update_observed`.
87 changes: 0 additions & 87 deletions docs/src/developer/imply.md

This file was deleted.

Loading
Loading