On Feb 26, 2007, at 12:10 PM, Jarle Brinchmann wrote:
I'm afraid that's not exactly what I'm looking for.  After
re-analyzing the problem and reading chapter 3 of the PDL book, I
realize what I actually need to do is find or write a "primitive" code
that will project a line into a plane, and then let threading take
care of doing that to each line in my image and give me a cube.


Again, sorry to be so late getting into the fray here. It sounds like the problem is to take a sparse collection of (N-1)-dimensional data and interpolate them on to a full N-dimensional data set. For N=2, the data are linear and the data set is an image.

Here's example code to do it in that case -- the more general case is almost as trivial but less clear to read, and is left as an exercise :-)

On input, let the data sets be contained in a list of 1-D PDLS, called @dat. Also, let the transformations to 2-D be defined by a list of 2x2-PDLs (matrices) called @mat and a list of 2-PDL offsets called @of, and let $nx and $ny contain the size of the output array onto which you want to interpolate. Then do this:

        # Assemble 2-D coordinates for each data point in each line
        undef @coords;
        for $i(0..$#dat) {
                $coords = ($mat[$i] x ndcoords($data2)->(*1))->((0)) + $of[i];
                push(@coords,$coords);
        }
        
        # Now make $coords: a 2xM-PDL list of all data point coordinates
        $coords = $coords[0]->glue(1,$coords[1..$#coords]);
        
        # Convert all the data points to a single M-PDL
        $data = $dat[0]->glue(0,$dat[1..$#dat]);

# ocoords gets a 2x($nx)x($ny) array with the coordinates of each pixel in the
        # output array.
        $ocoords = ndcoords($nx,$ny)->clump(1..2);

# odiff gets a 2xMx(nx)x(ny) array with the differences between the coordinates
        # of each pixel in the list and each pixel in the final image.
        $odiff = $coords->(:,:,*1) - $ocoords->(:,*1);

# Take 1/R^2: square the differences, collapse by summation, and take reciprocal
        $fact = 1.0/(($odiff*$odiff)->sumover)

# Now multiply by the data and collapse to (nx)x(ny) by summation, and divide # pixelwise by the summed factors themselves to get the weighted average values.
        $out = ($fact*$data)->sumover / $fact->sumover;

You can of course use a different weighting function by replacing the 1/R^2 with your favorite analytic expression.

The above works great if you can fit several times (nx)x(ny)xM bytes in RAM, but as with all threading tricks it trades memory and CPU cycles for programmer time. For a production run or for large data sets you're better off with a PP solution.

Cheers,
Craig




...
        
I
think I can manage that, but I haven't worked with c much, and I'm not
sure I understand how to use PP completely, but hopefully I'll learn.

Sort of on that note, I was hoping to use the code for, say, diagonal,
or some other similar code, as an example, but I can't find it.
Core.pm and Slices.pm have references to diagonal and diagonalI, but
I'm not sure where to follow those.  Where can I find out about how
the code is structured/where the source is?


Not going to be much help about your actual coding problem - it does sound indeed that you want to use PP for it. As for finding the source, this can sometimes be a bit tricky because the manual pages sometimes lead you astray..

diagonal is a good case in point. When you do help diagonal in the perldl shell you will be told that it is defined in Core.pm. This is in Basic/Core/Core.pm in the PDL source tree. A lot of key functionality is defined there. However the diagonal (and some other routines) are defined as simple wrappers around a different function, namely diagonalI. Here then comes the tricky part.. where is this.

Searching blindly will get you there (something like find . -name '*.pd' -exec grep -i -H 'diagonalI' {}\;) but who wants to do that each time. Anyway, first priority is to find a .pd file because these are the ones that contain the PP definitions you want. And I find that unless I want to do something hairy I tend to only need to look at two files for core functionality: Basic/Primitive/ primitive.pd and Basic/Slices/slices.pd - these define many of the most basic functions and are useful to browse to get some information.

That said, diagonalI is _not_ the function I'd start with if I were you... In fact, it does sound like given your problem that what you really want to do is to look at the routines in Image2D/image2d.pd and ImageND/imagend.pd and get a feel for what you need from these.

                                        Cheers,
                                                Jarle.




_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl



_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl

Reply via email to