Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "raq.h"
- #include <iostream>
- #include <iomanip>
- #include <cmath>
- // Create the RAQ object; perform precomputation
- RAQ::RAQ(std::vector<float> data){
- m_dataCopy = data;
- m_dataSize = int(data.size());
- raqComp();
- }
- // Query the RAQ for interval [i, j]
- float RAQ::query(int i, int j) const{
- if(0 <= i and i <= j and j <= m_dataSize-1){
- return m_avgValues[i][j];
- }
- else{
- throw std::domain_error("RAQ::query() i or j value is out of bounds");
- }
- }
- // Dump the RAQ data structure to stdout
- void RAQ::dump() const{
- for (int i = 0; i < m_avgValues.size(); i++){
- for (int j = i; j < m_avgValues[i].size(); j++){
- std::cout << " " << std::left << std::setw(7) << m_avgValues[i][j];
- }
- std::cout << std::endl;
- }
- std::cout << std::right;
- }
- void RAQ::raqComp(){
- for(int i = 0; i < m_dataSize; i++){
- std::vector<float> temp {};
- if(i != 0){
- for (int j = 0; j < i; j++){
- temp.push_back(0);
- }
- }
- temp.push_back(m_dataCopy[i]);
- temp = update(i, i, m_dataCopy[i], temp);
- m_avgValues.push_back(temp);
- }
- }
- std::vector<float> RAQ::update(float i, float j, float prevAvg, std::vector<float> temp){
- float avg;
- //base case if j = size-1
- if(j == m_dataSize - 1){
- return temp;
- }
- else{
- avg = ( ( (j - i + 1) * prevAvg ) + m_dataCopy[j+1] ) / (j-i+2);
- temp.push_back(avg);
- return update(i, j+1, avg, temp);
- }
- }
- //Beginning of BlockRAQ Code
- // Create the BlockRAQ object; perform precomputation
- BlockRAQ::BlockRAQ(std::vector<float> data){
- //initialize member variables
- m_dataCopy = data;
- m_blockSize = calcBlockSize();
- m_dataSize = int(data.size());
- m_numBlocks = ceil(m_dataSize / m_blockSize);
- //make the precomputations
- blockComp();
- }
- // Query the BlockRAQ for interval [i, j]
- float BlockRAQ::query(int i, int j) const{
- if(0 <= i and i <= j and j <= m_dataSize-1){
- float sum = 0;
- float range = j - i + 1;
- int size = m_blockSize;
- //low is the lower bound
- int low = i;
- //for values before any full blocks
- while (low <= j and low % size != 0){
- sum += m_dataCopy[low];
- low++;
- }
- //for values that make up entire blocks
- while(low +size <= j+1 and low % size == 0){
- sum += m_blockAverages[(low/size)] * 3;
- low += size;
- }
- //for values remaining after a block
- while (low <= j){
- sum += m_dataCopy[low];
- low++;
- }
- return (sum/range);
- }
- else{
- throw std::domain_error("BlockRAQ::query() i or j value is out of bounds");
- }
- }
- // Dump the BlockRAQ data structure to stdout
- void BlockRAQ::dump() const{
- std::cout << "Num blocks: " << m_numBlocks<< std::endl;
- std::cout << "Block size: " << m_blockSize << std::endl;
- std::cout << "Block averages: " << std::endl;
- for(int i = 0; i < int(m_blockAverages.size()); i++){
- std::cout << m_blockAverages[i] << " ";
- }
- std::cout << std::endl;
- }
- void BlockRAQ::blockComp(){
- int tempSum = 0;
- float avg = 0;
- float counter = 0;
- for (int i = 0; i < m_dataSize; i++){
- //summing the values for each block subgroup
- if (counter < m_blockSize){
- tempSum += m_dataCopy[i];
- counter++;
- }
- //if the block is the max size we add the average to the vector
- else{
- m_blockSums.push_back(tempSum);
- avg = tempSum / counter;
- m_blockAverages.push_back(avg);
- //if we're not at the end of the data vector we start the new sum
- tempSum = 0;
- tempSum += m_dataCopy[i];
- counter = 1;
- }
- }
- //This is a catch for a smaller final block
- //if the last block isn't completed than the tempSum value
- //will remain and we can add the smaller block to the averages
- if(tempSum != 0){
- m_blockSums.push_back(tempSum);
- avg = tempSum / counter;
- m_blockAverages.push_back(avg);
- }
- }
- int BlockRAQ::calcBlockSize(){
- int size = int(m_dataCopy.size());
- int bSize = (int) sqrt((float) size);
- return bSize;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement