libStatGen Software
1
|
00001 /* 00002 * Copyright (C) 2010 Regents of the University of Michigan 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include "IntArray.h" 00019 #include "Error.h" 00020 #include "Hash.h" 00021 #include "Sort.h" 00022 00023 #include <string.h> 00024 00025 int IntArray::alloc = 4; 00026 00027 IntArray::IntArray(int start_size) 00028 { 00029 count = start_size; 00030 size = (count + alloc) / alloc * alloc; 00031 items = new int [size]; 00032 } 00033 00034 IntArray::IntArray(const IntArray & source) 00035 { 00036 count = source.count; 00037 size = source.size; 00038 items = new int [size]; 00039 00040 for (int i = 0; i < count; i++) 00041 items[i] = source.items[i]; 00042 } 00043 00044 IntArray::~IntArray() 00045 { 00046 delete [] items; 00047 } 00048 00049 void IntArray::Grow(int new_size) 00050 { 00051 if (new_size > size) 00052 { 00053 if ((new_size >> 1) >= size) 00054 size = (new_size + alloc) / alloc * alloc; 00055 else 00056 { 00057 size = alloc; 00058 while (size <= new_size) 00059 size *= 2; 00060 } 00061 00062 int * new_items = new int [size]; 00063 for (int i = 0; i < count; i++) 00064 new_items[i] = items[i]; 00065 delete [] items; 00066 items = new_items; 00067 } 00068 } 00069 00070 int IntArray::Append(int value) 00071 { 00072 Grow(count + 1); 00073 items[count++] = value; 00074 return count; 00075 } 00076 00077 int IntArray::Append(const IntArray & rhs) 00078 { 00079 Grow(count + rhs.count); 00080 for (int i = 0; i < rhs.count; i++) 00081 items[count + i] = rhs.items[i]; 00082 count += rhs.count; 00083 return count; 00084 } 00085 00086 void IntArray::Set(int value) 00087 { 00088 for (int i = 0; i < count; i++) 00089 items[i] = value; 00090 } 00091 00092 void IntArray::SetSequence(int start, int increment) 00093 { 00094 for (int i = 0; i < count; i++, start += increment) 00095 items[i] = start; 00096 } 00097 00098 int IntArray::Delete(int index) 00099 { 00100 count--; 00101 if (count - index) 00102 memmove(items + index, items + index + 1, sizeof(int) *(count - index)); 00103 return count; 00104 } 00105 00106 void IntArray::InsertAt(int index, int value) 00107 { 00108 Grow(count + 1); 00109 if (count - index) 00110 memmove(items + index + 1, items + index, sizeof(int) *(count - index)); 00111 items[index] = value; 00112 count++; 00113 } 00114 00115 IntArray & IntArray::operator = (const IntArray & rhs) 00116 { 00117 Grow(rhs.count); 00118 count = rhs.count; 00119 for (int i = 0; i < count; i++) 00120 items[i] = rhs.items[i]; 00121 return *this; 00122 } 00123 00124 int IntArray::Sum(int start, int end) const 00125 { 00126 int result = 0; 00127 00128 for (int i = start; i <= end; i++) 00129 result += items[i]; 00130 00131 return result; 00132 } 00133 00134 double IntArray::dSum(int start, int end) const 00135 { 00136 double result = 0; 00137 00138 for (int i = start; i <= end; i++) 00139 result += items[i]; 00140 00141 return result; 00142 } 00143 00144 int IntArray::Max(int start, int end) const 00145 { 00146 if (start >= count) return 0; 00147 00148 int result = items[start]; 00149 00150 for (int i = start + 1; i <= end; i++) 00151 if (result < items[i]) 00152 result = items[i]; 00153 00154 return result; 00155 } 00156 00157 int IntArray::Min(int start, int end) const 00158 { 00159 if (start >= count) return 0; 00160 00161 int result = items[start]; 00162 00163 for (int i = start + 1; i <= end; i++) 00164 if (result > items[i]) 00165 result = items[i]; 00166 00167 return result; 00168 } 00169 00170 int IntArray::Find(int value) const 00171 { 00172 for (int i = 0; i < count; i++) 00173 if (value == items[i]) 00174 return i; 00175 return -1; 00176 } 00177 00178 int IntArray::BinarySearch(int value) const 00179 { 00180 int start = 0; 00181 int stop = count - 1; 00182 00183 while (start <= stop) 00184 { 00185 int mid = (start + stop) / 2; 00186 00187 if (items[mid] == value) 00188 return mid; 00189 00190 if (items[mid] > value) 00191 stop = mid - 1; 00192 else 00193 start = mid + 1; 00194 } 00195 00196 return -1; 00197 } 00198 00199 void IntArray::Zero() 00200 { 00201 for (int i = 0; i < count; i++) 00202 items[i] = 0; 00203 } 00204 00205 int IntArray::Compare(int * a, int * b) 00206 { 00207 return *a - *b; 00208 } 00209 00210 void IntArray::Sort() 00211 { 00212 QuickSort(items, count, sizeof(int), COMPAREFUNC Compare); 00213 } 00214 00215 void IntArray::Sort(IntArray & freeRider) 00216 { 00217 QuickSort2(items, freeRider.items, count, sizeof(int), COMPAREFUNC Compare); 00218 } 00219 00220 00221 void IntArray::Reverse() 00222 { 00223 for (int i = 0, j = count - 1; i < j; i++, j--) 00224 Swap(i, j); 00225 } 00226 00227 int IntArray::CountIfGreater(int threshold) const 00228 { 00229 int result = 0; 00230 00231 for (int i = 0; i < count; i++) 00232 if (items[i] > threshold) 00233 result++; 00234 00235 return result; 00236 } 00237 00238 int IntArray::CountIfGreaterOrEqual(int treshold) const 00239 { 00240 int result = 0; 00241 00242 for (int i = 0; i < count; i++) 00243 if (items[i] >= treshold) 00244 result++; 00245 00246 return result; 00247 } 00248 00249 void IntArray::Add(int term) 00250 { 00251 for (int i = 0; i < count; i++) 00252 items[i] += term; 00253 } 00254 00255 void IntArray::Multiply(int factor) 00256 { 00257 for (int i = 0; i < count; i++) 00258 items[i] *= factor; 00259 } 00260 00261 void IntArray::Divide(int denominator) 00262 { 00263 for (int i = 0; i < count; i++) 00264 items[i] /= denominator; 00265 } 00266 00267 void IntArray::Stack(const IntArray & a) 00268 { 00269 int end = count; 00270 00271 Dimension(count + a.count); 00272 00273 for (int i = 0; i < a.count; i++) 00274 items[i + end] = a[i]; 00275 } 00276 00277 bool IntArray::operator == (const IntArray & rhs) const 00278 { 00279 if (count != rhs.count) 00280 return false; 00281 00282 for (int i = 0; i < rhs.count; i++) 00283 if (items[i] != rhs.items[i]) 00284 return false; 00285 00286 return true; 00287 } 00288 00289 bool IntArray::operator != (const IntArray & rhs) const 00290 { 00291 return !(*this == rhs); 00292 } 00293 00294 // Check if all values are in ascending or descending order 00295 // 00296 00297 bool IntArray::isAscending() 00298 { 00299 for (int i = 1; i < count; i++) 00300 if (items[i] < items[i - 1]) 00301 return false; 00302 return true; 00303 } 00304 00305 bool IntArray::isDescending() 00306 { 00307 for (int i = 1; i < count; i++) 00308 if (items[i] > items[i - 1]) 00309 return false; 00310 return true; 00311 } 00312 00313 void IntArray::Add(const IntArray & v) 00314 { 00315 if (Length() != v.Length()) 00316 error("IntArray::Add - vectors have different lengths\n" 00317 "IntArrays - Left[%d] += Right[%d] ", 00318 Length(), v.Length()); 00319 00320 for (int i = 0; i < Length(); i++) 00321 items[i] += v[i]; 00322 } 00323 00324 int IntArray::InnerProduct(IntArray & v) 00325 { 00326 if (Length() != v.Length()) 00327 error("IntArray::InnerProduct - vectors have different dimensions\n" 00328 "IntArrays - Left[%d] * Right[%d] ", 00329 Length(), v.Length()); 00330 00331 int sum = 0; 00332 for (int i = 0; i < Length(); i++) 00333 sum += items[i] * v[i]; 00334 00335 return sum; 00336 } 00337 00338 void IntArray::Swap(IntArray & rhs) 00339 { 00340 int * temp = rhs.items; 00341 rhs.items = items; 00342 items = temp; 00343 00344 int swap = rhs.count; 00345 rhs.count = count; 00346 count = swap; 00347 00348 swap = rhs.size; 00349 rhs.size = size; 00350 size = swap; 00351 } 00352 00353 void IntArray::Print(FILE * output) 00354 { 00355 Print(output, "Array of Integers"); 00356 } 00357 00358 void IntArray::Print(FILE * output, const char * label) 00359 { 00360 fprintf(output, "%s [%d elements]: ", label, count); 00361 00362 for (int i = 0; i < count; i++) 00363 fprintf(output, "%d ", items[i]); 00364 00365 fprintf(output, "\n"); 00366 } 00367 00368 void IntArray::PushIfNew(int value) 00369 { 00370 for (int i = 0; i < count; i++) 00371 if (items[i] == value) 00372 return; 00373 00374 Push(value); 00375 } 00376 00377 int IntArray::Product() 00378 { 00379 int product = 1; 00380 00381 for (int i = 0; i < count; i++) 00382 product *= items[i]; 00383 00384 return product; 00385 } 00386 00387 double IntArray::DoubleProduct() 00388 { 00389 double product = 1.0; 00390 00391 for (int i = 0; i < count; i++) 00392 product *= items[i]; 00393 00394 return product; 00395 } 00396 00397 int IntArray::Hash(int initval) 00398 { 00399 return hash((unsigned char *) items, sizeof(int) * count, initval); 00400 } 00401 00402 int IntArray::SumProduct(const IntArray & weight) const 00403 { 00404 if (count != weight.count) 00405 error("IntArray::SumProduct called with different sized arrays\n"); 00406 00407 int sum = 0; 00408 for (int i = 0; i < count; i++) 00409 sum += items[i] * weight[i]; 00410 00411 return sum; 00412 } 00413 00414 double IntArray::dSumProduct(const IntArray & weight) const 00415 { 00416 if (count != weight.count) 00417 error("IntArray::dSumProduct called with different sized arrays\n"); 00418 00419 double sum = 0.0; 00420 for (int i = 0; i < count; i++) 00421 sum += items[i] * weight[i]; 00422 00423 return sum; 00424 } 00425