Example #1
0
ColumnPtr ColumnArray::indexImpl(const PaddedPODArray<T> & indexes, size_t limit) const
{
    if (limit == 0)
        return ColumnArray::create(data);

    /// Convert indexes to UInt64 in case of overflow.
    auto nested_indexes_column = ColumnUInt64::create();
    PaddedPODArray<UInt64> & nested_indexes = nested_indexes_column->getData();
    nested_indexes.reserve(getOffsets().back());

    auto res = ColumnArray::create(data->cloneEmpty());

    Offsets & res_offsets = res->getOffsets();
    res_offsets.resize(limit);
    size_t current_offset = 0;

    for (size_t i = 0; i < limit; ++i)
    {
        for (size_t j = 0; j < sizeAt(indexes[i]); ++j)
            nested_indexes.push_back(offsetAt(indexes[i]) + j);
        current_offset += sizeAt(indexes[i]);
        res_offsets[i] = current_offset;
    }

    if (current_offset != 0)
        res->data = data->index(*nested_indexes_column, current_offset);

    return res;
}
Example #2
0
void ColumnArray::insertDefault()
{
    /// NOTE 1: We can use back() even if the array is empty (due to zero -1th element in PODArray).
    /// NOTE 2: We cannot use reference in push_back, because reference get invalidated if array is reallocated.
    auto last_offset = getOffsets().back();
    getOffsets().push_back(last_offset);
}
Example #3
0
void ColumnArray::insert(const Field & x)
{
    const Array & array = DB::get<const Array &>(x);
    size_t size = array.size();
    for (size_t i = 0; i < size; ++i)
        getData().insert(array[i]);
    getOffsets().push_back(getOffsets().back() + size);
}
Example #4
0
void ColumnArray::insertFrom(const IColumn & src_, size_t n)
{
    const ColumnArray & src = static_cast<const ColumnArray &>(src_);
    size_t size = src.sizeAt(n);
    size_t offset = src.offsetAt(n);

    getData().insertRangeFrom(src.getData(), offset, size);
    getOffsets().push_back(getOffsets().back() + size);
}
Example #5
0
const char * ColumnArray::deserializeAndInsertFromArena(const char * pos)
{
    size_t array_size = unalignedLoad<size_t>(pos);
    pos += sizeof(array_size);

    for (size_t i = 0; i < array_size; ++i)
        pos = getData().deserializeAndInsertFromArena(pos);

    getOffsets().push_back(getOffsets().back() + array_size);
    return pos;
}
Example #6
0
ColumnPtr ColumnArray::filterNumber(const Filter & filt, ssize_t result_size_hint) const
{
	if (getOffsets().size() == 0)
		return std::make_shared<ColumnArray>(data);

	auto res = std::make_shared<ColumnArray>(data->cloneEmpty());

	auto & res_elems = static_cast<ColumnVector<T> &>(res->getData()).getData();
	Offsets_t & res_offsets = res->getOffsets();

	filterArraysImpl<T>(static_cast<const ColumnVector<T> &>(*data).getData(), getOffsets(), res_elems, res_offsets, filt, result_size_hint);
	return res;
}
Example #7
0
//this function will print a samfile from the bamfile
int motherView(bufReader *rd,int nFiles,std::vector<regs>regions) {
  aRead b;
  b.vDat=new uint8_t[RLEN];
  kstring_t str;  str.s=NULL; str.l=str.m=0;
  
  if(regions.size()==0) {//print all
    int block_size;
    while(SIG_COND && bgzf_read(rd[0].fp,&block_size,sizeof(int))){
      getAlign(rd[0].fp,block_size,b);
      printReadBuffered(b,rd[0].hd,str);
      fprintf(stdout,"%s",str.s);
    }
  }else {
    for(int i=0;i<(int)regions.size();i++){
      int tmpRef = regions[i].refID;
      int tmpStart = regions[i].start;
      int tmpStop = regions[i].stop;
      
      getOffsets(rd[0].bamfname,rd[0].hd,rd[0].it,tmpRef,tmpStart,tmpStop);
      int ret =0;
      while(SIG_COND){
	ret = bam_iter_read(rd[0].fp, &rd[0].it, b);
	if(ret<0)
	  break;
	printReadBuffered(b,rd[0].hd,str);
	fprintf(stdout,"%s",str.s);
      }
      free(rd[0].it.off);//the offsets
    }
    free(str.s);
    delete [] b.vDat;
  }
  return 0;
}
Example #8
0
void ColumnArray::insertRangeFrom(const IColumn & src, size_t start, size_t length)
{
	if (length == 0)
		return;

	const ColumnArray & src_concrete = static_cast<const ColumnArray &>(src);

	if (start + length > src_concrete.getOffsets().size())
		throw Exception("Parameter out of bound in ColumnArray::insertRangeFrom method.",
			ErrorCodes::PARAMETER_OUT_OF_BOUND);

	size_t nested_offset = src_concrete.offsetAt(start);
	size_t nested_length = src_concrete.getOffsets()[start + length - 1] - nested_offset;

	data->insertRangeFrom(src_concrete.getData(), nested_offset, nested_length);

	Offsets_t & cur_offsets = getOffsets();
	const Offsets_t & src_offsets = src_concrete.getOffsets();

	if (start == 0 && cur_offsets.empty())
	{
		cur_offsets.assign(src_offsets.begin(), src_offsets.begin() + length);
	}
	else
	{
		size_t old_size = cur_offsets.size();
		size_t prev_max_offset = old_size ? cur_offsets.back() : 0;
		cur_offsets.resize(old_size + length);

		for (size_t i = 0; i < length; ++i)
			cur_offsets[old_size + i] = src_offsets[start + i] - nested_offset + prev_max_offset;
	}
}
Example #9
0
Eigen::VectorXd& BCIDataSet::getInstance(int i)
{
  int epoch = 0, t0 = 0;
  getOffsets(i, epoch, t0);
  buildInstance(epoch, t0);
  return tempInstance;
}
Example #10
0
ColumnPtr ColumnArray::filterTuple(const Filter & filt, ssize_t result_size_hint) const
{
    if (getOffsets().size() == 0)
        return ColumnArray::create(data);

    const ColumnTuple & tuple = static_cast<const ColumnTuple &>(*data);

    /// Make temporary arrays for each components of Tuple, then filter and collect back.

    size_t tuple_size = tuple.getColumns().size();

    if (tuple_size == 0)
        throw Exception("Logical error: empty tuple", ErrorCodes::LOGICAL_ERROR);

    Columns temporary_arrays(tuple_size);
    for (size_t i = 0; i < tuple_size; ++i)
        temporary_arrays[i] = ColumnArray(tuple.getColumns()[i]->assumeMutable(), getOffsetsPtr()->assumeMutable())
                .filter(filt, result_size_hint);

    Columns tuple_columns(tuple_size);
    for (size_t i = 0; i < tuple_size; ++i)
        tuple_columns[i] = static_cast<const ColumnArray &>(*temporary_arrays[i]).getDataPtr();

    return ColumnArray::create(
        ColumnTuple::create(tuple_columns),
        static_cast<const ColumnArray &>(*temporary_arrays.front()).getOffsetsPtr());
}
Example #11
0
/* Median filter: pixel goes with a majority of neighboring pixel */
void medianify(unsigned char *mask, unsigned char *median, int rows, int cols) {

  long imagesize, i;
  int j, total;
  int *offsets;

  imagesize = rows * cols;
  offsets = getOffsets(cols, imagesize);

  for (i=0; i < imagesize; ++i){ /* for each pixel */

    /* don't process the 1 pixel layer around the whole image */
    if (edge(i, cols, imagesize)) median[i] = mask[i]; 
    
    else {

      total = 0;

      /* count number of foreground pixels in i and neighbors, set i to majority */
      for (j = 0; j < 9; ++j) {
        if ( mask[offsets[j] + i] == FOREGROUND) {
          ++total;
        }
      }

      if (total > 4) {
        median[i] = FOREGROUND;
      }
      
      else {
        median[i] = BACKGROUND;
      }
    }  
  }
}
Example #12
0
void ColumnArray::popBack(size_t n)
{
    auto & offsets_data = getOffsets();
    size_t nested_n = offsets_data.back() - offsetAt(offsets_data.size() - n);
    if (nested_n)
        getData().popBack(nested_n);
    offsets_data.resize_assume_reserved(offsets_data.size() - n);
}
Example #13
0
ColumnPtr ColumnArray::filterGeneric(const Filter & filt, ssize_t result_size_hint) const
{
	size_t size = getOffsets().size();
	if (size != filt.size())
		throw Exception("Size of filter doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

	if (size == 0)
		return std::make_shared<ColumnArray>(data);

	Filter nested_filt(getOffsets().back());
	for (size_t i = 0; i < size; ++i)
	{
		if (filt[i])
			memset(&nested_filt[offsetAt(i)], 1, sizeAt(i));
		else
			memset(&nested_filt[offsetAt(i)], 0, sizeAt(i));
	}

	std::shared_ptr<ColumnArray> res = std::make_shared<ColumnArray>(data);

	ssize_t nested_result_size_hint = 0;
	if (result_size_hint < 0)
		nested_result_size_hint = result_size_hint;
	else if (result_size_hint && result_size_hint < 1000000000 && data->size() < 1000000000)	/// Избегаем переполнения.
		nested_result_size_hint = result_size_hint * data->size() / size;

	res->data = data->filter(nested_filt, nested_result_size_hint);

	Offsets_t & res_offsets = res->getOffsets();
	if (result_size_hint)
		res_offsets.reserve(result_size_hint > 0 ? result_size_hint : size);

	size_t current_offset = 0;
	for (size_t i = 0; i < size; ++i)
	{
		if (filt[i])
		{
			current_offset += sizeAt(i);
			res_offsets.push_back(current_offset);
		}
	}

	return res;
}
/// Put implementation here to avoid extra linking dependencies for clickhouse_common_io
void dumpToArrayColumns(const Counters & counters, DB::IColumn * column_names_, DB::IColumn * column_values_, bool nonzero_only)
{
    /// Convert ptr and make simple check
    auto column_names = (column_names_) ? &typeid_cast<DB::ColumnArray &>(*column_names_) : nullptr;
    auto column_values = (column_values_) ? &typeid_cast<DB::ColumnArray &>(*column_values_) : nullptr;

    size_t size = 0;

    for (Event event = 0; event < Counters::num_counters; ++event)
    {
        UInt64 value = counters[event].load(std::memory_order_relaxed);

        if (nonzero_only && 0 == value)
            continue;

        ++size;

        if (column_names)
        {
            const char * desc = ProfileEvents::getName(event);
            column_names->getData().insertData(desc, strlen(desc));
        }

        if (column_values)
            column_values->getData().insert(value);
    }

    if (column_names)
    {
        auto & offsets = column_names->getOffsets();
        offsets.push_back(offsets.back() + size);
    }

    if (column_values)
    {
        /// Nested columns case
        bool the_same_offsets = column_names && column_names->getOffsetsPtr().get() == column_values->getOffsetsPtr().get();
        if (!the_same_offsets)
        {
            auto & offsets = column_values->getOffsets();
            offsets.push_back(offsets.back() + size);
        }
    }
}
Example #15
0
ColumnPtr ColumnArray::filterGeneric(const Filter & filt, ssize_t result_size_hint) const
{
    size_t size = getOffsets().size();
    if (size != filt.size())
        throw Exception("Size of filter doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    if (size == 0)
        return ColumnArray::create(data);

    Filter nested_filt(getOffsets().back());
    for (size_t i = 0; i < size; ++i)
    {
        if (filt[i])
            memset(&nested_filt[offsetAt(i)], 1, sizeAt(i));
        else
            memset(&nested_filt[offsetAt(i)], 0, sizeAt(i));
    }

    auto res = ColumnArray::create(data->cloneEmpty());

    ssize_t nested_result_size_hint = 0;
    if (result_size_hint < 0)
        nested_result_size_hint = result_size_hint;
    else if (result_size_hint && result_size_hint < 1000000000 && data->size() < 1000000000)    /// Avoid overflow.
         nested_result_size_hint = result_size_hint * data->size() / size;

    res->data = data->filter(nested_filt, nested_result_size_hint);

    Offsets & res_offsets = res->getOffsets();
    if (result_size_hint)
        res_offsets.reserve(result_size_hint > 0 ? result_size_hint : size);

    size_t current_offset = 0;
    for (size_t i = 0; i < size; ++i)
    {
        if (filt[i])
        {
            current_offset += sizeAt(i);
            res_offsets.push_back(current_offset);
        }
    }

    return res;
}
Example #16
0
void MatrixOpData::cleanUp(double offsetScale)
{
    const ArrayDouble & a = getArray();
    const ArrayDouble::Values & m = a.getValues();
    const unsigned long dim = a.getLength();

    // Estimate the magnitude of the matrix.
    double max_val = 0.;
    for (unsigned long i = 0; i<dim; ++i)
    {
        for (unsigned long j = 0; j<dim; ++j)
        {
            const double val = fabs(m[i * dim + j]);
            max_val = max_val > val ? max_val : val;
        }
    }

    // Determine an absolute tolerance.
    // TODO: For double matrices a smaller tolerance could be used.  However we
    // have matrices that may have been quantized to less than double precision
    // either from being written to files or via the factories that take float
    // args.  In any case, the tolerance is small enough to pick up anything
    // that would be significant in the context of color management.
    const double scale = max_val > 1e-4 ? max_val : 1e-4;
    const double abs_tol = scale * 1e-6;

    // Replace values that are close to integers by exact values.
    for (unsigned long i = 0; i<dim; ++i)
    {
        for (unsigned long j = 0; j<dim; ++j)
        {
            const double val = m[i * dim + j];
            const double round_val = round(val);
            const double diff = fabs(val - round_val);
            if (diff < abs_tol)
            {
                setArrayValue(i * dim + j, round_val);
            }
        }
    }

    // Do likewise for the offsets.
    const double scale2 = offsetScale > 1e-4 ? offsetScale : 1e-4;
    const double abs_tol2 = scale2 * 1e-6;

    for (unsigned long i = 0; i<dim; ++i)
    {
        const double val = getOffsets()[i];
        const double round_val = round(val);
        const double diff = fabs(val - round_val);
        if (diff < abs_tol2)
        {
            setOffsetValue(i, round_val);
        }
    }
}
Example #17
0
bool ColumnArray::hasEqualOffsets(const ColumnArray & other) const
{
    if (offsets == other.offsets)
        return true;

    const Offsets & offsets1 = getOffsets();
    const Offsets & offsets2 = other.getOffsets();
    return offsets1.size() == offsets2.size()
        && (offsets1.size() == 0 || 0 == memcmp(offsets1.data(), offsets2.data(), sizeof(offsets1[0]) * offsets1.size()));
}
Example #18
0
void ColumnArray::insertData(const char * pos, size_t length)
{
    /** Similarly - only for arrays of fixed length values.
      */
    IColumn * data_ = &getData();
    if (!data_->isFixedAndContiguous())
        throw Exception("Method insertData is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);

    size_t field_size = data_->sizeOfValueIfFixed();

    const char * end = pos + length;
    size_t elems = 0;
    for (; pos + field_size <= end; pos += field_size, ++elems)
        data_->insertData(pos, field_size);

    if (pos != end)
        throw Exception("Incorrect length argument for method ColumnArray::insertData", ErrorCodes::BAD_ARGUMENTS);

    getOffsets().push_back(getOffsets().back() + elems);
}
Example #19
0
ColumnPtr ColumnArray::filterNullable(const Filter & filt, ssize_t result_size_hint) const
{
    if (getOffsets().size() == 0)
        return ColumnArray::create(data);

    const ColumnNullable & nullable_elems = static_cast<const ColumnNullable &>(*data);

    auto array_of_nested = ColumnArray::create(nullable_elems.getNestedColumnPtr(), offsets);
    auto filtered_array_of_nested_owner = array_of_nested->filter(filt, result_size_hint);
    auto & filtered_array_of_nested = static_cast<const ColumnArray &>(*filtered_array_of_nested_owner);
    auto & filtered_offsets = filtered_array_of_nested.getOffsetsPtr();

    auto res_null_map = ColumnUInt8::create();

    filterArraysImplOnlyData(nullable_elems.getNullMapData(), getOffsets(), res_null_map->getData(), filt, result_size_hint);

    return ColumnArray::create(
        ColumnNullable::create(
            filtered_array_of_nested.getDataPtr(),
            std::move(res_null_map)),
        filtered_offsets);
}
Example #20
0
ColumnPtr ColumnArray::replicateNumber(const Offsets & replicate_offsets) const
{
    size_t col_size = size();
    if (col_size != replicate_offsets.size())
        throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

    MutableColumnPtr res = cloneEmpty();

    if (0 == col_size)
        return res;

    ColumnArray & res_ = typeid_cast<ColumnArray &>(*res);

    const typename ColumnVector<T>::Container & src_data = typeid_cast<const ColumnVector<T> &>(*data).getData();
    const Offsets & src_offsets = getOffsets();

    typename ColumnVector<T>::Container & res_data = typeid_cast<ColumnVector<T> &>(res_.getData()).getData();
    Offsets & res_offsets = res_.getOffsets();

    res_data.reserve(data->size() / col_size * replicate_offsets.back());
    res_offsets.reserve(replicate_offsets.back());

    Offset prev_replicate_offset = 0;
    Offset prev_data_offset = 0;
    Offset current_new_offset = 0;

    for (size_t i = 0; i < col_size; ++i)
    {
        size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
        size_t value_size = src_offsets[i] - prev_data_offset;

        for (size_t j = 0; j < size_to_replicate; ++j)
        {
            current_new_offset += value_size;
            res_offsets.push_back(current_new_offset);

            if (value_size)
            {
                res_data.resize(res_data.size() + value_size);
                memcpy(&res_data[res_data.size() - value_size], &src_data[prev_data_offset], value_size * sizeof(T));
            }
        }

        prev_replicate_offset = replicate_offsets[i];
        prev_data_offset = src_offsets[i];
    }

    return res;
}
Example #21
0
ColumnPtr ColumnArray::permute(const Permutation & perm, size_t limit) const
{
	size_t size = getOffsets().size();

	if (limit == 0)
		limit = size;
	else
		limit = std::min(size, limit);

	if (perm.size() < limit)
		throw Exception("Size of permutation is less than required.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

	if (limit == 0)
		return std::make_shared<ColumnArray>(data);

	Permutation nested_perm(getOffsets().back());

	std::shared_ptr<ColumnArray> res = std::make_shared<ColumnArray>(data->cloneEmpty());

	Offsets_t & res_offsets = res->getOffsets();
	res_offsets.resize(limit);
	size_t current_offset = 0;

	for (size_t i = 0; i < limit; ++i)
	{
		for (size_t j = 0; j < sizeAt(perm[i]); ++j)
			nested_perm[current_offset + j] = offsetAt(perm[i]) + j;
		current_offset += sizeAt(perm[i]);
		res_offsets[i] = current_offset;
	}

	if (current_offset != 0)
		res->data = data->permute(nested_perm, current_offset);

	return res;
}
Example #22
0
template <> ColumnPtr ColumnConst<String>::convertToFullColumn() const
{
    if (!data_type || typeid_cast<const DataTypeString *>(&*data_type))
    {
        auto res = std::make_shared<ColumnString>();
        ColumnString::Offsets_t & offsets = res->getOffsets();
        ColumnString::Chars_t & vec = res->getChars();

        size_t string_size = data.size() + 1;
        size_t offset = 0;
        offsets.resize(s);
        vec.resize(s * string_size);

        for (size_t i = 0; i < s; ++i)
        {
            memcpy(&vec[offset], data.data(), string_size);
            offset += string_size;
            offsets[i] = offset;
        }

        return res;
    }
    else if (const DataTypeFixedString * type = typeid_cast<const DataTypeFixedString *>(&*data_type))
    {
        size_t n = type->getN();

        if (data.size() > n)
            throw Exception("Too long value for " + type->getName(), ErrorCodes::TOO_LARGE_STRING_SIZE);

        auto res = std::make_shared<ColumnFixedString>(n);
        ColumnFixedString::Chars_t & vec = res->getChars();

        vec.resize_fill(n * s);
        size_t offset = 0;

        for (size_t i = 0; i < s; ++i)
        {
            memcpy(&vec[offset], data.data(), data.size());
            offset += n;
        }

        return res;
    }
    else
        throw Exception("Invalid data type in ColumnConstString: " + data_type->getName(), ErrorCodes::LOGICAL_ERROR);
}
Example #23
0
StringRef ColumnArray::getDataAt(size_t n) const
{
    /** Returns the range of memory that covers all elements of the array.
      * Works for arrays of fixed length values.
      * For arrays of strings and arrays of arrays, the resulting chunk of memory may not be one-to-one correspondence with the elements,
      *  since it contains only the data laid in succession, but not the offsets.
      */

    size_t offset_of_first_elem = offsetAt(n);
    StringRef first = getData().getDataAtWithTerminatingZero(offset_of_first_elem);

    size_t array_size = sizeAt(n);
    if (array_size == 0)
        return StringRef(first.data, 0);

    size_t offset_of_last_elem = getOffsets()[n] - 1;
    StringRef last = getData().getDataAtWithTerminatingZero(offset_of_last_elem);

    return StringRef(first.data, last.data + last.size - first.data);
}
Example #24
0
void MatrixOpData::finalize()
{
    AutoMutex lock(m_mutex);

    std::ostringstream cacheIDStream;
    cacheIDStream << getID();

    md5_state_t state;
    md5_byte_t digest[16];

    // TODO: array and offset do not require double precison in cache.
    md5_init(&state);
    md5_append(&state,
        (const md5_byte_t *)&(getArray().getValues()[0]),
        (int)(16 * sizeof(double)));
    md5_append(&state,
        (const md5_byte_t *)getOffsets().getValues(),
        (int)(4 * sizeof(double)));
    md5_finish(&state, digest);

    cacheIDStream << GetPrintableHash(digest);
    m_cacheID = cacheIDStream.str();
}
Example #25
0
ColumnPtr ColumnConst<Array>::convertToFullColumn() const
{
    if (!data_type)
        throw Exception("No data type specified for ColumnConstArray", ErrorCodes::LOGICAL_ERROR);

    const DataTypeArray * type = typeid_cast<const DataTypeArray *>(&*data_type);
    if (!type)
        throw Exception("Non-array data type specified for ColumnConstArray", ErrorCodes::LOGICAL_ERROR);

    const Array & array = getDataFromHolderImpl();
    size_t array_size = array.size();

    const auto & nested_type = type->getNestedType();
    ColumnPtr nested_column;

    if (nested_type->isNull())
    {
        /// Special case: an array of Null is actually an array of Nullable(UInt8).
        nested_column = std::make_shared<ColumnNullable>(
            std::make_shared<ColumnUInt8>(), std::make_shared<ColumnUInt8>());
    }
    else
        nested_column = type->getNestedType()->createColumn();

    auto res = std::make_shared<ColumnArray>(nested_column);
    ColumnArray::Offsets_t & offsets = res->getOffsets();

    offsets.resize(s);
    for (size_t i = 0; i < s; ++i)
    {
        offsets[i] = (i + 1) * array_size;
        for (size_t j = 0; j < array_size; ++j)
            nested_column->insert(array[j]);
    }

    return res;
}
Example #26
0
/* turn off any foreground pixel with a background pixel neighbor (8-connected) */
void shrink(unsigned char *mask, unsigned char *shrunk, int rows, int cols) {

  long imagesize, i;
  int j;
  int *offsets;

  imagesize = rows * cols;
  offsets = getOffsets(cols, imagesize);

  for (i=0; i < imagesize; ++i){

    /* don't process the 1 pixel layer around the whole image */
    if (edge(i, cols, imagesize)) shrunk[i] = mask[i]; 

    /* ignore if background */
    else if (mask[i] == BACKGROUND) {
      shrunk[i] = BACKGROUND;
    }
    /* if foreground, apply shrinking algorithm */
    else if (mask[i] == FOREGROUND) {

      shrunk[i] = FOREGROUND;

      /* look at 8 nearest neighbors. If ANY are foreground, turn pixel ON */
      for (j = 0; j < 9; ++j) {
        if( mask[ i + offsets[j]] == BACKGROUND){
          shrunk[i] = BACKGROUND;
          break;
        }
      }
    }
    else {
      printf("Error: Hit a value that's not 0 or 255!\n");
      shrunk[i] = mask[i];
    }
  }
}
Example #27
0
MatrixOpDataRcPtr MatrixOpData::inverse() const
{
    // Get the inverse matrix.
    MatrixArrayPtr invMatrixArray = m_array.inverse();
    // MatrixArray::inverse() will throw for singular matrices.

    // Calculate the inverse offset.
    const Offsets& offsets = getOffsets();
    Offsets invOffsets;
    if (offsets.isNotNull())
    {
        invMatrixArray->inner(offsets, invOffsets);
        invOffsets.scale(-1);
    }

    MatrixOpDataRcPtr invOp = std::make_shared<MatrixOpData>(getOutputBitDepth(), getInputBitDepth());
    invOp->setRGBA(&(invMatrixArray->getValues()[0]));
    invOp->setOffsets(invOffsets);

    // No need to call validate(), the invOp will have proper dimension,
    // bit-depths, matrix and offets values.

    return invOp;
}
Example #28
0
ColumnPtr ColumnArray::replicateConst(const Offsets_t & replicate_offsets) const
{
	size_t col_size = size();
	if (col_size != replicate_offsets.size())
		throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);

	if (0 == col_size)
		return cloneEmpty();

	const Offsets_t & src_offsets = getOffsets();

	auto res_column_offsets = std::make_shared<ColumnOffsets_t>();
	Offsets_t & res_offsets = res_column_offsets->getData();
	res_offsets.reserve(replicate_offsets.back());

	Offset_t prev_replicate_offset = 0;
	Offset_t prev_data_offset = 0;
	Offset_t current_new_offset = 0;

	for (size_t i = 0; i < col_size; ++i)
	{
		size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
		size_t value_size = src_offsets[i] - prev_data_offset;

		for (size_t j = 0; j < size_to_replicate; ++j)
		{
			current_new_offset += value_size;
			res_offsets.push_back(current_new_offset);
		}

		prev_replicate_offset = replicate_offsets[i];
		prev_data_offset = src_offsets[i];
	}

	return std::make_shared<ColumnArray>(getData().cloneResized(current_new_offset), res_column_offsets);
}
	void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
	{
		const ColumnWithTypeAndName & arg_from = block.unsafeGetByPosition(arguments[0]);
		const ColumnWithTypeAndName & arg_charset_from = block.unsafeGetByPosition(arguments[1]);
		const ColumnWithTypeAndName & arg_charset_to = block.unsafeGetByPosition(arguments[2]);
		ColumnWithTypeAndName & res = block.unsafeGetByPosition(result);

		const ColumnConstString * col_charset_from = typeid_cast<const ColumnConstString *>(arg_charset_from.column.get());
		const ColumnConstString * col_charset_to = typeid_cast<const ColumnConstString *>(arg_charset_to.column.get());

		if (!col_charset_from || !col_charset_to)
			throw Exception("2nd and 3rd arguments of function " + getName() + " (source charset and destination charset) must be constant strings.",
				ErrorCodes::ILLEGAL_COLUMN);

		String charset_from = col_charset_from->getData();
		String charset_to = col_charset_to->getData();

		if (const ColumnString * col_from = typeid_cast<const ColumnString *>(arg_from.column.get()))
		{
			auto col_to = std::make_shared<ColumnString>();
			convert(charset_from, charset_to, col_from->getChars(), col_from->getOffsets(), col_to->getChars(), col_to->getOffsets());
			res.column = col_to;
		}
		else if (const ColumnConstString * col_from = typeid_cast<const ColumnConstString *>(arg_from.column.get()))
		{
			auto full_column_holder = col_from->cloneResized(1)->convertToFullColumnIfConst();
			const ColumnString * col_from_full = static_cast<const ColumnString *>(full_column_holder.get());

			auto col_to_full = std::make_shared<ColumnString>();
			convert(charset_from, charset_to, col_from_full->getChars(), col_from_full->getOffsets(), col_to_full->getChars(), col_to_full->getOffsets());

			res.column = std::make_shared<ColumnConstString>(col_from->size(), (*col_to_full)[0].get<String>(), res.type);
		}
		else
			throw Exception("Illegal column passed as first argument of function " + getName() + " (must be ColumnString).",
				ErrorCodes::ILLEGAL_COLUMN);
	}
Example #30
0
MatrixOpDataRcPtr MatrixOpData::compose(ConstMatrixOpDataRcPtr & B) const
{
    if (getOutputBitDepth() != B->getInputBitDepth())
    {
        std::ostringstream oss;
        oss << "Matrix bit-depth missmatch between '";
        oss << getID();
        oss << "' and '";
        oss << B->getID();
        oss << "'. ";

        throw Exception(oss.str().c_str());
    }

    // Ensure that both matrices will have the right dimension (ie. 4x4).
    if (m_array.getLength() != 4 || B->m_array.getLength() != 4)
    {
        // Note: By design, only 4x4 matrices are instantiated.
        // The CLF 3x3 (and 3x4) matrices are automatically converted
        // to 4x4 matrices, and a Matrix Transform only expects 4x4 matrices.
        throw Exception("MatrixOpData: array content issue.");
    }

    Descriptions newDesc = getDescriptions();
    newDesc += B->getDescriptions();
    MatrixOpDataRcPtr out = std::make_shared<MatrixOpData>(
        getInputBitDepth(),
        B->getOutputBitDepth());
    out->setID(getID() + B->getID());
    out->getDescriptions() = newDesc;

    // TODO: May want to revisit how the metadata is set.

    // By definition, A.compose(B) implies that op A precedes op B
    // in the opList. The LUT format coefficients follow matrix math:
    // vec2 = A x vec1 where A is 3x3 and vec is 3x1.
    // So the composite operation in matrix form is vec2 = B x A x vec1.
    // Hence we compute B x A rather than A x B.

    MatrixArrayPtr outPtr = B->m_array.inner(this->m_array);

    out->getArray() = *outPtr.get();

    // Compute matrix B times offsets from A.

    Offsets offs;

    B->m_array.inner(getOffsets(), offs);

    const unsigned long dim = this->m_array.getLength();

    // Determine overall scaling of the offsets prior to any catastrophic
    // cancellation that may occur during the add.
    double val, max_val = 0.;
    for (unsigned long i = 0; i<dim; ++i)
    {
        val = fabs(offs[i]);
        max_val = max_val > val ? max_val : val;
        val = fabs(B->getOffsets()[i]);
        max_val = max_val > val ? max_val : val;
    }

    // Add offsets from B.
    for (unsigned long i = 0; i<dim; ++i)
    {
        offs[i] += B->getOffsets()[i];
    }

    out->setOffsets(offs);

    // To enable use of strict float comparisons above, we adjust the
    // result so that values very near integers become exactly integers.
    out->cleanUp(max_val);

    return out;
}