source: trunk/Cbc/src/CbcLinkedUtils.cpp @ 1885

Last change on this file since 1885 was 1885, checked in by stefan, 5 years ago

fix bug that was even pointed out by compiler warnings

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