NAG Library Manual, Mark 28.4
```/* nag_opt_lp_solve (e04mfc) Example Program.
*
* Copyright 2022 Numerical Algorithms Group.
*
* Mark 28.4, 2022.
*/

/* This sample linear program (LP) is a portfolio investment problem
* (see Chapter 7, pp 258--262 of ``Numerical Linear Algebra and
* Optimization'', by Gill, Murray and Wright, Addison Wesley, 1991).
* The problem involves the rearrangement of a portfolio of three
* stocks, Glitter, Risky and Trusty, so that the net worth of the
* investor is maximized.
* The problem is characterized by the following data:
*                           Glitter     Risky        Trusty
* 1990 Holdings                75       1000           25
* 1990 Priceshare(\$)           20          2          100
* 2099 Priceshare(\$)           18          3          102
* 2099 Dividend                 5          0            2
*
* The variables x[0], x[1] and x[2] represent the change in each of
* the three stocks.
*/

#include <nag.h>
#include <stdio.h>

#define A(I, J) a[(I)*tda + J]

int main(void) {
const char *optionsfile = "e04mfce.opt";
Integer exit_status = 0;
Nag_Boolean print;
Integer n, nbnd, nclin, tda;
Nag_E04_Opt options;
double *a = 0, bigbnd, *bl = 0, *bu = 0, *cvec = 0, objf, *x = 0;
Nag_Comm comm;
NagError fail;

INIT_FAIL(fail);

printf("nag_opt_lp_solve (e04mfc) Example Program Results\n");
/* Set the actual problem dimensions.
* n      = the number of variables.
* nclin  = the number of general linear constraints (may be 0).
*/
n = 3;
nclin = 5;
nbnd = n + nclin;
if (n >= 1 && nclin >= 0) {
if (!(x = NAG_ALLOC(n, double)) || !(cvec = NAG_ALLOC(n, double)) ||
!(a = NAG_ALLOC(nclin * n, double)) ||
!(bl = NAG_ALLOC(nbnd, double)) || !(bu = NAG_ALLOC(nbnd, double))) {
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
tda = n;
} else {
printf("Invalid n or nclin.\n");
exit_status = 1;
return exit_status;
}

/* Define the value used to denote ``infinite'' bounds. */
bigbnd = 1e+25;

/* Objective function:  maximize  5*X[0] + 2*X[2], or equivalently,
* minimize -5*X[0] - 2*X[2].
*/
cvec[0] = -5.0;
cvec[1] = 0.0;
cvec[2] = -2.0;

/* a  = the general constraint matrix.
* bl = the lower bounds on  x  and  A*x.
* bu = the upper bounds on  x  and  A*x.
* x  = the initial estimate of the solution.
*
* A nonnegative amount of stock must be present after rearrangement.
* For Glitter:  x[0] + 75 >= 0.
*/
bl[0] = -75.0;
bu[0] = bigbnd;

/* For Risky:    x[1] + 1000 >= 0.0 */
bl[1] = -1000.0;
bu[1] = bigbnd;

/* For Trusty:   x[2] + 25 >= 0.0 */
bl[2] = -25.0;
bu[2] = bigbnd;

/* The current value of the portfolio must be the same after
* rearrangement, i.e.,
*  20*(75+x[0]) + 2*(1000+x[1]) + 100*(25+x[2]) = 6000, or
*  20*x[0] + 2*x[1] + 100*x[2] = 0.
*/
A(0, 0) = 20.0;
A(0, 1) = 2.0;
A(0, 2) = 100.0;
bl[n] = 0.0;
bu[n] = 0.0;

/* The value of the portfolio must increase by at least 5 per cent
* at the end of the year, i.e.,
* 18*(75+x[0]) + 3*(1000+x[1]) + 102*(25+x[2]) >= 6300, or
* 18*x[0] + 3*x[1] + 102*x[2] >= -600.
*/
A(1, 0) = 18.0;
A(1, 1) = 3.0;
A(1, 2) = 102.0;
bl[n + 1] = -600.0;
bu[n + 1] = bigbnd;

/* There are three ``balanced portfolio'' constraints.  The value of
* a stock must constitute at least a quarter of the total final
* value of the portfolio.  After rearrangement, the value of the
* portfolio after is  20*(75+x[0]) + 2*(1000+x[1]) + 100*(25+x[2]).
*
* If Glitter is to constitute at least a quarter of the final
* portfolio, then  15*x[0] - 0.5*x[1] - 25*x[2] >= 0.
*/
A(2, 0) = 15.0;
A(2, 1) = -0.5;
A(2, 2) = -25.0;
bl[n + 2] = 0.0;
bu[n + 2] = bigbnd;

/* If Risky is to constitute at least a quarter of the final
* portfolio, then  -5*x[0] + 1.5*x[1] - 25*x[2] >= -500.
*/
A(3, 0) = -5.0;
A(3, 1) = 1.5;
A(3, 2) = -25.0;
bl[n + 3] = -500.0;
bu[n + 3] = bigbnd;

/* If Trusty is to constitute at least a quarter of the final
* portfolio, then  -5*x[0] - 0.5*x[1] + 75*x[2] >= -1000.
*/
A(4, 0) = -5.0;
A(4, 1) = -0.5;
A(4, 2) = 75.0;
bl[n + 4] = -1000.0;
bu[n + 4] = bigbnd;

/* Set the initial estimate of the solution.
* This portfolio is infeasible.
*/
x[0] = 10.0;
x[1] = 20.0;
x[2] = 100.0;

/* Initialize options structure to null values. */
/* nag_opt_init (e04xxc).
* Initialization function for option setting
*/
nag_opt_init(&options);
options.inf_bound = bigbnd;

/* Solve the problem. */
/* nag_opt_lp_solve (e04mfc), see above. */
fflush(stdout);
nag_opt_lp_solve(n, nclin, a, tda, bl, bu, cvec, x, &objf, &options, &comm,
&fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_opt_lp_solve (e04mfc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

/* Re-solve the problem with some additonal options. */

printf("Re-solve problem with output of iteration results");
printf(" suppressed and ftol = 1.0e-10.\n");

print = Nag_TRUE;
* Read options from a text file
*/
fflush(stdout);
nag_opt_read("e04mfc", optionsfile, &options, print, "stdout", &fail);
if (fail.code != NE_NOERROR) {
exit_status = 1;
goto END;
}

/* Reset starting point */
x[0] = 0.0;
x[1] = 0.0;
x[2] = 0.0;

/* Solve the problem again. */
/* nag_opt_lp_solve (e04mfc), see above. */
nag_opt_lp_solve(n, nclin, a, tda, bl, bu, cvec, x, &objf, &options, &comm,
&fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_opt_lp_solve (e04mfc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

/* Free memory allocated by nag_opt_lp_solve (e04mfc) to pointers in options.
*/
/* nag_opt_free (e04xzc).
* Memory freeing function for use with option setting
*/
nag_opt_free(&options, "all", &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_opt_free (e04xzc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}

END:
NAG_FREE(x);
NAG_FREE(cvec);
NAG_FREE(a);
NAG_FREE(bl);
NAG_FREE(bu);

return exit_status;
}
```