GALAHAD LLST package#
purpose#
Given a real llst
package finds a minimizer of the linear
least-squares objective function
Factorization of matrices of the form
lstr
may be preferred.
See Section 4 of $GALAHAD/doc/llst.pdf for additional details.
method#
The required solution
The method is iterative, and proceeds in two phases.
Firstly, lower and upper bounds,
The dominant cost is the requirement that we solve a sequence of linear systems (2). This may be rewritten as
reference#
The method is the obvious adaptation to the linear least-squares problem of that described in detail in
H. S. Dollar, N. I. M. Gould and D. P. Robinson. ``On solving trust-region and other regularised subproblems in optimization’’. Mathematical Programming Computation 2(1) (2010) 21–57.
matrix storage#
The unsymmetric
Dense storage format:
The matrix
Dense by columns storage format:
The matrix
Sparse co-ordinate storage format:
Only the nonzero entries of the matrices are stored.
For the
Sparse row-wise storage format:
Again only the nonzero entries are stored, but this time
they are ordered so that those in row i appear directly before those
in row i+1. For the i-th row of
Sparse column-wise storage format:
Once again only the nonzero entries are stored, but this time
they are ordered so that those in column j appear directly before those
in column j+1. For the j-th column of
The symmetric
Dense storage format:
The matrix
Sparse co-ordinate storage format:
Only the nonzero entries of the matrices are stored.
For the
Sparse row-wise storage format:
Again only the nonzero entries are stored, but this time
they are ordered so that those in row i appear directly before those
in row i+1. For the i-th row of
Diagonal storage format:
If
Multiples of the identity storage format:
If
The identity matrix format:
If
The zero matrix format:
The same is true if
introduction to function calls#
To solve a given problem, functions from the llst package must be called in the following order:
llst_initialize - provide default control parameters and set up initial data structures
llst_read_specfile (optional) - override control values by reading replacement values from a file
llst_import - set up problem data structures and fixed values
llst_import_scaling (optional) - set up problem data structures for
if requiredllst_reset_control (optional) - possibly change control parameters if a sequence of problems are being solved
llst_solve_problem - solve the trust-region problem
llst_information (optional) - recover information about the solution and solution process
llst_terminate - deallocate data structures
See the examples section for illustrations of use.
callable functions#
overview of functions provided#
// typedefs typedef float spc_; typedef double rpc_; typedef int ipc_; // structs struct llst_control_type; struct llst_history_type; struct llst_inform_type; struct llst_time_type; // global functions void llst_initialize( void **data, struct llst_control_type* control, ipc_ *status ); void llst_read_specfile( struct llst_control_type* control, const char specfile[] ); void llst_import( struct llst_control_type* control, void **data, ipc_ *status, ipc_ m, ipc_ n, const char A_type[], ipc_ A_ne, const ipc_ A_row[], const ipc_ A_col[], const ipc_ A_ptr[] ); void llst_import_scaling( struct llst_control_type* control, void **data, ipc_ *status, ipc_ n, const char S_type[], ipc_ S_ne, const ipc_ S_row[], const ipc_ S_col[], const ipc_ S_ptr[] ); void llst_reset_control( struct llst_control_type* control, void **data, ipc_ *status ); void llst_solve_problem( void **data, ipc_ *status, ipc_ m, ipc_ n, const rpc_ radius, ipc_ A_ne, const rpc_ A_val[], const rpc_ b[], rpc_ x[], ipc_ S_ne, const rpc_ S_val[] ); void llst_information(void **data, struct llst_inform_type* inform, ipc_ *status); void llst_terminate( void **data, struct llst_control_type* control, struct llst_inform_type* inform );
typedefs#
typedef float spc_
spc_
is real single precision
typedef double rpc_
rpc_
is the real working precision used, but may be changed to float
by
defining the preprocessor variable REAL_32
or (if supported) to
__real128
using the variable REAL_128
.
typedef int ipc_
ipc_
is the default integer word length used, but may be changed to
int64_t
by defining the preprocessor variable INTEGER_64
.
function calls#
void llst_initialize( void **data, struct llst_control_type* control, ipc_ *status )
Set default control values and initialize private data
Parameters:
data |
holds private internal data |
control |
is a struct containing control information (see llst_control_type) |
status |
is a scalar variable of type ipc_, that gives the exit status from the package. Possible values are (currently):
|
void llst_read_specfile( struct llst_control_type* control, const char specfile[] )
Read the content of a specification file, and assign values associated with given keywords to the corresponding control parameters. An in-depth discussion of specification files is available, and a detailed list of keywords with associated default values is provided in $GALAHAD/src/llst/LLST.template. See also Table 2.1 in the Fortran documentation provided in $GALAHAD/doc/llst.pdf for a list of how these keywords relate to the components of the control structure.
Parameters:
control |
is a struct containing control information (see llst_control_type) |
specfile |
is a character string containing the name of the specification file |
void llst_import( struct llst_control_type* control, void **data, ipc_ *status, ipc_ m, ipc_ n, const char A_type[], ipc_ A_ne, const ipc_ A_row[], const ipc_ A_col[], const ipc_ A_ptr[] )
Import problem data into internal storage prior to solution.
Parameters:
control |
is a struct whose members provide control paramters for the remaining prcedures (see llst_control_type) |
data |
holds private internal data |
status |
is a scalar variable of type ipc_, that gives the exit status from the package. Possible values are:
|
m |
is a scalar variable of type ipc_, that holds the number of residuals, i.e., the number of rows of |
n |
is a scalar variable of type ipc_, that holds the number of variables, i.e., the number of columns of |
A_type |
is a one-dimensional array of type char that specifies the unsymmetric storage scheme used for the constraint Jacobian, |
A_ne |
is a scalar variable of type ipc_, that holds the number of entries in |
A_row |
is a one-dimensional array of size A_ne and type ipc_, that holds the row indices of |
A_col |
is a one-dimensional array of size A_ne and type ipc_, that holds the column indices of |
A_ptr |
is a one-dimensional array of size n+1 and type ipc_, that holds the starting position of each row of |
void llst_import_scaling( struct llst_control_type* control, void **data, ipc_ *status, ipc_ n, const char S_type[], ipc_ S_ne, const ipc_ S_row[], const ipc_ S_col[], const ipc_ S_ptr[] )
Import the scaling matrix
Parameters:
control |
is a struct whose members provide control paramters for the remaining prcedures (see llst_control_type) |
data |
holds private internal data |
status |
is a scalar variable of type ipc_, that gives the exit status from the package. Possible values are:
|
n |
is a scalar variable of type ipc_, that holds the number of variables, i.e., the number of rows and columns of |
S_type |
is a one-dimensional array of type char that specifies the symmetric storage scheme used for the matrix |
S_ne |
is a scalar variable of type ipc_, that holds the number of entries in the lower triangular part of |
S_row |
is a one-dimensional array of size S_ne and type ipc_, that holds the row indices of the lower triangular part of |
S_col |
is a one-dimensional array of size S_ne and type ipc_, that holds the column indices of the lower triangular part of |
S_ptr |
is a one-dimensional array of size n+1 and type ipc_, that holds the starting position of each row of the lower triangular part of |
void llst_reset_control( struct llst_control_type* control, void **data, ipc_ *status )
Reset control parameters after import if required.
Parameters:
control |
is a struct whose members provide control paramters for the remaining prcedures (see llst_control_type) |
data |
holds private internal data |
status |
is a scalar variable of type ipc_, that gives the exit status from the package. Possible values are:
|
void llst_solve_problem( void **data, ipc_ *status, ipc_ m, ipc_ n, const rpc_ radius, ipc_ A_ne, const rpc_ A_val[], const rpc_ b[], rpc_ x[], ipc_ S_ne, const rpc_ S_val[] )
Solve the trust-region problem.
Parameters:
data |
holds private internal data |
status |
is a scalar variable of type ipc_, that gives the entry and exit status from the package. Possible exit values are:
|
m |
is a scalar variable of type ipc_, that holds the number of residuals |
n |
is a scalar variable of type ipc_, that holds the number of variables |
radius |
is a scalar of type rpc_, that holds the trust-region radius, |
A_ne |
is a scalar variable of type ipc_, that holds the number of entries in the observation matrix |
A_val |
is a one-dimensional array of size A_ne and type rpc_, that holds the values of the entries of the observation matrix |
b |
is a one-dimensional array of size m and type rpc_, that holds the values |
x |
is a one-dimensional array of size n and type rpc_, that holds the values |
S_ne |
is a scalar variable of type ipc_, that holds the number of entries in the scaling matrix |
S_val |
is a one-dimensional array of size S_ne and type rpc_, that holds the values of the entries of the scaling matrix |
void llst_information(void **data, struct llst_inform_type* inform, ipc_ *status)
Provides output information
Parameters:
data |
holds private internal data |
inform |
is a struct containing output information (see llst_inform_type) |
status |
is a scalar variable of type ipc_, that gives the exit status from the package. Possible values are (currently):
|
void llst_terminate( void **data, struct llst_control_type* control, struct llst_inform_type* inform )
Deallocate all internal private storage
Parameters:
data |
holds private internal data |
control |
is a struct containing control information (see llst_control_type) |
inform |
is a struct containing output information (see llst_inform_type) |
available structures#
llst_control_type structure#
#include <galahad_llst.h> struct llst_control_type { // fields bool f_indexing; ipc_ error; ipc_ out; ipc_ print_level; ipc_ new_a; ipc_ new_s; ipc_ max_factorizations; ipc_ taylor_max_degree; rpc_ initial_multiplier; rpc_ lower; rpc_ upper; rpc_ stop_normal; bool equality_problem; bool use_initial_multiplier; bool space_critical; bool deallocate_error_fatal; char definite_linear_solver[31]; char prefix[31]; struct sbls_control_type sbls_control; struct sls_control_type sls_control; struct ir_control_type ir_control; };
detailed documentation#
control derived type as a C struct
components#
bool f_indexing
use C or Fortran sparse matrix indexing
ipc_ error
unit for error messages
ipc_ out
unit for monitor output
ipc_ print_level
controls level of diagnostic output
ipc_ new_a
how much of
0 unchanged
1 values but not indices have changed
2 values and indices have changed
ipc_ new_s
how much of
0 unchanged
1 values but not indices have changed
2 values and indices have changed
ipc_ max_factorizations
the maximum number of factorizations (=iterations) allowed. -ve implies no limit
ipc_ taylor_max_degree
maximum degree of Taylor approximant allowed (<= 3)
rpc_ initial_multiplier
initial estimate of the Lagrange multipler
rpc_ lower
lower and upper bounds on the multiplier, if known
rpc_ upper
see lower
rpc_ stop_normal
stop when
bool equality_problem
is the solution is <b<required to lie on the boundary (i.e., is the constraint an equality)?
bool use_initial_multiplier
ignore initial_multiplier?
bool space_critical
if space is critical, ensure allocated arrays are no bigger than needed
bool deallocate_error_fatal
exit if any deallocation fails
char definite_linear_solver[31]
the name of the definite linear equation solver used. Possible choices are currently: ‘sils’, ‘ma27’, ‘ma57’, ‘ma77’, ‘ma86’, ‘ma87’, ‘ma97’, ‘ssids’, ‘mumps’, ‘pardiso’, ‘mkl_pardiso’, ‘pastix’, ‘wsmp’, ‘potr’, ‘sytr’ and ‘pbtr’, although only ‘potr’, ‘sytr’, ‘pbtr’ and, for OMP 4.0-compliant compilers, ‘ssids’ are installed by default; others are easily installed (see README.external). More details of the capabilities of each solver are provided in the documentation for galahad_sls.
char prefix[31]
all output lines will be prefixed by prefix(2:LEN(TRIM(.prefix))-1) where prefix contains the required string enclosed in quotes, e.g. “string” or ‘string’
struct sbls_control_type sbls_control
control parameters for the symmetric factorization and related linear solves (see sbls_c documentation)
struct sls_control_type sls_control
control parameters for the factorization of S and related linear solves (see sls_c documentation)
struct ir_control_type ir_control
control parameters for iterative refinement for definite system solves (see ir_c documentation)
llst_time_type structure#
#include <galahad_llst.h> struct llst_time_type { // fields rpc_ total; rpc_ assemble; rpc_ analyse; rpc_ factorize; rpc_ solve; rpc_ clock_total; rpc_ clock_assemble; rpc_ clock_analyse; rpc_ clock_factorize; rpc_ clock_solve; };
detailed documentation#
time derived type as a C struct
components#
rpc_ total
total CPU time spent in the package
rpc_ assemble
CPU time assembling
rpc_ analyse
CPU time spent analysing
rpc_ factorize
CPU time spent factorizing
rpc_ solve
CPU time spent solving linear systems inolving
rpc_ clock_total
total clock time spent in the package
rpc_ clock_assemble
clock time assembling
rpc_ clock_analyse
clock time spent analysing
rpc_ clock_factorize
clock time spent factorizing
rpc_ clock_solve
clock time spent solving linear systems inolving
llst_history_type structure#
#include <galahad_llst.h> struct llst_history_type { // fields rpc_ lambda; rpc_ x_norm; rpc_ r_norm; };
detailed documentation#
history derived type as a C struct
components#
rpc_ lambda
the value of
rpc_ x_norm
the corresponding value of
rpc_ r_norm
the corresponding value of
llst_inform_type structure#
#include <galahad_llst.h> struct llst_inform_type { // fields ipc_ status; ipc_ alloc_status; ipc_ factorizations; ipc_ len_history; rpc_ r_norm; rpc_ x_norm; rpc_ multiplier; char bad_alloc[81]; struct llst_time_type time; struct llst_history_type history[100]; struct sbls_inform_type sbls_inform; struct sls_inform_type sls_inform; struct ir_inform_type ir_inform; };
detailed documentation#
inform derived type as a C struct
components#
ipc_ status
reported return status:
0
the solution has been found
-1
an array allocation has failed
-2
an array deallocation has failed
-3
n and/or Delta is not positive
-10
the factorization of
failed-15
does not appear to be strictly diagonally dominant-16
ill-conditioning has prevented furthr progress
ipc_ alloc_status
STAT value after allocate failure.
ipc_ factorizations
the number of factorizations performed
ipc_ len_history
the number of (
rpc_ r_norm
corresponding value of the two-norm of the residual,
rpc_ x_norm
the S-norm of x,
rpc_ multiplier
the Lagrange multiplier corresponding to the trust-region constraint
char bad_alloc[81]
name of array which provoked an allocate failure
struct llst_time_type time
time information
struct llst_history_type history[100]
history information
struct sbls_inform_type sbls_inform
information from the symmetric factorization and related linear solves (see sbls_c documentation)
struct sls_inform_type sls_inform
information from the factorization of S and related linear solves (see sls_c documentation)
struct ir_inform_type ir_inform
information from the iterative refinement for definite system solves (see ir_c documentation)
example calls#
This is an example of how to use the package to solve a linear least-squares trust-region subproblem; the code is available in $GALAHAD/src/llst/C/llstt.c . A variety of supported Hessian and constraint matrix storage formats are shown.
Notice that C-style indexing is used, and that this is flagged by setting
control.f_indexing
to false
. The floating-point type rpc_
is set in galahad_precision.h
to double
by default, but to float
if the preprocessor variable SINGLE
is defined. Similarly, the integer
type ipc_
from galahad_precision.h
is set to int
by default,
but to int64_t
if the preprocessor variable INTEGER_64
is defined.
/* llsttf.c */
/* Full test for the LLST C interface using C sparse matrix indexing */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "galahad_precision.h"
#include "galahad_cfunctions.h"
#include "galahad_llst.h"
#ifdef REAL_128
#include <quadmath.h>
#endif
int main(void) {
// Derived types
void *data;
struct llst_control_type control;
struct llst_inform_type inform;
ipc_ i, l;
// Set problem data
// set dimensions
ipc_ m = 100;
ipc_ n = 2*m+1;
// A = ( I : Diag(1:n) : e )
ipc_ A_ne = 3*m;
ipc_ A_row[A_ne];
ipc_ A_col[A_ne];
ipc_ A_ptr[m+1];
rpc_ A_val[A_ne];
// store A in sparse formats
l=0;
for( i=0; i < m; i++){
A_ptr[i] = l;
A_row[l] = i;
A_col[l] = i;
A_val[l] = 1.0;
l++;
A_row[l] = i;
A_col[l] = m+i;
A_val[l] = i+1;
l++;
A_row[l] = i;
A_col[l] = n-1;
A_val[l] = 1.0;
l++;
}
A_ptr[m] = l;
// store A in dense format
ipc_ A_dense_ne = m * n;
rpc_ A_dense_val[A_dense_ne];
for( i=0; i < A_dense_ne; i++) A_dense_val[i] = 0.0;
l=-1;
for( i=1; i <= m; i++){
A_dense_val[l+i] = 1.0;
A_dense_val[l+m+i] = i;
A_dense_val[l+n] = 1.0;
l=l+n;
}
// S = diag(1:n)**2
ipc_ S_ne = n;
ipc_ S_row[S_ne];
ipc_ S_col[S_ne];
ipc_ S_ptr[n+1];
rpc_ S_val[S_ne];
// store S in sparse formats
for( i=0; i < n; i++){
S_row[i] = i;
S_col[i] = i;
S_ptr[i] = i;
S_val[i] = (i+1)*(i+1);
}
S_ptr[n] = n;
// store S in dense format
ipc_ S_dense_ne = n*(n+1)/2;
rpc_ S_dense_val[S_dense_ne];
for( i=0; i < S_dense_ne; i++) S_dense_val[i] = 0.0;
l=-1;
for( i=1; i <= n; i++){
S_dense_val[l+i] = i*i;
l=l+i;
}
// b is a vector of ones
rpc_ b[m]; // observations
for( i=0; i < m; i++){
b[i] = 1.0;
}
// trust-region radius is one
rpc_ radius = 1.0;
// Set output storage
rpc_ x[n]; // solution
char st = ' ';
ipc_ status;
printf(" C sparse matrix indexing\n\n");
printf(" basic tests of problem storage formats\n\n");
// loop over storage formats
for( ipc_ d=1; d<=4; d++){
// Initialize LLST
llst_initialize( &data, &control, &status );
strcpy(control.definite_linear_solver, "potr ") ;
strcpy(control.sbls_control.symmetric_linear_solver, "sytr ") ;
strcpy(control.sbls_control.definite_linear_solver, "potr ") ;
// control.print_level = 1;
// Set user-defined control options
control.f_indexing = false; // C sparse matrix indexing
// use s or not (1 or 0)
for( ipc_ use_s=0; use_s<=1; use_s++){
switch(d){
case 1: // sparse co-ordinate storage
st = 'C';
llst_import( &control, &data, &status, m, n,
"coordinate", A_ne, A_row, A_col, NULL );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, 0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"coordinate", S_ne, S_row,
S_col, NULL );
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, S_ne, S_val );
}
break;
case 2: // sparse by rows
st = 'R';
llst_import( &control, &data, &status, m, n,
"sparse_by_rows", A_ne, NULL, A_col, A_ptr );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, 0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"sparse_by_rows", S_ne, NULL,
S_col, S_ptr );
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, S_ne, S_val );
}
break;
case 3: // dense
st = 'D';
llst_import( &control, &data, &status, m, n,
"dense", A_dense_ne, NULL, NULL, NULL );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_dense_ne, A_dense_val, b, x,
0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"dense", S_dense_ne,
NULL, NULL, NULL );
llst_solve_problem( &data, &status, m, n, radius,
A_dense_ne, A_dense_val, b, x,
S_dense_ne, S_dense_val );
}
break;
case 4: // diagonal
st = 'I';
llst_import( &control, &data, &status, m, n,
"coordinate", A_ne, A_row, A_col, NULL );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, 0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"diagonal", S_ne, NULL, NULL, NULL );
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, S_ne, S_val );
}
break;
}
llst_information( &data, &inform, &status );
if(inform.status == 0){
#ifdef REAL_128
// interim replacement for quad output: $GALAHAD/include/galahad_pquad_lf.h
#include "galahad_pquad_lf.h"
#else
printf("storage type %c%1" i_ipc_ ": status = %1" i_ipc_
", ||r|| = %5.2f\n",
st, use_s, inform.status, inform.r_norm );
#endif
}else{
printf("storage type %c%1" i_ipc_
": LLST_solve exit status = %1" i_ipc_ "\n",
st, use_s, inform.status);
}
}
//printf("x: ");
//for( ipc_ i = 0; i < n; i++) printf("%f ", x[i]);
//printf("\n");
// Delete internal workspace
llst_terminate( &data, &control, &inform );
}
}
This is the same example, but now fortran-style indexing is used; the code is available in $GALAHAD/src/llst/C/llsttf.c .
/* llsttf.c */
/* Full test for the LLST C interface using Fortran sparse matrix indexing */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "galahad_precision.h"
#include "galahad_cfunctions.h"
#include "galahad_llst.h"
#ifdef REAL_128
#include <quadmath.h>
#endif
int main(void) {
// Derived types
void *data;
struct llst_control_type control;
struct llst_inform_type inform;
ipc_ i, l;
// Set problem data
// set dimensions
ipc_ m = 100;
ipc_ n = 2*m+1;
// A = ( I : Diag(1:n) : e )
ipc_ A_ne = 3*m;
ipc_ A_row[A_ne];
ipc_ A_col[A_ne];
ipc_ A_ptr[m+1];
rpc_ A_val[A_ne];
// store A in sparse formats
l=0;
for( i=1; i <= m; i++){
A_ptr[i-1] = l+1;
A_row[l] = i;
A_col[l] = i;
A_val[l] = 1.0;
l++;
A_row[l] = i;
A_col[l] = m+i;
A_val[l] = i;
l++;
A_row[l] = i;
A_col[l] = n;
A_val[l] = 1.0;
l++;
}
A_ptr[m] = l+1;
// store A in dense format
ipc_ A_dense_ne = m * n;
rpc_ A_dense_val[A_dense_ne];
for( i=0; i < A_dense_ne; i++) A_dense_val[i] = 0.0;
l=-1;
for( i=1; i <= m; i++){
A_dense_val[l+i] = 1.0;
A_dense_val[l+m+i] = i;
A_dense_val[l+n] = 1.0;
l=l+n;
}
// S = diag(1:n)**2
ipc_ S_ne = n;
ipc_ S_row[S_ne];
ipc_ S_col[S_ne];
ipc_ S_ptr[n+1];
rpc_ S_val[S_ne];
// store S in sparse formats
for( i=0; i < n; i++){
S_row[i] = i+1;
S_col[i] = i+1;
S_ptr[i] = i+1;
S_val[i] = (i+1)*(i+1);
}
S_ptr[n] = n+1;
// store S in dense format
ipc_ S_dense_ne = n*(n+1)/2;
rpc_ S_dense_val[S_dense_ne];
for( i=0; i < S_dense_ne; i++) S_dense_val[i] = 0.0;
l=-1;
for( i=1; i <= n; i++){
S_dense_val[l+i] = i*i;
l=l+i;
}
// b is a vector of ones
rpc_ b[m]; // observations
for( i=0; i < m; i++){
b[i] = 1.0;
}
// trust-region radius is one
rpc_ radius = 1.0;
// Set output storage
rpc_ x[n]; // solution
char st = ' ';
ipc_ status;
printf(" Fortran sparse matrix indexing\n\n");
printf(" basic tests of problem storage formats\n\n");
// loop over storage formats
for( ipc_ d=1; d<=4; d++){
// Initialize LLST
llst_initialize( &data, &control, &status );
strcpy(control.definite_linear_solver, "potr ") ;
strcpy(control.sbls_control.symmetric_linear_solver, "sytr ") ;
strcpy(control.sbls_control.definite_linear_solver, "potr ") ;
// control.print_level = 1;
// Set user-defined control options
control.f_indexing = true; // Fortran sparse matrix indexing
// use s or not (1 or 0)
for( ipc_ use_s=0; use_s<=1; use_s++){
switch(d){
case 1: // sparse co-ordinate storage
st = 'C';
llst_import( &control, &data, &status, m, n,
"coordinate", A_ne, A_row, A_col, NULL );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, 0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"coordinate", S_ne, S_row,
S_col, NULL );
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, S_ne, S_val );
}
break;
case 2: // sparse by rows
st = 'R';
llst_import( &control, &data, &status, m, n,
"sparse_by_rows", A_ne, NULL, A_col, A_ptr );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, 0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"sparse_by_rows", S_ne, NULL,
S_col, S_ptr );
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, S_ne, S_val );
}
break;
case 3: // dense
st = 'D';
llst_import( &control, &data, &status, m, n,
"dense", A_dense_ne, NULL, NULL, NULL );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_dense_ne, A_dense_val, b, x,
0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"dense", S_dense_ne,
NULL, NULL, NULL );
llst_solve_problem( &data, &status, m, n, radius,
A_dense_ne, A_dense_val, b, x,
S_dense_ne, S_dense_val );
}
break;
case 4: // diagonal
st = 'I';
llst_import( &control, &data, &status, m, n,
"coordinate", A_ne, A_row, A_col, NULL );
if(use_s == 0){
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, 0, NULL );
}else{
llst_import_scaling( &control, &data, &status, n,
"diagonal", S_ne, NULL, NULL, NULL );
llst_solve_problem( &data, &status, m, n, radius,
A_ne, A_val, b, x, S_ne, S_val );
}
break;
}
llst_information( &data, &inform, &status );
if(inform.status == 0){
#ifdef REAL_128
// interim replacement for quad output: $GALAHAD/include/galahad_pquad_lf.h
#include "galahad_pquad_lf.h"
#else
printf("storage type %c%1" i_ipc_ ": status = %1" i_ipc_
", ||r|| = %5.2f\n",
st, use_s, inform.status, inform.r_norm );
#endif
}else{
printf("storage type %c%1" i_ipc_
": LLST_solve exit status = %1" i_ipc_ "\n",
st, use_s, inform.status);
}
}
//printf("x: ");
//for( ipc_ i = 0; i < n; i++) printf("%f ", x[i]);
//printf("\n");
// Delete internal workspace
llst_terminate( &data, &control, &inform );
}
}