Coverage Report

Created: 2025-08-28 06:30

/src/quantlib/ql/experimental/finitedifferences/fdmvppstartlimitstepcondition.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3
/*
4
 Copyright (C) 2011, 2012 Klaus Spanderen
5
6
 This file is part of QuantLib, a free-software/open-source library
7
 for financial quantitative analysts and developers - http://quantlib.org/
8
9
 QuantLib is free software: you can redistribute it and/or modify it
10
 under the terms of the QuantLib license.  You should have received a
11
 copy of the license along with this program; if not, please email
12
 <quantlib-dev@lists.sf.net>. The license is also available online at
13
 <http://quantlib.org/license.shtml>.
14
15
 This program is distributed in the hope that it will be useful, but WITHOUT
16
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 FOR A PARTICULAR PURPOSE.  See the license for more details.
18
*/
19
20
/*! \file fdmvppstartlimitstepcondition.cpp
21
*/
22
23
#include <algorithm>
24
#include <ql/math/array.hpp>
25
#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
26
#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
27
#include <ql/experimental/finitedifferences/fdmvppstartlimitstepcondition.hpp>
28
#include <ql/methods/finitedifferences/operators/fdmlinearopiterator.hpp>
29
#include <ql/methods/finitedifferences/utilities/fdminnervaluecalculator.hpp>
30
31
32
namespace QuantLib {
33
34
    FdmVPPStartLimitStepCondition::FdmVPPStartLimitStepCondition(
35
        const FdmVPPStepConditionParams& params,
36
        Size nStarts,
37
        const FdmVPPStepConditionMesher& mesh,
38
        const ext::shared_ptr<FdmInnerValueCalculator>& gasPrice,
39
        const ext::shared_ptr<FdmInnerValueCalculator>& sparkSpreadPrice)
40
0
    : FdmVPPStepCondition(params,
41
0
                          nStates(params.tMinUp, params.tMinDown, nStarts),
42
0
                          mesh, gasPrice, sparkSpreadPrice),
43
0
      nStarts_(nStarts) {
44
0
        QL_REQUIRE(tMinUp_ > 0,   "minimum up time must be greater than one");
45
0
        QL_REQUIRE(tMinDown_ > 0, "minimum down time must be greater than one");
46
0
    }
47
48
    Array FdmVPPStartLimitStepCondition::changeState(
49
0
        const Real gasPrice, const Array& state, Time) const {
50
51
0
        const Real startUpCost
52
0
                = startUpFixCost_ + (gasPrice + fuelCostAddon_)*startUpFuel_;
53
54
0
        Array retVal(state.size());
55
0
        const Size sss = 2*tMinUp_ + tMinDown_;
56
57
0
        for (Size i=0; i < nStates_; ++i) {
58
0
            const Size j = i % sss;
59
60
0
            if (j < tMinUp_-1) {
61
0
                retVal[i] = std::max(state[i+1], state[tMinUp_+i+1]);
62
0
            }
63
0
            else if (j == tMinUp_-1) {
64
0
                retVal[i] = std::max({state[i+tMinUp_+1], state[i], state[i+tMinUp_]});
65
0
            }
66
0
            else if (j < 2*tMinUp_) {
67
0
                retVal[i] = retVal[i-tMinUp_];
68
0
            }
69
0
            else if (j <  2*tMinUp_+tMinDown_-1) {
70
0
                retVal[i] = state[i+1];
71
0
            }
72
0
            else if (nStarts_ == Null<Size>()) {
73
0
                retVal[i] = std::max(state[i],
74
0
                    std::max(state.front(), state[tMinUp_]) - startUpCost);
75
76
0
            }
77
0
            else if (i >= sss) {
78
0
                retVal[i] = std::max(state[i],
79
0
                    std::max(state[i+1-2*sss], state[i+1-2*sss+tMinUp_])
80
0
                            - startUpCost);
81
0
            }
82
0
            else {
83
0
                retVal[i] = state[i];
84
0
            }
85
0
        }
86
87
0
        return retVal;
88
0
    }
89
90
    Size FdmVPPStartLimitStepCondition::nStates(Size tMinUp, Size tMinDown,
91
0
                                                Size nStarts) {
92
0
        return (2*tMinUp+tMinDown)*((nStarts == Null<Size>())? 1 : nStarts+1);
93
0
    }
94
95
0
    Real FdmVPPStartLimitStepCondition::maxValue(const Array& states) const {
96
0
        return *std::max_element(states.begin(), states.end());
97
0
    }
98
99
}