1 /* $Id: CoinWarmStartPrimalDual.cpp 1373 2011-01-03 23:57:44Z lou $ */
2 // Copyright (C) 2003, International Business Machines
3 // Corporation and others.  All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 
6 #if defined(_MSC_VER)
7 // Turn off compiler warning about long names
8 #  pragma warning(disable:4786)
9 #endif
10 
11 #include <cassert>
12 
13 #include "CoinWarmStartPrimalDual.hpp"
14 #include <cmath>
15 
16 //#############################################################################
17 
18 /*
19   Generate a `diff' that can convert the warm start passed as a parameter to
20   the warm start specified by this.
21 
22   The capabilities are limited: the basis passed as a parameter can be no
23   larger than the basis pointed to by this.
24 */
25 
26 CoinWarmStartDiff*
generateDiff(const CoinWarmStart * const oldCWS) const27 CoinWarmStartPrimalDual::generateDiff (const CoinWarmStart *const oldCWS) const
28 {
29 /*
30   Make sure the parameter is CoinWarmStartPrimalDual or derived class.
31 */
32   const CoinWarmStartPrimalDual *old =
33       dynamic_cast<const CoinWarmStartPrimalDual *>(oldCWS) ;
34   if (!old)
35   { throw CoinError("Old warm start not derived from CoinWarmStartPrimalDual.",
36 		    "generateDiff","CoinWarmStartPrimalDual") ; }
37 
38   CoinWarmStartPrimalDualDiff* diff = new CoinWarmStartPrimalDualDiff;
39   CoinWarmStartDiff* vecdiff;
40   vecdiff = primal_.generateDiff(&old->primal_);
41   diff->primalDiff_.swap(*dynamic_cast<CoinWarmStartVectorDiff<double>*>(vecdiff));
42   delete vecdiff;
43   vecdiff = dual_.generateDiff(&old->dual_);
44   diff->dualDiff_.swap(*dynamic_cast<CoinWarmStartVectorDiff<double>*>(vecdiff));
45   delete vecdiff;
46 
47   return diff;
48 }
49 
50 //#############################################################################
51 
52 /*
53   Apply diff to this warm start.
54 
55   Update this warm start by applying diff. It's assumed that the
56   allocated capacity of the warm start is sufficiently large.
57 */
58 
59 void
applyDiff(const CoinWarmStartDiff * const cwsdDiff)60 CoinWarmStartPrimalDual::applyDiff (const CoinWarmStartDiff *const cwsdDiff)
61 {
62 /*
63   Make sure we have a CoinWarmStartPrimalDualDiff
64 */
65   const CoinWarmStartPrimalDualDiff *diff =
66     dynamic_cast<const CoinWarmStartPrimalDualDiff *>(cwsdDiff) ;
67   if (!diff)
68   { throw CoinError("Diff not derived from CoinWarmStartPrimalDualDiff.",
69 		    "applyDiff","CoinWarmStartPrimalDual") ; }
70 
71   primal_.applyDiff(&diff->primalDiff_);
72   dual_.applyDiff(&diff->dualDiff_);
73 }
74