PDL

 view release on metacpan or  search on metacpan

lib/PDL/Core/pdlcore.c  view on Meta::CPAN

      } else if ( (PDL_Indx)SvIV(*svp) == 0) {
        sv_setiv(*svp, (IV)1);
      }
    }
  }

  return depth;
}

/* helper function used in pdl_from_array */
static pdl_datatypes _detect_datatype(AV *av) {
  SV **item;
  AV *array;
  PDL_Indx count, i;
  if (!av) return PDL_D;
  count = av_len(av);
  for (i = 0; i < count; i++) {
    item = av_fetch(av, i, 0);
    if (*item) {
      if (SvROK(*item)) {
        array = (AV*)SvRV(*item);
        if (_detect_datatype(array) == PDL_D) {
          return PDL_D;
        }
      }
      if (SvOK(*item) && !SvIOK(*item)) {
        return PDL_D;
      }
    }
  }
#if IVSIZE == 8
  return PDL_LL;
#else
  return PDL_L;
#endif
}

/**********************************************************************
 * pdl_from_array - dispatcher gets called only by pdl_avref (defined in
 * Core.xs) - it breaks out to pdl_setav_<type>, below, based on the
 * type of the destination PDL.
 */
pdl* pdl_from_array(AV* av, AV* dims, pdl_datatypes dtype, pdl* dest_pdl)
{
  PDL_Indx ndims, i, level=0;
  PDL_Anyval undefval = { PDL_INVALID, {0} };
  ndims = av_len(dims)+1;
  PDL_Indx dest_dims[ndims];
  for (i=0; i<ndims; i++) {
     dest_dims[i] = SvIV(*(av_fetch(dims, ndims-1-i, 0))); /* reverse order */
  }
  if (dest_pdl == NULL)
     dest_pdl = pdl_pdlnew();
  if (!dest_pdl) return dest_pdl;
  pdl_error err = pdl_setdims (dest_pdl, dest_dims, ndims);
  if (err.error) return NULL;
  if (dtype == -1) {
    dtype = _detect_datatype(av);
  }
  dest_pdl->datatype = dtype;
  err = pdl_allocdata (dest_pdl);
  if (err.error) return NULL;
  err = pdl_make_physical(dest_pdl);
  if (err.error) return NULL;
  /******
   * Copy the undefval to fill empty spots in the ndarray...
   */
  PDLDEBUG_f(printf("pdl_from_array type: %d\n", dtype));
  ANYVAL_FROM_SV(undefval, NULL, TRUE, dtype, FALSE);
#define X(dtype_dest, ctype_dest, ppsym_dest, ...) \
    pdl_setav_ ## ppsym_dest(dest_pdl->data,av,dest_dims,ndims,level, undefval.value.ppsym_dest, dest_pdl);
  PDL_GENERICSWITCH(PDL_TYPELIST_ALL, dtype, X, return NULL)
#undef X
  if (dest_pdl->has_badvalue && dest_pdl->badvalue.type != dtype)
    barf("Badvalue has type=%d != pdltype=%d", dest_pdl->badvalue.type, dtype);
  return dest_pdl;
}

/* Compute offset of (x,y,z,...) position in row-major list */
PDL_Indx pdl_get_offset(PDL_Indx* pos, PDL_Indx* dims, PDL_Indx *incs, PDL_Indx offset, PDL_Indx ndims) {
   PDL_Indx i;
   PDL_Indx result;
   for (i=0; i<ndims; i++) { /* Check */
      if (pos[i]<-dims[i] || pos[i]>=dims[i])
         return -1;
   }
   result = offset;
   for (i=0; i<ndims; i++) {
       result += (pos[i]+((pos[i]<0)?dims[i]:0))*incs[i];
   }
   return result;
}

/*CORE21 unused*/
PDL_Anyval pdl_at0( pdl* it ) {
  PDL_Anyval result = { PDL_INVALID, {0} };
  if (it->nvals != 1) { return result; }
  ANYVAL_FROM_CTYPE_OFFSET(result, it->datatype, PDL_REPRP(it), PDL_REPROFFS(it));
  return result;
}

/*CORE21 unused*/
PDL_Anyval pdl_at( void* x, pdl_datatypes datatype, PDL_Indx* pos, PDL_Indx* dims,
	PDL_Indx* incs, PDL_Indx offset, PDL_Indx ndims) {
  PDL_Anyval result = { PDL_INVALID, {0} };
  PDL_Indx ioff = pdl_get_offset(pos, dims, incs, offset, ndims);
  if (ioff < 0) return result;
  ANYVAL_FROM_CTYPE_OFFSET(result, datatype, x, ioff);
  return result;
}

/* Set value at position (x,y,z...) */
pdl_error pdl_set( void* x, pdl_datatypes datatype, PDL_Indx* pos, PDL_Indx* dims, PDL_Indx* incs, PDL_Indx offs, PDL_Indx ndims, PDL_Anyval value) {
  pdl_error PDL_err = {0, NULL, 0};
  PDL_Indx ioff = pdl_get_offset(pos, dims, incs, offs, ndims);
  if (ioff < 0)
    return pdl_make_error_simple(PDL_EUSERERROR, "Position out of range");
  PDL_Anyval typedval;
  ANYVAL_TO_ANYVAL_NEWTYPE(value, typedval, datatype);
  if (typedval.type < 0)
    return pdl_make_error_simple(PDL_EUSERERROR, "Error making typedval");



( run in 1.513 second using v1.01-cache-2.11-cpan-39bf76dae61 )