libStatGen Software  1
IntArray.cpp
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends