source: branches/sandbox/Cbc/src/CbcLinkedUtils.cpp @ 1387

Last change on this file since 1387 was 1387, checked in by lou, 10 years ago

This commit removes remaining code associated with NEW_STYLE_SOLVER. See the notes in CbcLinkedUtils? for why the remaining code remains.

File size: 24.8 KB
Line 
1// Copyright (C) 2007, International Business Machines
2// Corporation and others.  All Rights Reserved.
3/* $Id$ */
4
5/*! \file CbcAugmentClpSimplex.cpp
6    \brief Hooks to Ampl (for CbcLinked)
7
8    This code is a condensation of ClpAmplStuff.cpp, renamed to better
9    reflect its current place in cbc.
10
11  The code here had ties to NEW_STYLE_SOLVER code. During the 091209 Watson
12  meeting, NEW_STYLE_SOLVER code was eliminated. The code here was condensed
13  from ClpAmplStuff.cpp. The hook into CbcLinked is loadNonLinear. Once you
14  bring that in, all the rest follows. Still, we're down about 400 lines of
15  code. In the process, it appears that ClpAmplObjective.cpp was never needed
16  here; the code was hooked into ClpAmplStuff.cpp.  --lh, 091209 --
17*/
18
19#include "ClpConfig.h"
20#include "CbcConfig.h"
21#ifdef COIN_HAS_ASL
22#include "CoinPragma.hpp"
23#include "CoinHelperFunctions.hpp"
24#include "CoinIndexedVector.hpp"
25#include "ClpFactorization.hpp"
26#include "ClpSimplex.hpp"
27#include "ClpAmplObjective.hpp"
28#include "ClpConstraintAmpl.hpp"
29#include "ClpMessage.hpp"
30#include "CoinUtilsConfig.h"
31#include "CoinHelperFunctions.hpp"
32#include "CoinWarmStartBasis.hpp"
33#include "OsiSolverInterface.hpp"
34#include "CbcSolver.hpp"
35#include "Cbc_ampl.h"
36#include "CoinTime.hpp"
37#include "CglStored.hpp"
38#include "CoinModel.hpp"
39#include "CbcLinked.hpp"
40
41extern "C" {
42    //# include "getstub.h"
43# include "asl_pfgh.h"
44}
45
46// stolen from IPopt with changes
47typedef struct {
48    double obj_sign_;
49    ASL_pfgh * asl_;
50    double * non_const_x_;
51    int * column_; // for jacobian
52    int * rowStart_;
53    double * gradient_;
54    double * constraintValues_;
55    int nz_h_full_; // number of nonzeros in hessian
56    int nerror_;
57    bool objval_called_with_current_x_;
58    bool conval_called_with_current_x_;
59    bool jacval_called_with_current_x_;
60} CbcAmplInfo;
61
62//#############################################################################
63// Constructors / Destructor / Assignment
64//#############################################################################
65
66//-------------------------------------------------------------------
67// Default Constructor
68//-------------------------------------------------------------------
69ClpAmplObjective::ClpAmplObjective ()
70        : ClpObjective()
71{
72    type_ = 12;
73    objective_ = NULL;
74    amplObjective_ = NULL;
75    gradient_ = NULL;
76    offset_ = 0.0;
77}
78
79bool get_constraints_linearity(void * amplInfo, int  n,
80                               int * const_types)
81{
82    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
83    ASL_pfgh* asl = info->asl_;
84    //check that n is good
85    assert(n == n_con);
86    // check that there are no network constraints
87    assert(nlnc == 0 && lnc == 0);
88    //the first nlc constraints are non linear the rest is linear
89    int i;
90    for (i = 0; i < nlc; i++) {
91        const_types[i] = 1;
92    }
93    // the rest is linear
94    for (i = nlc; i < n_con; i++)
95        const_types[i] = 0;
96    return true;
97}
98static bool internal_objval(CbcAmplInfo * info , double & obj_val)
99{
100    ASL_pfgh* asl = info->asl_;
101    info->objval_called_with_current_x_ = false; // in case the call below fails
102
103    if (n_obj == 0) {
104        obj_val = 0;
105        info->objval_called_with_current_x_ = true;
106        return true;
107    }  else {
108        double  retval = objval(0, info->non_const_x_, (fint*)info->nerror_);
109        if (!info->nerror_) {
110            obj_val = info->obj_sign_ * retval;
111            info->objval_called_with_current_x_ = true;
112            return true;
113        } else {
114            abort();
115        }
116    }
117
118    return false;
119}
120
121static bool internal_conval(CbcAmplInfo * info , double * g)
122{
123    ASL_pfgh* asl = info->asl_;
124    info->conval_called_with_current_x_ = false; // in case the call below fails
125    assert (g);
126
127    conval(info->non_const_x_, g, (fint*)info->nerror_);
128
129    if (!info->nerror_) {
130        info->conval_called_with_current_x_ = true;
131        return true;
132    } else {
133        abort();
134    }
135    return false;
136}
137
138static bool apply_new_x(CbcAmplInfo * info  , bool new_x, int  n, const double * x)
139{
140    ASL_pfgh* asl = info->asl_;
141
142    if (new_x) {
143        // update the flags so these methods are called
144        // before evaluating the hessian
145        info->conval_called_with_current_x_ = false;
146        info->objval_called_with_current_x_ = false;
147        info->jacval_called_with_current_x_ = false;
148
149        //copy the data to the non_const_x_
150        if (!info->non_const_x_) {
151            info->non_const_x_ = new double [n];
152        }
153
154        for (int  i = 0; i < n; i++) {
155            info->non_const_x_[i] = x[i];
156        }
157
158        // tell ampl that we have a new x
159        xknowne(info->non_const_x_, (fint*)info->nerror_);
160        return info->nerror_ ? false : true;
161    }
162
163    return true;
164}
165
166static bool eval_f(void * amplInfo, int  n, const double * x, bool new_x, double & obj_value)
167{
168    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
169    if (!apply_new_x(info, new_x, n, x)) {
170        return false;
171    }
172
173    return internal_objval(info, obj_value);
174}
175
176static bool eval_grad_f(void * amplInfo, int  n, const double * x, bool new_x, double * grad_f)
177{
178    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
179    ASL_pfgh* asl = info->asl_;
180    if (!apply_new_x(info, new_x, n, x)) {
181        return false;
182    }
183    int i;
184
185    if (n_obj == 0) {
186        for (i = 0; i < n; i++) {
187            grad_f[i] = 0.;
188        }
189    } else {
190        objgrd(0, info->non_const_x_, grad_f, (fint*)info->nerror_);
191        if (info->nerror_) {
192            return false;
193        }
194
195        if (info->obj_sign_ == -1) {
196            for (i = 0; i < n; i++) {
197                grad_f[i] = -grad_f[i];
198            }
199        }
200    }
201    return true;
202}
203
204static bool eval_g(void * amplInfo, int  n, const double * x, bool new_x, double * g)
205{
206    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
207#ifndef NDEBUG
208    ASL_pfgh* asl = info->asl_;
209#endif
210    // warning: n_var is a macro that assumes we have a variable called asl
211    assert(n == n_var);
212
213    if (!apply_new_x(info, new_x, n, x)) {
214        return false;
215    }
216
217    return internal_conval(info, g);
218}
219
220static bool eval_jac_g(void * amplInfo, int  n, const double * x, bool new_x,
221                       double * values)
222{
223    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
224    ASL_pfgh* asl = info->asl_;
225    assert(n == n_var);
226
227    assert (values);
228    if (!apply_new_x(info, new_x, n, x)) {
229        return false;
230    }
231
232    jacval(info->non_const_x_, values, (fint*)info->nerror_);
233    if (!info->nerror_) {
234        return true;
235    } else {
236        abort();
237    }
238    return false;
239}
240//-------------------------------------------------------------------
241// Useful Constructor
242//-------------------------------------------------------------------
243ClpAmplObjective::ClpAmplObjective (void * amplInfo)
244        : ClpObjective()
245{
246    type_ = 12;
247    activated_ = 1;
248    gradient_ = NULL;
249    objective_ = NULL;
250    offset_ = 0.0;
251    amplObjective_ = amplInfo;
252}
253
254//-------------------------------------------------------------------
255// Copy constructor
256//-------------------------------------------------------------------
257ClpAmplObjective::ClpAmplObjective (const ClpAmplObjective & rhs)
258        : ClpObjective(rhs)
259{
260    amplObjective_ = rhs.amplObjective_;
261    offset_ = rhs.offset_;
262    type_ = rhs.type_;
263    if (!amplObjective_) {
264        objective_ = NULL;
265        gradient_ = NULL;
266    } else {
267        CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
268        ASL_pfgh* asl = info->asl_;
269
270        int numberColumns = n_var;;
271        if (rhs.objective_) {
272            objective_ = new double [numberColumns];
273            memcpy(objective_, rhs.objective_, numberColumns*sizeof(double));
274        } else {
275            objective_ = NULL;
276        }
277        if (rhs.gradient_) {
278            gradient_ = new double [numberColumns];
279            memcpy(gradient_, rhs.gradient_, numberColumns*sizeof(double));
280        } else {
281            gradient_ = NULL;
282        }
283    }
284}
285
286
287//-------------------------------------------------------------------
288// Destructor
289//-------------------------------------------------------------------
290ClpAmplObjective::~ClpAmplObjective ()
291{
292    delete [] objective_;
293    delete [] gradient_;
294}
295
296//----------------------------------------------------------------
297// Assignment operator
298//-------------------------------------------------------------------
299ClpAmplObjective &
300ClpAmplObjective::operator=(const ClpAmplObjective & rhs)
301{
302    if (this != &rhs) {
303        delete [] objective_;
304        delete [] gradient_;
305        amplObjective_ = rhs.amplObjective_;
306        offset_ = rhs.offset_;
307        type_ = rhs.type_;
308        if (!amplObjective_) {
309            objective_ = NULL;
310            gradient_ = NULL;
311        } else {
312            CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
313            ASL_pfgh* asl = info->asl_;
314
315            int numberColumns = n_var;;
316            if (rhs.objective_) {
317                objective_ = new double [numberColumns];
318                memcpy(objective_, rhs.objective_, numberColumns*sizeof(double));
319            } else {
320                objective_ = NULL;
321            }
322            if (rhs.gradient_) {
323                gradient_ = new double [numberColumns];
324                memcpy(gradient_, rhs.gradient_, numberColumns*sizeof(double));
325            } else {
326                gradient_ = NULL;
327            }
328        }
329    }
330    return *this;
331}
332
333// Returns gradient
334double *
335ClpAmplObjective::gradient(const ClpSimplex * model,
336                           const double * solution, double & offset, bool refresh,
337                           int includeLinear)
338{
339    if (model)
340        assert (model->optimizationDirection() == 1.0);
341    bool scaling = false;
342    if (model && (model->rowScale() ||
343                  model->objectiveScale() != 1.0 || model->optimizationDirection() != 1.0))
344        scaling = true;
345    const double * cost = NULL;
346    if (model)
347        cost = model->costRegion();
348    if (!cost) {
349        // not in solve
350        cost = objective_;
351        scaling = false;
352    }
353    assert (!scaling);
354    if (!amplObjective_ || !solution || !activated_) {
355        offset = offset_;
356        return objective_;
357    } else {
358        if (refresh || !gradient_) {
359            CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
360            ASL_pfgh* asl = info->asl_;
361            int numberColumns = n_var;;
362
363            if (!gradient_)
364                gradient_ = new double[numberColumns];
365            assert (solution);
366            eval_grad_f(amplObjective_, numberColumns, solution, true, gradient_);
367            // Is this best way?
368            double objValue = 0.0;
369            eval_f(amplObjective_, numberColumns, solution, false, objValue);
370            double objValue2 = 0.0;
371            for (int i = 0; i < numberColumns; i++)
372                objValue2 += gradient_[i] * solution[i];
373            offset_ = objValue2 - objValue; // or other way???
374            if (model && model->optimizationDirection() != 1.0) {
375                offset *= model->optimizationDirection();
376                for (int i = 0; i < numberColumns; i++)
377                    gradient_[i] *= -1.0;
378            }
379        }
380        offset = offset_;
381        return gradient_;
382    }
383}
384
385//-------------------------------------------------------------------
386// Clone
387//-------------------------------------------------------------------
388ClpObjective * ClpAmplObjective::clone() const
389{
390    return new ClpAmplObjective(*this);
391}
392// Resize objective
393void
394ClpAmplObjective::resize(int newNumberColumns)
395{
396    CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
397    ASL_pfgh* asl = info->asl_;
398    int numberColumns = n_var;;
399    if (numberColumns != newNumberColumns) {
400        abort();
401    }
402
403}
404// Delete columns in  objective
405void
406ClpAmplObjective::deleteSome(int numberToDelete, const int * which)
407{
408    if (numberToDelete)
409        abort();
410}
411/* Returns reduced gradient.Returns an offset (to be added to current one).
412 */
413double
414ClpAmplObjective::reducedGradient(ClpSimplex * model, double * region,
415                                  bool useFeasibleCosts)
416{
417    int numberRows = model->numberRows();
418    int numberColumns = model->numberColumns();
419
420    //work space
421    CoinIndexedVector  * workSpace = model->rowArray(0);
422
423    CoinIndexedVector arrayVector;
424    arrayVector.reserve(numberRows + 1);
425
426    int iRow;
427#ifdef CLP_DEBUG
428    workSpace->checkClear();
429#endif
430    double * array = arrayVector.denseVector();
431    int * index = arrayVector.getIndices();
432    int number = 0;
433    const double * costNow = gradient(model, model->solutionRegion(), offset_,
434                                      true, useFeasibleCosts ? 2 : 1);
435    double * cost = model->costRegion();
436    const int * pivotVariable = model->pivotVariable();
437    for (iRow = 0; iRow < numberRows; iRow++) {
438        int iPivot = pivotVariable[iRow];
439        double value;
440        if (iPivot < numberColumns)
441            value = costNow[iPivot];
442        else if (!useFeasibleCosts)
443            value = cost[iPivot];
444        else
445            value = 0.0;
446        if (value) {
447            array[iRow] = value;
448            index[number++] = iRow;
449        }
450    }
451    arrayVector.setNumElements(number);
452
453    // Btran basic costs
454    model->factorization()->updateColumnTranspose(workSpace, &arrayVector);
455    double * work = workSpace->denseVector();
456    ClpFillN(work, numberRows, 0.0);
457    // now look at dual solution
458    double * rowReducedCost = region + numberColumns;
459    double * dual = rowReducedCost;
460    const double * rowCost = cost + numberColumns;
461    for (iRow = 0; iRow < numberRows; iRow++) {
462        dual[iRow] = array[iRow];
463    }
464    double * dj = region;
465    ClpDisjointCopyN(costNow, numberColumns, dj);
466
467    model->transposeTimes(-1.0, dual, dj);
468    for (iRow = 0; iRow < numberRows; iRow++) {
469        // slack
470        double value = dual[iRow];
471        value += rowCost[iRow];
472        rowReducedCost[iRow] = value;
473    }
474    return offset_;
475}
476/* Returns step length which gives minimum of objective for
477   solution + theta * change vector up to maximum theta.
478
479   arrays are numberColumns+numberRows
480*/
481double
482ClpAmplObjective::stepLength(ClpSimplex * model,
483                             const double * solution,
484                             const double * change,
485                             double maximumTheta,
486                             double & currentObj,
487                             double & predictedObj,
488                             double & thetaObj)
489{
490    // Assume convex
491    CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
492    ASL_pfgh* asl = info->asl_;
493
494    int numberColumns = n_var;;
495    double * tempSolution = new double [numberColumns];
496    double * tempGradient = new double [numberColumns];
497    // current
498    eval_f(amplObjective_, numberColumns, solution, true, currentObj);
499    double objA = currentObj;
500    double thetaA = 0.0;
501    // at maximum
502    int i;
503    for (i = 0; i < numberColumns; i++)
504        tempSolution[i] = solution[i] + maximumTheta * change[i];
505    eval_f(amplObjective_, numberColumns, tempSolution, true, thetaObj);
506    double objC = thetaObj;
507    double thetaC = maximumTheta;
508    double objB = 0.5 * (objA + objC);
509    double thetaB = 0.5 * maximumTheta;
510    double gradientNorm = 1.0e6;
511    while (gradientNorm > 1.0e-6 && thetaC - thetaA > 1.0e-8) {
512        for (i = 0; i < numberColumns; i++)
513            tempSolution[i] = solution[i] + thetaB * change[i];
514        eval_grad_f(amplObjective_, numberColumns, tempSolution, true, tempGradient);
515        eval_f(amplObjective_, numberColumns, tempSolution, false, objB);
516        double changeObj = 0.0;
517        gradientNorm = 0.0;
518        for (i = 0; i < numberColumns; i++) {
519            changeObj += tempGradient[i] * change[i];
520            gradientNorm += tempGradient[i] * tempGradient[i];
521        }
522        gradientNorm = fabs(changeObj) / sqrt(gradientNorm);
523        // Should try and get quadratic convergence by interpolation
524        if (changeObj < 0.0) {
525            // increasing is good
526            thetaA = thetaB;
527        } else {
528            // decreasing is good
529            thetaC = thetaB;
530        }
531        thetaB = 0.5 * (thetaA + thetaC);
532    }
533    delete [] tempSolution;
534    delete [] tempGradient;
535    predictedObj = objB;
536    return thetaB;
537}
538// Return objective value (without any ClpModel offset) (model may be NULL)
539double
540ClpAmplObjective::objectiveValue(const ClpSimplex * model, const double * solution) const
541{
542    CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
543    ASL_pfgh* asl = info->asl_;
544
545    int numberColumns = n_var;;
546    // current
547    double currentObj = 0.0;
548    eval_f(amplObjective_, numberColumns, solution, true, currentObj);
549    return currentObj;
550}
551// Scale objective
552void
553ClpAmplObjective::reallyScale(const double * columnScale)
554{
555    abort();
556}
557/* Given a zeroed array sets nonlinear columns to 1.
558   Returns number of nonlinear columns
559*/
560int
561ClpAmplObjective::markNonlinear(char * which)
562{
563    int iColumn;
564    CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
565    ASL_pfgh* asl = info->asl_;
566    int nonLinear = CoinMax(nlvc, nlvo);
567    for (iColumn = 0; iColumn < nonLinear; iColumn++) {
568        which[iColumn] = 1;
569    }
570    int numberNonLinearColumns = 0;
571    int numberColumns = n_var;;
572    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
573        if (which[iColumn])
574            numberNonLinearColumns++;
575    }
576    return numberNonLinearColumns;
577}
578// Say we have new primal solution - so may need to recompute
579void
580ClpAmplObjective::newXValues()
581{
582    CbcAmplInfo * info = (CbcAmplInfo *) amplObjective_;
583    info->conval_called_with_current_x_ = false;
584    info->objval_called_with_current_x_ = false;
585    info->jacval_called_with_current_x_ = false;
586}
587
588//#############################################################################
589// Constructors / Destructor / Assignment
590//#############################################################################
591//-------------------------------------------------------------------
592// Default Constructor
593//-------------------------------------------------------------------
594ClpConstraintAmpl::ClpConstraintAmpl ()
595        : ClpConstraint()
596{
597    type_ = 3;
598    column_ = NULL;
599    coefficient_ = NULL;
600    numberCoefficients_ = 0;
601    amplInfo_ = NULL;
602}
603
604//-------------------------------------------------------------------
605// Useful Constructor
606//-------------------------------------------------------------------
607ClpConstraintAmpl::ClpConstraintAmpl (int row, void * amplInfo)
608        : ClpConstraint()
609{
610    type_ = 3;
611    rowNumber_ = row;
612    amplInfo_ = amplInfo;
613    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;
614#ifndef NDEBUG
615    ASL_pfgh* asl = info->asl_;
616#endif
617    // warning: nlc is a macro that assumes we have a variable called asl
618    assert (rowNumber_ < nlc);
619    numberCoefficients_ = info->rowStart_[rowNumber_+1] - info->rowStart_[rowNumber_];
620    column_ = CoinCopyOfArray(info->column_ + info->rowStart_[rowNumber_], numberCoefficients_);
621    coefficient_ = new double [numberCoefficients_];;
622}
623
624//-------------------------------------------------------------------
625// Copy constructor
626//-------------------------------------------------------------------
627ClpConstraintAmpl::ClpConstraintAmpl (const ClpConstraintAmpl & rhs)
628        : ClpConstraint(rhs)
629{
630    numberCoefficients_ = rhs.numberCoefficients_;
631    column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_);
632    coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_);
633}
634
635
636//-------------------------------------------------------------------
637// Destructor
638//-------------------------------------------------------------------
639ClpConstraintAmpl::~ClpConstraintAmpl ()
640{
641    delete [] column_;
642    delete [] coefficient_;
643}
644
645//----------------------------------------------------------------
646// Assignment operator
647//-------------------------------------------------------------------
648ClpConstraintAmpl &
649ClpConstraintAmpl::operator=(const ClpConstraintAmpl & rhs)
650{
651    if (this != &rhs) {
652        delete [] column_;
653        delete [] coefficient_;
654        numberCoefficients_ = rhs.numberCoefficients_;
655        column_ = CoinCopyOfArray(rhs.column_, numberCoefficients_);
656        coefficient_ = CoinCopyOfArray(rhs.coefficient_, numberCoefficients_);
657    }
658    return *this;
659}
660//-------------------------------------------------------------------
661// Clone
662//-------------------------------------------------------------------
663ClpConstraint * ClpConstraintAmpl::clone() const
664{
665    return new ClpConstraintAmpl(*this);
666}
667
668// Returns gradient
669int
670ClpConstraintAmpl::gradient(const ClpSimplex * model,
671                            const double * solution,
672                            double * gradient,
673                            double & functionValue,
674                            double & offset,
675                            bool useScaling,
676                            bool refresh) const
677{
678    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;
679    ASL_pfgh* asl = info->asl_;
680    int numberColumns = n_var;;
681    // If not done then do all
682    if (!info->jacval_called_with_current_x_) {
683        bool getStuff = eval_g(amplInfo_, numberColumns, solution, true, info->constraintValues_);
684        assert (getStuff);
685        getStuff = eval_jac_g(amplInfo_, numberColumns, solution, false, info->gradient_);
686        assert (getStuff);
687        info->jacval_called_with_current_x_ = getStuff;
688    }
689    if (refresh || !lastGradient_) {
690        functionValue_ = info->constraintValues_[rowNumber_];
691        offset_ = functionValue_; // sign??
692        if (!lastGradient_)
693            lastGradient_ = new double[numberColumns];
694        CoinZeroN(lastGradient_, numberColumns);
695        assert (!(model && model->rowScale() && useScaling));
696        int i;
697        int start = info->rowStart_[rowNumber_];
698        assert (numberCoefficients_ == info->rowStart_[rowNumber_+1] - start);
699        for (i = 0; i < numberCoefficients_; i++) {
700            int iColumn = column_[i];
701            double valueS = solution[iColumn];
702            double valueG = info->gradient_[start+i];
703            lastGradient_[iColumn] = valueG;
704            offset_ -= valueS * valueG;
705        }
706    }
707    functionValue = functionValue_;
708    offset = offset_;
709    memcpy(gradient, lastGradient_, numberColumns*sizeof(double));
710    return 0;
711}
712// Resize constraint
713void
714ClpConstraintAmpl::resize(int newNumberColumns)
715{
716    abort();
717}
718// Delete columns in  constraint
719void
720ClpConstraintAmpl::deleteSome(int numberToDelete, const int * which)
721{
722    if (numberToDelete) {
723        abort();
724    }
725}
726// Scale constraint
727void
728ClpConstraintAmpl::reallyScale(const double * columnScale)
729{
730    abort();
731}
732/* Given a zeroed array sets nonlinear columns to 1.
733   Returns number of nonlinear columns
734*/
735int
736ClpConstraintAmpl::markNonlinear(char * which) const
737{
738    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;
739    ASL_pfgh* asl = info->asl_;
740    int iColumn;
741    int numberNon = 0;
742    int nonLinear = CoinMax(nlvc, nlvo);
743    for (iColumn = 0; iColumn < numberCoefficients_; iColumn++) {
744        int jColumn = column_[iColumn];
745        if (jColumn < nonLinear) {
746            which[jColumn] = 1;
747            numberNon++;
748        }
749    }
750    return numberNon;
751}
752/* Given a zeroed array sets possible nonzero coefficients to 1.
753   Returns number of nonzeros
754*/
755int
756ClpConstraintAmpl::markNonzero(char * which) const
757{
758    int iColumn;
759    for (iColumn = 0; iColumn < numberCoefficients_; iColumn++) {
760        which[column_[iColumn]] = 1;
761    }
762    return numberCoefficients_;
763}
764// Number of coefficients
765int
766ClpConstraintAmpl::numberCoefficients() const
767{
768    return numberCoefficients_;
769}
770// Say we have new primal solution - so may need to recompute
771void
772ClpConstraintAmpl::newXValues()
773{
774    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo_;
775    info->conval_called_with_current_x_ = false;
776    info->objval_called_with_current_x_ = false;
777    info->jacval_called_with_current_x_ = false;
778}
779
780/* Load nonlinear part of problem from AMPL info
781   Returns 0 if linear
782   1 if quadratic objective
783   2 if quadratic constraints
784   3 if nonlinear objective
785   4 if nonlinear constraints
786   -1 on failure
787*/
788int
789ClpSimplex::loadNonLinear(void * amplInfo, int & numberConstraints,
790                          ClpConstraint ** & constraints)
791{
792    numberConstraints = 0;
793    constraints = NULL;
794    CbcAmplInfo * info = (CbcAmplInfo *) amplInfo;
795    ASL_pfgh* asl = info->asl_;
796    // For moment don't say quadratic
797    int type = 0;
798    if (nlo + nlc) {
799        // nonlinear
800        if (!nlc) {
801            type = 3;
802            delete objective_;
803            objective_ = new ClpAmplObjective(amplInfo);
804        } else {
805            type = 4;
806            numberConstraints = nlc;
807            constraints = new ClpConstraint * [numberConstraints];
808            if (nlo) {
809                delete objective_;
810                objective_ = new ClpAmplObjective(amplInfo);
811            }
812            for (int i = 0; i < numberConstraints; i++) {
813                constraints[i] = new ClpConstraintAmpl(i, amplInfo);
814            }
815        }
816    }
817    return type;
818}
819#else
820#include "ClpSimplex.hpp"
821#include "ClpConstraint.hpp"
822int
823ClpSimplex::loadNonLinear(void * , int & ,
824                          ClpConstraint ** & )
825{
826    abort();
827    return 0;
828}
829#endif
Note: See TracBrowser for help on using the repository browser.