1 /* $Id: $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's offical duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================*/
25
26 /*****************************************************************************
27
28 File name: njn_dynprogprob.cpp
29
30 Author: John Spouge
31
32 Contents:
33
34 ******************************************************************************/
35
36 #include <assert.h>
37
38 #include "njn_dynprogprob.hpp"
39 #include "njn_memutil.hpp"
40
41 using namespace Njn;
42
43
44 const size_t DynProgProb::ARRAY_CAPACITY = 256;
45
init(size_t arrayCapacity_)46 void DynProgProb::init (size_t arrayCapacity_) // range for d_array_p [0,1][0...arrayCapacity_ - 1]
47 {
48 if (arrayCapacity_ > 0)
49 {
50 for (size_t i = 0; i < 2; i++)
51 {
52 d_array_p [i] = new double [arrayCapacity_];
53 MemUtil::memZero (d_array_p [i], sizeof (double) * arrayCapacity_);
54 }
55 }
56
57 d_arrayCapacity = arrayCapacity_;
58 }
59
free2()60 void DynProgProb::free2 ()
61 {
62 if (getArrayCapacity () > 0)
63 {
64 for (size_t i = 0; i < 2; i++)
65 {
66 delete [] d_array_p [i]; d_array_p [i] = 0;
67 }
68 }
69
70 d_arrayCapacity = 0;
71 }
72
clear(long int valueBegin_,size_t arrayCapacity_)73 void DynProgProb::clear (
74 long int valueBegin_, // lower limit for long int values in the array (an offset)
75 size_t arrayCapacity_) // new array capacity
76 // resets the computation
77 {
78 free2 ();
79 init (arrayCapacity_);
80 d_valueBegin = valueBegin_;
81 d_step = 0;
82 }
83
clear(long int valueLower_,long int valueUpper_,const double * prob_)84 void DynProgProb::clear ( // initializes the "probabilities" with non-negative weights
85 long int valueLower_, // lower long int value corresponding to the "probability" array
86 long int valueUpper_, // one beyond present upper long int value corresponding to the "probability" array
87 const double *prob_) // "probabilities" prob [valueLower_, valueUpper_) corresponding to the long ints
88 {
89 assert ((! prob_ && valueLower_ <= 0 && 0 <= valueUpper_) ||
90 /*sls added "("*/(prob_ && valueLower_ < valueUpper_)/*sls added ")"*/ );
91
92 if (prob_)
93 {
94 for (size_t i = 0; i < static_cast <size_t> (valueUpper_ - valueLower_); i++)
95 {
96 assert (0.0 <= prob_ [i]);
97 }
98
99 clear (valueLower_, static_cast <size_t> (valueUpper_ - valueLower_));
100
101 d_valueLower = valueLower_;
102 d_valueUpper = valueUpper_;
103 MemUtil::memCpy (d_array_p [0], prob_, sizeof (double) * getArrayCapacity ());
104
105 return;
106 }
107
108 if (valueLower_ == 0 && valueUpper_ == 0)
109 {
110 clear (-static_cast <long int> (ARRAY_CAPACITY / 2) + 1, ARRAY_CAPACITY);
111 }
112 else
113 {
114 clear (valueLower_, static_cast <size_t> (valueUpper_ - valueLower_));
115 }
116
117 d_valueLower = 0;
118 d_valueUpper = 1;
119 d_array_p [0][getArrayPos (0)] = 1.0;
120
121 return;
122 }
123
copy(size_t step_,const double * const * array_,size_t arrayCapacity_,long int valueBegin_,long int valueLower_,long int valueUpper_,ValueFct * newStateFct_,size_t dimInputProb_,const double * inputProb_)124 void DynProgProb::copy (
125 size_t step_, // current index : starts at 0
126 const double *const *array_, // two corresponding arrays of probabilities
127 size_t arrayCapacity_, // present capacity of the array
128 long int valueBegin_, // lower limit for long int values in the array (an offset)
129 long int valueLower_, // present lower long int value in the array
130 long int valueUpper_, // one beyond present upper long int value in the array
131 ValueFct *newStateFct_, // function for updating dynamic programming values
132 size_t dimInputProb_,
133 const double *inputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
134 {
135 if (arrayCapacity_ != getArrayCapacity ())
136 {
137 free2 ();
138 init (arrayCapacity_);
139 }
140
141 d_step = step_;
142 for (size_t i = 0; i < 2; i++)
143 {
144 if (getArrayCapacity () > 0) MemUtil::memCpy (d_array_p [i], array_ [i], sizeof (double) * getArrayCapacity ());
145 }
146
147 d_valueBegin = valueBegin_;
148 d_valueLower = valueLower_;
149 d_valueUpper = valueUpper_;
150
151 setValueFct (newStateFct_);
152 setInput (dimInputProb_, inputProb_);
153 }
154
initInput(size_t dimInputProb_)155 void DynProgProb::initInput (size_t dimInputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
156 {
157 if (dimInputProb_ > 0)
158 {
159 d_inputProb_p = new double [dimInputProb_];
160 MemUtil::memZero (d_inputProb_p, sizeof (double) * dimInputProb_);
161 }
162
163 d_dimInputProb = dimInputProb_;
164 }
165
freeInput()166 void DynProgProb::freeInput ()
167 {
168 if (getDimInputProb () > 0)
169 {
170 delete [] d_inputProb_p; d_inputProb_p = 0;
171 }
172
173 d_dimInputProb = 0;
174 }
175
setInput(size_t dimInputProb_,const double * inputProb_)176 void DynProgProb::setInput (
177 size_t dimInputProb_,
178 const double *inputProb_) // array of input states : d_inputProb_p [0...dimStateProb - 1]
179 {
180 if (dimInputProb_ != getDimInputProb ())
181 {
182 freeInput ();
183 initInput (dimInputProb_);
184 }
185
186 if (getDimInputProb () > 0) MemUtil::memCpy (d_inputProb_p, inputProb_, sizeof (double) * getDimInputProb ());
187 }
188
update()189 void DynProgProb::update () // updates dynamic prog probs
190 {
191 assert (getValueFct ());
192 assert (getDimInputProb ());
193 assert (getInputProb ());
194
195 const size_t ARRAY_FAC = 2;
196 assert (1 < ARRAY_FAC);
197
198 long int i = 0;
199 size_t j = 0;
200
201 const double *oldArray = 0;
202 double *array = 0;
203 long int value = 0;
204 long int valueBegin = 0;
205 long int valueLower = 0;
206 long int valueUpper = 0;
207 /*sls deleted size_t arrayPos = 0;*/
208
209 oldArray = d_array_p [d_step % 2];
210 array = d_array_p [(d_step + 1) % 2];
211 valueLower = LONG_MAX;
212 valueUpper = LONG_MIN;
213
214 MemUtil::memZero (array, sizeof (double) * getArrayCapacity ());
215
216 for (i = getValueLower (); i < getValueUpper (); i++)
217 {
218 if (oldArray [getArrayPos (i)] == 0.0) continue;
219
220 for (j = 0; j < getDimInputProb (); j++)
221 {
222 if (getInputProb () [j] == 0.0) continue;
223
224 // adjust the reserve, if necessary
225 value = getValueFct () (i, j);
226 while (value < getValueBegin () || getValueEnd () <= value) {
227 valueBegin = getValueBegin ();
228 if (value < getValueBegin ()) valueBegin -= (ARRAY_FAC - 1) * getArrayCapacity ();
229 reserve (ARRAY_FAC * getArrayCapacity ());
230 setValueBegin (valueBegin);
231 oldArray = d_array_p [d_step % 2];
232 array = d_array_p [(d_step + 1) % 2];
233 }
234
235 if (value < valueLower) valueLower = value;
236 if (valueUpper < value) valueUpper = value;
237
238 // add the probability
239 assert (getValueBegin () <= i);
240 assert (i < getValueEnd ());
241 array [getArrayPos (value)] += oldArray [getArrayPos (i)] * getInputProb () [j];
242 }
243 }
244
245 d_valueLower = valueLower;
246 d_valueUpper = valueUpper + 1;
247 d_step++;
248 }
249
reserve(size_t arrayCapacity_)250 void DynProgProb::reserve (size_t arrayCapacity_) // new array capacity
251 // increases capacity of and copies d_array_p, while updating other variables
252 {
253 assert (getArrayCapacity () < arrayCapacity_);
254
255 double *array = new double [getArrayCapacity ()];
256
257 for (size_t i = 0; i < 2; i++)
258 {
259 MemUtil::memCpy (array, d_array_p [i], sizeof (double) * getArrayCapacity ());
260 delete [] d_array_p [i]; d_array_p [i] = 0;
261 d_array_p [i] = new double [arrayCapacity_];
262 MemUtil::memZero (d_array_p [i], sizeof (double) * arrayCapacity_);
263 MemUtil::memCpy (d_array_p [i], array, sizeof (double) * getArrayCapacity ());
264 }
265
266 d_arrayCapacity = arrayCapacity_;
267
268 delete [] array; array = 0;
269 }
270
setValueBegin(long int valueBegin_)271 void DynProgProb::setValueBegin (long int valueBegin_)
272 // resets the offset d_valueBegin
273 // assert (valueBegin_ <= getValueBegin ()) : enlarge the array only
274 // assert (offSet < getArrayCapacity ());
275 {
276 assert (valueBegin_ <= getValueBegin ());
277 size_t offSet = static_cast <size_t> (getValueBegin () - valueBegin_);
278 if (offSet == 0) return; // nothing to do
279
280 assert (offSet < getArrayCapacity ());
281
282 double *array = new double [getArrayCapacity ()];
283
284 for (size_t i = 0; i < 2; i++)
285 {
286 MemUtil::memCpy (array, d_array_p [i], sizeof (double) * getArrayCapacity ());
287 MemUtil::memZero (d_array_p [i], sizeof (double) * getArrayCapacity ());
288 MemUtil::memCpy (d_array_p [i] + offSet, array, sizeof (double) * (getArrayCapacity () - offSet));
289 }
290
291 delete [] array; array = 0;
292
293 d_valueBegin = valueBegin_;
294 }
295
296