# 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

classweight_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:

successboolwhether solver was successful

betaarray (p,)solution

classweight_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 kin data to infil/ direc

create fortran input file nn.in

Get weights and chi2 from

`nn_orbmat.out`

Read chi2 values from nn_kinem.out

Read

`nn_orbmat.out`

Read

`nn_orb.out`

to astropy table

`solve`

([orblib])Main method to solve NNLS problem.

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 tablethis 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)¶Main method to solve NNLS problem.

- Parameters:

orblibdyn.OrbitLibraryThis 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

- 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

classweight_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_solverstringeither

`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 aperture+intrinsic mass constraits from MGE

`solve`

(orblib)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`

objectorb_losvd`dyn.kinematics.Histogram`

historgram of orblib losvds

orb_gharrayarray 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:

orblib`dyn.orblib.OrbitLibrary`

an orbit library

- Returns:

- tuple
(orbmat, rhs)

- get_observed_mass_constraints()¶
Get aperture+intrinsic mass constraits from MGE

- 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)¶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.OrbitLibrarymust have attributes losvd_histograms, intrinsic_masses, and projected_masses

- 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

classweight_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`

objectdirectory_with_mlstringmodel directory with the ml extension

CRcutBool, default Falsewhether to use the CRcut solution for the counter-rotating orbit problem. See Zhu et al. 2018 for more.

Methods:

`chi2_kinmap`

(weights)Returns the chi2 directly calculated from the gh kinematic maps.

`solve`

(orblib)Template solve method

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:

weights`numpy.array`

likeThe model’s orbital weights.

- Returns:

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

- solve(
orblib)¶Template solve method

Specific implementations should override this.

- Parameters:

orblibdyn.OrbitLibrary object- Returns:

weightsarrayorbit weights

chi2_allfloata total chi2 value

chi2_kinfloata chi2 value purely for kinematics

chi2_kinmapfloatdirectly 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.