Weight Solver

Classes related to solving for orbital weights. WeightSolver is a generic parent class, specific implementations are sub-classes of this.

API

Classes:

CvxoptNonNegSolver([P, q])

Solver for NNLS problem using CVXOPT

LegacyWeightSolver(**kwargs)

Use legacy AKA Fortran weight solving.

NNLS([nnls_solver])

Python implementations of NNLS weight solving

WeightSolver(config, directory_with_ml[, CRcut])

Generic WeightSolver class

class weight_solvers.CvxoptNonNegSolver(P=None, q=None)

Solver for NNLS problem using CVXOPT

Solves the QP problem:

argmin (1/2 beta^T P beta + q beta T) subject to (component-wise) beta > 0

Parameters:
Parray (p, p)

quadratic part of objective function

qarray (p,)

linear part of objective function

Attributes:
successbool

whether solver was successful

betaarray (p,)

solution

class weight_solvers.LegacyWeightSolver(**kwargs)

Use legacy AKA Fortran weight solving.

Uses the legcay_fortran program triaxnnls_CRcut.f90 or `triaxnnls_noCRcut.f90. Uses Lawson and Hanson non-negative least-squares algorithm.

Methods:

copy_kinematic_data()

Copy kin data to infil/ direc

create_fortran_input_nnls()

create fortran input file nn.in

get_weights_and_chi2_from_orbmat_file()

Get weights and chi2 from nn_orbmat.out

read_chi2()

Read chi2 values from nn_kinem.out

read_nnls_orbmat_rhs_and_solution()

Read nn_orbmat.out

read_weights()

Read nn_orb.out to astropy table

solve([orblib, ignore_existing_weights])

Main method to solve NNLS problem.

write_executable_for_weight_solver()

write executable bash script file

copy_kinematic_data()

Copy kin data to infil/ direc

create_fortran_input_nnls()

create fortran input file nn.in

Parameters:
None
Returns:
None
get_weights_and_chi2_from_orbmat_file()

Get weights and chi2 from nn_orbmat.out

Note: Chi2 values returned differ from read_chi2 method. See that docstring for more.

Returns:
tuple

(weights, chi2_all, chi2_gh), where:

  • weights : array of orbit weights

  • chi2_all : sum of squared residuals for intrinsic masses, projected_masses and GH coefficients h_1 to h_n

  • chi2_kin : sum of squared residuals for GH coefficients h_1 to h_n

read_chi2()

Read chi2 values from nn_kinem.out

Taken from old schwpy code, lines 181-212 of schw_domoditer.py

Note: This is a legacy method for reading legacy output and it not used by default. Instead we use self.get_chi2_from_orbmat get chi2 values. The chi2 value definitions of this method are NOT the same chi2 values given by self.get_chi2_from_orbmat. They differ in (i) including intrinsic/projected mass constraints, and (ii) using h1/h2 vs V/sigma, and (iii) if CRcut==True, whether the ‘cut’ orbits - with artificially large h1 - are included (here they aren’t)

Returns:
tuple
(chi2, kinchi2) where:
  • chi2 = sum of sq. residuals of observed GH coefficients h_1 to h_N

  • kinchi2 = sum of sq. residuals of V, sigma, and GH coefficients from h_3 to h_N

read_nnls_orbmat_rhs_and_solution()

Read nn_orbmat.out

This contains the matrix and right-hand-side for the NNLS problem, and the solution

Returns:
tuple

(orbmat, rhs, solution)

read_weights()

Read nn_orb.out to astropy table

this contains oribtal weights, orbit type, and other columns

Returns:
None

sets self.weights which is an astropy table containing the orbital weights

solve(orblib=None, ignore_existing_weights=False)

Main method to solve NNLS problem.

Parameters:
orblibdyn.OrbitLibrary

This parameter is not used in this Legacy implementation (as all orbit library information is read from files). It is included here for consistency with later WeightSolver implementations

ignore_existing_weightsbool

If True, do not check for already existing weights and solve again. Default is False.

Returns:
tuple
(weights, chi2_all, chi2_kin, chi2_kinmap) where:
  • weights : array, of orbit weights

  • chi2_all : float, sum of squared residuals for intrinsic masses, projected_masses and GH coefficients from h_1 to h_n

  • chi2_kin : float sum of squared residuals for GH coefficients h_1 to h_n

  • chi2_kinmap : directly calculates the chi2 from the kinematic maps

write_executable_for_weight_solver()

write executable bash script file

Parameters:
None
Returns:
string

the name of the bash script file to execute

class weight_solvers.NNLS(nnls_solver=None, **kwargs)

Python implementations of NNLS weight solving

Uses either scipy.optimize.nnls or cvxopt as backends. This constructs the NNLS matrix and rhs, solves, and saves the result.

Parameters:
nnls_solverstring

either scipy or cvxopt

Methods:

apply_CR_cut(kins, orb_losvd, orb_gh)

apply CRcut

construct_nnls_matrix_and_rhs(orblib)

construct nnls matrix_and rhs

get_observed_mass_constraints([kins, pops])

Get aperture+intrinsic mass constraints from MGE

solve(orblib[, ignore_existing_weights])

Solve for orbit weights

apply_CR_cut(kins, orb_losvd, orb_gh)

apply CRcut

to solve the counter rotating orbit problem. This cuts orbits which have \(|V - V_\mathrm{obs}|> 3\sigma_\mathrm{obs}\). See Zhu+2018 MNRAS 2018 473 3000 for details

Parameters:
kinsa dyn.kinematics.Kinematic object
orb_losvddyn.kinematics.Histogram

historgram of orblib losvds

orb_gharray

array of input gh expansion coefficients, before the CRcut

Returns:
array

array of input gh expansion coefficients, after the CRcut

construct_nnls_matrix_and_rhs(orblib)

construct nnls matrix_and rhs

Parameters:
orblibdyn.orblib.OrbitLibrary

an orbit library

Returns:
tuple

(orbmat, rhs)

get_observed_mass_constraints(kins=True, pops=False)

Get aperture+intrinsic mass constraints from MGE

Parameters:
kinsBool

If True, returns the projected masses of the MGE for the kinematic data apertures.

popsBool

If True, returns the projected masses of the MGE for the population data apertures. If both kins and pops are True, population data is returned following kinematic data.

Returns:
None

sets attributes:

  • self.intrinsic_masses

  • self.intrinsic_mass_error

  • self.projected_masses

  • self.projected_mass_error

  • constraint counts self.n_intrinsic, self.n_apertures and self.n_mass_constraints

solve(orblib, ignore_existing_weights=False)

Solve for orbit weights

Note: the returned chi2 values are not the same as LegacyWeightSolver.read_chi2 - see the docstring for more info

Parameters:
orblibdyn.OrbitLibrary
ignore_existing_weightsbool

If True, do not check for already existing weights and solve again. Default is False.

Returns:
tuple
(weights, chi2_all, chi2_kin, chi2_kinmap) where:
  • weights : array, of orbit weights

  • chi2_all : float, sum of squared residuals for intrinsic masses, projected_masses and GH coefficients from h_1 to h_n

  • chi2_kin : float sum of squared residuals for GH coefficients h_1 to h_n

  • chi2_kinmap : directly calculates the chi2 from the kinematic maps

class weight_solvers.WeightSolver(config, directory_with_ml, CRcut=False)

Generic WeightSolver class

Specific implementations are defined as sub-classes. Each one should have a main method solve

Parameters:
configa dyn.config_reader.Configuration object
directory_with_mlstring

model directory with the ml extension

CRcutBool, default False

whether to use the CRcut solution for the counter-rotating orbit problem. See Zhu et al. 2018 for more. If CRcut is given in the configuration file’s weight solver settings (which is normally the case), this parameter is ignored.

Methods:

chi2_kinmap(weights)

Returns the chi2 directly calculated from the gh kinematic maps.

solve(orblib[, ignore_existing_weights])

Template solve method

weight_file_exists()

Check whether the file(s) holding the current model's weights exist.

chi2_kinmap(weights)

Returns the chi2 directly calculated from the gh kinematic maps.

For each kinematic set, the following applies: If number_GH in the weight_solver_settings is smaller than the number of GH coefficients in the data file, only number_GH coefficients will be considered. If number_GH is greater than the number of GH coefficients in the data file, only the coefficients in the data file will be considered.

Does only work with Gauss Hermite kinematics.

Parameters:
weightsnumpy.array like

The model’s orbital weights.

Returns:
chi2_kinmapfloat

chi2 directly calculated from the kinematic maps: sum of squared residuals of V, sigma, and GH coefficients from h_3 to h_N

solve(orblib, ignore_existing_weights=False)

Template solve method

Specific implementations should override this.

Parameters:
orblibdyn.OrbitLibrary object
ignore_existing_weightsbool

If True, do not check for already existing weights and solve again. Default is False.

Returns:
weightsarray

orbit weights

chi2_allfloat

a total chi2 value

chi2_kinfloat

a chi2 value purely for kinematics

chi2_kinmapfloat

directly calculates the chi2 from the kinematic maps

weight_file_exists()

Check whether the file(s) holding the current model’s weights exist.

May be re-implemented by sub-classes.

Returns:
bool

True if weight solving data exists, False otherwise.

Inheritance Diagram

Inheritance diagram of weight_solvers