1template <class T> T CoinMax(register const T x1, register const T x2);
2template <class T> T CoinMin(register const T x1, register const T x2);
3class CoinIndexedVector;
4class ClpModel {
5protected:
6    double objectiveScale_;
7    double rhsScale_;
8    int numberRows_;
9    int numberColumns_;
10    double * rowActivity_;
11    double * columnActivity_;
12    double * dual_;
13    double * reducedCost_;
14    double* rowLower_;
15    double* rowUpper_;
16    double * rowObjective_;
17    double * columnLower_;
18    double * columnUpper_;
19    double * rowScale_;
20    double * columnScale_;
21    double * inverseRowScale_;
22    double * inverseColumnScale_;
23    int problemStatus_;
24    int secondaryStatus_;
25};
26class ClpSimplex : public ClpModel {
27    void deleteRim(int getRidOfFactorizationData=2);
28    double upperOut_;
29    double dualTolerance_;
30    double primalTolerance_;
31    double * rowLowerWork_;
32    double * columnLowerWork_;
33    double * rowUpperWork_;
34    double * columnUpperWork_;
35    double * rowObjectiveWork_;
36    CoinIndexedVector * columnArray_[6];
37    double * reducedCostWork_;
38    double * rowActivityWork_;
39    double * columnActivityWork_;
40    ClpSimplex * auxiliaryModel_;
41};
42class CoinIndexedVector {
43public:
44    void clear();
45};
46void ClpSimplex::deleteRim(int getRidOfFactorizationData)
47{
48  int numberRows=numberRows_;
49  int numberColumns=numberColumns_;
50  int i;
51  int numberPrimalScaled=0;
52  int numberPrimalUnscaled=0;
53  int numberDualScaled=0;
54  int numberDualUnscaled=0;
55  double scaleC = 1.0/objectiveScale_;
56  double scaleR = 1.0/rhsScale_;
57  if (!inverseColumnScale_) {
58      for (i=0; i<numberColumns; i++)
59	{
60	  double scaleFactor = columnScale_[i];
61	  double valueScaled = columnActivityWork_[i];
62	  double lowerScaled = columnLowerWork_[i];
63	  double upperScaled = columnUpperWork_[i];
64	  if (lowerScaled>-1.0e20||upperScaled<1.0e20) {
65	      if (valueScaled<lowerScaled-primalTolerance_||   valueScaled>upperScaled+primalTolerance_)
66		numberPrimalScaled++;
67	      else
68		upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled));
69	  }
70	  columnActivity_[i] = valueScaled*scaleFactor*scaleR;
71	  double value = columnActivity_[i];
72	  if (value<columnLower_[i]-primalTolerance_)
73	    numberPrimalUnscaled++;
74	  else if (value>columnUpper_[i]+primalTolerance_)
75	    numberPrimalUnscaled++;
76	  double valueScaledDual = reducedCostWork_[i];
77	  if (valueScaled>columnLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
78	    numberDualScaled++;
79	  if (valueScaled<columnUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
80	    numberDualScaled++;
81	  reducedCost_[i] = (valueScaledDual*scaleC)/scaleFactor;
82	  double valueDual = reducedCost_[i];
83	  if (value>columnLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
84	    numberDualUnscaled++;
85	  if (value<columnUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
86	    numberDualUnscaled++;
87	}
88      for (i=0; i<numberRows; i++)
89	{
90	  double scaleFactor = rowScale_[i];
91	  double valueScaled = rowActivityWork_[i];
92	  double lowerScaled = rowLowerWork_[i];
93	  double upperScaled = rowUpperWork_[i];
94	  if (lowerScaled>-1.0e20||upperScaled<1.0e20) {      if (valueScaled<lowerScaled-primalTolerance_||   valueScaled>upperScaled+primalTolerance_)        numberPrimalScaled++;      else        upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled));    }
95	  rowActivity_[i] = (valueScaled*scaleR)/scaleFactor;
96	  double value = rowActivity_[i];
97	  if (value<rowLower_[i]-primalTolerance_)      numberPrimalUnscaled++;
98	  else if (value>rowUpper_[i]+primalTolerance_)      numberPrimalUnscaled++;
99	  double valueScaledDual = dual_[i]+rowObjectiveWork_[i];
100	  ;
101	  if (valueScaled>rowLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)      numberDualScaled++;
102	  if (valueScaled<rowUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)      numberDualScaled++;
103	  dual_[i] *= scaleFactor*scaleC;
104	  double valueDual = dual_[i];
105	  if (rowObjective_)      valueDual += rowObjective_[i];
106	  if (value>rowLower_[i]+primalTolerance_&&valueDual>dualTolerance_)      numberDualUnscaled++;
107	  if (value<rowUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)      numberDualUnscaled++;
108	}
109  }
110  const double * inverseScale = inverseColumnScale_;
111  for (i=0; i<numberColumns; i++)
112    {
113      double scaleFactor = columnScale_[i];
114      double valueScaled = columnActivityWork_[i];
115      double lowerScaled = columnLowerWork_[i];
116      double upperScaled = columnUpperWork_[i];
117      if (lowerScaled>-1.0e20||upperScaled<1.0e20) {      if (valueScaled<lowerScaled-primalTolerance_||   valueScaled>upperScaled+primalTolerance_)        numberPrimalScaled++;      else        upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled));    }
118      columnActivity_[i] = valueScaled*scaleFactor*scaleR;
119      double value = columnActivity_[i];
120      if (value<columnLower_[i]-primalTolerance_)      numberPrimalUnscaled++;
121      else if (value>columnUpper_[i]+primalTolerance_)      numberPrimalUnscaled++;
122      double valueScaledDual = reducedCostWork_[i];
123      if (valueScaled>columnLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)      numberDualScaled++;
124      if (valueScaled<columnUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)      numberDualScaled++;
125      reducedCost_[i] = (valueScaledDual*scaleC)*inverseScale[i];
126      double valueDual = reducedCost_[i];
127      if (value>columnLower_[i]+primalTolerance_&&valueDual>dualTolerance_)      numberDualUnscaled++;
128      if (value<columnUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)      numberDualUnscaled++;
129    }
130  inverseScale = inverseRowScale_;
131  for (i=0; i<numberRows; i++)
132    {
133      double scaleFactor = rowScale_[i];
134      double valueScaled = rowActivityWork_[i];
135      double lowerScaled = rowLowerWork_[i];
136      double upperScaled = rowUpperWork_[i];
137      if (lowerScaled>-1.0e20||upperScaled<1.0e20) {      if (valueScaled<lowerScaled-primalTolerance_||   valueScaled>upperScaled+primalTolerance_)        numberPrimalScaled++;      else        upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled));    }
138      rowActivity_[i] = (valueScaled*scaleR)*inverseScale[i];
139      double value = rowActivity_[i];
140      if (value<rowLower_[i]-primalTolerance_)      numberPrimalUnscaled++;
141      else if (value>rowUpper_[i]+primalTolerance_)      numberPrimalUnscaled++;
142      double valueScaledDual = dual_[i]+rowObjectiveWork_[i];
143      ;
144      if (valueScaled>rowLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)      numberDualScaled++;
145      if (valueScaled<rowUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)      numberDualScaled++;
146      dual_[i] *= scaleFactor*scaleC;
147      double valueDual = dual_[i];
148      if (rowObjective_)      valueDual += rowObjective_[i];
149      if (value>rowLower_[i]+primalTolerance_&&valueDual>dualTolerance_)      numberDualUnscaled++;
150      if (value<rowUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)      numberDualUnscaled++;
151    }
152  if (numberPrimalUnscaled) {
153      if (numberDualUnscaled)
154	secondaryStatus_=4;
155      else
156	secondaryStatus_=2;
157  }
158  if (numberDualUnscaled)
159    secondaryStatus_=3;
160  int iRow,iColumn;
161  for (iRow=0; iRow<4; iRow++)
162    ;
163  for (iColumn=0; iColumn<2; iColumn++)
164    if (columnArray_[iColumn])
165      columnArray_[iColumn]->clear();
166}
167