# NAME

PDL::CCS::Functions - Useful perl-level functions for PDL::CCS

# SYNOPSIS

```
use PDL;
use PDL::CCS::Functions;
##---------------------------------------------------------------------
## ... stuff happens
```

# Decoding

## ccs_pointerlen

` Signature: (indx ptr(N+1); indx [o]len(N))`

Get number of non-missing values for each axis value from a CCS-encoded offset pointer vector $ptr().

## ccs_decode

` Signature: (indx whichnd(Ndims,Nnz); nzvals(Nnz); missing(); \@Dims; [o]a(@Dims))`

Decode a CCS-encoded matrix (no dataflow).

# Scalar Operations

Scalar operations can be performed in parallel directly on `$nzvals`

(and if applicable on `$missing`

as well):

```
$c = 42;
$nzvals2 = $nzvals + $c; $missing2 = $missing + $c;
$nzvals2 = $nzvals - $c; $missing2 = $missing - $c;
$nzvals2 = $nzvals * $c; $missing2 = $missing * $c;
$nzvals2 = $nzvals / $c; $missing2 = $missing / $c;
$nzvals2 = $nzvals ** $c; $missing2 = $missing ** $c;
$nzvals2 = log($nzvals); $missing2 = log($missing);
$nzvals2 = exp($nzvals); $missing2 = exp(missing);
$nzvals2 = $nzvals->and2($c,0); $missing2 = $missing->and($c,0);
$nzvals2 = $nzvals->or2($c,0); $missing2 = $missing->or2($c,0);
$nzvals2 = $nzvals->not(); $missing2 = $missing->not();
```

Nothing prevents scalar operations from producing new "missing" values (e.g. $nzvals*0), so you might want to re-encode your compressed data after applying the operation.

# Vector Operations

## ccs_OP_vector_mia

` Signature: (indx whichDimV(Nnz); nzvals(Nnz); vec(V); [o]nzvals_out(Nnz))`

A number of row- and column-vector operations may be performed directly on encoded Nd-PDLs, without the need for decoding to a (potentially huge) dense temporary. These operations assume that "missing" values are annihilators with respect to the operation in question, i.e. that it holds for all `$x`

in `$vec`

that:

` ($missing __OP__ $x) == $missing`

This is in line with the usual PDL semantics if your `$missing`

value is `BAD`

, but may produce unexpected results when e.g. adding a vector to a sparse PDL with `$missing`

==0. If you really need to do something like the latter, then you're probably better off decoding to a dense PDL anyway.

Predefined function names for encoded-PDL vector operations are all of the form: `ccs_${OPNAME}_ma`

, where ${OPNAME} is the base name of the operation:

```
plus ##-- addition
minus ##-- subtraction
mult ##-- multiplication (NOT matrix-multiplication)
divide ##-- division
modulo ##-- modulo
power ##-- potentiation
gt ##-- greater-than
ge ##-- greater-than-or-equal
lt ##-- less-than
le ##-- less-than-or-equal
eq ##-- equality
ne ##-- inequality
spaceship ##-- 3-way comparison
and2 ##-- binary AND
or2 ##-- binary OR
xor ##-- binary XOR
shiftleft ##-- left-shift
shiftright ##-- right-shift
```

## \&CODE = ccs_binop_vector_mia($opName, \&PDLCODE);

Returns a generic vector-operation subroutine which reports errors as `$opName`

and uses \&PDLCODE to perform underlying computation.

# Sorting

## ccs_qsort

` Signature: (indx which(Ndims,Nnz); nzvals(Nnz); missing(); Dim0(); indx [o]nzix(Nnz); indx [o]nzenum(Nnz))`

Underlying guts for PDL::CCS::Nd::qsort() and PDL::CCS::Nd::qsorti(). Given a set of $Nnz items $i each associated with a vector-key `$which(:,$i)`

and a value `$nzvals($i)`

, returns a vector of $Nnz item indices `$nzix()`

such that `$which(:,$nzix)`

is vector-sorted in ascending order and `$nzvals(:,$nzix)`

are sorted in ascending order for each unique key-vector in `$which()`

, and an enumeration `$nzenum()`

of items for each unique key-vector in terms of the sorted data: `$nzenum($j)`

is the logical position of the item `$nzix($j)`

.

If `$missing`

and `$Dim0`

are defined, items `$i=$nzix($j)`

with values `$nzvals($i) > $missing`

will be logically enumerated at the end of the range [0,$Dim0-1] and there will be a gap between `$nzenum()`

values for a `$which()`

-key with fewer than $Dim0 instances; otherwise $nzenum() values will be enumerated in ascending order starting from 0.

For an unsorted index+value dataset `($which0,$nzvals0)`

with

` ($nzix,$nzenum) = ccs_qsort($which0("1:-1,"),$nzvals0,$missing,$which0("0,")->max+1)`

qsort() can be implemented as:

```
$which = $nzenum("*1,")->glue(0,$which0("1:-1,")->dice_axis(1,$nzix));
$nzvals = $nzvals0->index($nzix);
```

and qsorti() as:

```
$which = $nzenum("*1,")->glue(0,$which0("1:-1,")->dice_axis(1,$nzix));
$nzvals = $which0("(0),")->index($nzix);
```

# ACKNOWLEDGEMENTS

Perl by Larry Wall.

PDL by Karl Glazebrook, Tuomas J. Lukka, Christian Soeller, and others.

# AUTHOR

Bryan Jurish <moocow@cpan.org>

## Copyright Policy

Copyright (C) 2007-2013, Bryan Jurish. All rights reserved.

This package is free software, and entirely without warranty. You may redistribute it and/or modify it under the same terms as Perl itself.

# SEE ALSO

perl(1), PDL(3perl), PDL::CCS::Nd(3perl),