Пример #1
0
// Helper function to implement the base-class version of values() when rank > 4.
void AMDataSource::valuesImplementationRecursive(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, AMnDIndex current, int dimension, double **outputValues) const
{
    if(dimension == current.rank()-1) {	// base case: final dimension
        for(int i=indexStart.at(dimension); i<=indexEnd.at(dimension); ++i) {
            current[dimension] = i;
            *((*outputValues)++) = double(value(current));
        }
    }
    else {
        for(int i=indexStart.at(dimension); i<indexEnd.at(dimension); ++i) {
            current[dimension] = i;
            valuesImplementationRecursive(indexStart, indexEnd, current, dimension+1, outputValues);
        }
    }
}
Пример #2
0
void AMInMemoryDataStore::valuesImplementationRecursive(const AMnDIndex &siStart, const AMnDIndex &siEnd, int measurementId, const AMnDIndex &miStart, const AMnDIndex &miEnd, double **outputValues, int scanDimension, int scanSpaceOffset, const AMnDIndex &fullSize, int measurementSpaceSize) const {

	if(scanDimension == axes_.count()-1) { // base case: last (final) dimension
		for(int i=siStart.at(scanDimension); i<=siEnd.at(scanDimension); ++i) {
			measurementValues(scanPoints_.at(scanSpaceOffset+i).at(measurementId), fullSize, miStart, miEnd, *outputValues);
			*outputValues += measurementSpaceSize;
		}
	}
	else {
		for(int i=siStart.at(scanDimension); i<=siEnd.at(scanDimension); ++i) {
			// get product of all higher scan dimensions:
			int multiplier = 1;
			for(int mu=scanDimension+1; mu<siStart.rank(); ++mu)
				multiplier *= scanSize_.at(mu);

			// recurse:
			valuesImplementationRecursive(siStart, siEnd, measurementId, miStart, miEnd, outputValues, scanDimension+1, scanSpaceOffset + i*multiplier, fullSize, measurementSpaceSize);
		}
	}
}
Пример #3
0
/* This base-class implementation simply calls value() repeatedly and should absolutely be re-implemented for better performance. */
bool AMDataSource::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const
{
    static bool programmerWarningIssued = false;
    if(!programmerWarningIssued) {
        AMErrorMon::debug(0, AMDATASOURCE_VALUES_BASE_IMPLEMENTATION_CALLED, QString("AMDataSource: Warning: Data source '%1' is using the base implementation of AMDataSource::values(), which is very inefficient. Re-implement values() to improve performance.  (This warning will only be given once.)").arg(name()));
        programmerWarningIssued = true;	// one problem with this warning method: if multiple classes have this problem, it will only be given once, and the subsequent classes will not be named.
    }

    int _rank = rank();

    if(indexStart.rank() != _rank || indexEnd.rank() != _rank)
        return false;

#ifdef AM_ENABLE_BOUNDS_CHECKING
    for(int mu=0; mu<_rank; ++mu) {
        if(indexEnd.at(mu) >= size(mu))
            return false;
        if(indexEnd.at(mu) < indexStart.at(mu))
            return false;
    }
#endif

    switch(_rank) {
    case 0:
        *outputValues = double(value(indexStart));
        break;

    case 1: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            *(outputValues++) = double(value(AMnDIndex(i)));
        break;
    }

    case 2: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            for(int j=indexStart.j(); j<=indexEnd.j(); ++j)
                *(outputValues++) = double(value(AMnDIndex(i,j)));
        break;
    }

    case 3: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            for(int j=indexStart.j(); j<=indexEnd.j(); ++j)
                for(int k=indexStart.k(); k<=indexEnd.k(); ++k)
                    *(outputValues++) = double(value(AMnDIndex(i,j,k)));
        break;
    }

    case 4: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            for(int j=indexStart.j(); j<=indexEnd.j(); ++j)
                for(int k=indexStart.k(); k<=indexEnd.k(); ++k)
                    for(int l=indexStart.l(); l<=indexEnd.l(); ++l)
                        *(outputValues++) = double(value(AMnDIndex(i,j,k,l)));
        break;
    }

    default: {
        valuesImplementationRecursive(indexStart, indexEnd, AMnDIndex(_rank, AMnDIndex::DoNotInit), 0, &outputValues);
        break;
    }
    }
    return true;
}
Пример #4
0
bool AMInMemoryDataStore::values(const AMnDIndex &scanIndexStart, const AMnDIndex &scanIndexEnd, int measurementId, const AMnDIndex &measurementIndexStart, const AMnDIndex &measurementIndexEnd, double *outputValues) const {

	if(scanIndexStart.rank() != axes_.count() || scanIndexEnd.rank() != axes_.count())
		return false;
	if(measurementId >= measurements_.count())
		return false;

	const AMMeasurementInfo& mi = measurements_.at(measurementId);
	if(measurementIndexStart.rank() != mi.rank() || measurementIndexEnd.rank() != mi.rank())
		return false;

#ifdef AM_ENABLE_BOUNDS_CHECKING
	// check bounds for scan axes
	for(int mu=axes_.count()-1; mu >= 0; --mu) {
		if(scanIndexEnd.at(mu) < scanIndexStart.at(mu))
			return false;
		if(scanIndexEnd.at(mu) >= axes_.at(mu).size)
			return false;
	}

	// check bounds for measurement axes
	for(int mu=mi.rank()-1; mu >= 0; --mu) {
		if(measurementIndexEnd.at(mu) < measurementIndexStart.at(mu))
			return false;
		if(measurementIndexEnd.at(mu) >= mi.size(mu))
			return false;
	}
#endif

	// Determine the full size of the measurement (not necessarily the size of the block that we want to read out).
	AMnDIndex measurementSize = mi.size();
	int flatMeasurementSize = measurementSize.product();

	// specific cases of scan rank:
	switch(scanIndexStart.rank()) {
	case 0: {
		// null scan space; just copy in the measurement block

		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			outputValues[0] = double(scalarScanPoint_.at(measurementId).at(0));
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize)	// if asking for the whole measurement, can optimize.
				measurementValues(scalarScanPoint_.at(measurementId), flatMeasurementSize, outputValues);
			else
				measurementValues(scalarScanPoint_.at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
		}
		break;
	}

	case 1:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i)
				*(outputValues++) = double(scanPoints_.at(i).at(measurementId).at(0));
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize)	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					measurementValues(scanPoints_.at(i).at(measurementId), flatMeasurementSize, outputValues);
					outputValues += measurementSpaceSize;
				}
			else
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					measurementValues(scanPoints_.at(i).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
					outputValues += measurementSpaceSize;
				}
		}
		break;
	}

	case 2:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
				int ic = i*scanSize_.j();
				for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
					*(outputValues++) = double(scanPoints_.at(ic+j).at(measurementId).at(0));
				}
			}
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize) {	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						measurementValues(scanPoints_.at(ic+j).at(measurementId), flatMeasurementSize, outputValues);
						outputValues += measurementSpaceSize;
					}
				}
			}
			else {
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						measurementValues(scanPoints_.at(ic+j).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
						outputValues += measurementSpaceSize;
					}
				}
			}
		}
		break;
	}

	case 3:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
				int ic = i*scanSize_.j()*scanSize_.k();
				for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
					int jc = j*scanSize_.k();
					for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
						*(outputValues++) = double(scanPoints_.at(ic+jc+k).at(measurementId).at(0));
					}
				}
			}
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize) {	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							measurementValues(scanPoints_.at(ic+jc+k).at(measurementId), flatMeasurementSize, outputValues);
							outputValues += measurementSpaceSize;
						}
					}
				}
			}
			else {
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							measurementValues(scanPoints_.at(ic+jc+k).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
							outputValues += measurementSpaceSize;
						}
					}
				}
			}
		}
		break;
	}

	case 4:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
				int ic = i*scanSize_.j()*scanSize_.k()*scanSize_.l();
				for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
					int jc = j*scanSize_.k()*scanSize_.l();
					for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
						int kc = k*scanSize_.l();
						for(int l=scanIndexStart.l(); l<=scanIndexEnd.l(); ++l) {
							*(outputValues++) = double(scanPoints_.at(ic+jc+kc+l).at(measurementId).at(0));
						}
					}
				}
			}
		}

		else {
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize) {	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k()*scanSize_.l();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k()*scanSize_.l();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							int kc = k*scanSize_.l();
							for(int l=scanIndexStart.l(); l<=scanIndexEnd.l(); ++l) {
								measurementValues(scanPoints_.at(ic+jc+kc+l).at(measurementId), flatMeasurementSize, outputValues);
								outputValues += measurementSpaceSize;
							}
						}
					}
				}
			}
			else {
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k()*scanSize_.l();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k()*scanSize_.l();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							int kc = k*scanSize_.l();
							for(int l=scanIndexStart.l(); l<=scanIndexEnd.l(); ++l) {
								measurementValues(scanPoints_.at(ic+jc+kc+l).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
								outputValues += measurementSpaceSize;
							}
						}
					}
				}
			}
		}
		break;
	}
	default:{
		int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

		valuesImplementationRecursive(scanIndexStart, scanIndexEnd, measurementId, measurementIndexStart, measurementIndexEnd, &outputValues, 0, 0, measurementSize, measurementSpaceSize);
		return false;
		break;
	}
	}

	return true;
}