in reply to perl bit matrix transposition / weak typing problem

Umm, transpose() doesn't return anything. Adding a return pack("C*",@out) makes it do what you want. If it doesn't for you, could you say what perl version you are using? And exactly what you are seeing? "Cries foul" isn't descriptive enough.

Update: another way:

sub transpose { return if length $_[0] < $BUFSIZE; pack"B*",join"",(split//,unpack"B*",substr$_[0],0,$BUFSIZE)[map$_% +$BUFSIZE*$BUFSIZE+int($_/$BUFSIZE),0..$BUFSIZE**2-1] }
Just as background, in case it helps with your problem, note that perl's bitops have two different modes, numeric (where the scalar operands are numbers) and bitwise, where the operands are strings and the operation is done on each bit of each character. The numeric mode is triggered whenever either of the operands was set to a number or has been used in a numeric context. For example, 3|8 is 11, but "3"|"8" is ";". You can force one or the other regardless of where a scalar's been by replacing one of the operands, say $x, with (0+$x) to force numeric mode, or stringize both, so $x^$y becomes "$x"^"$y", to force bitwise mode. See perlop for more info.

Replies are listed 'Best First'.
Re^2: perl bit matrix transposition / weak typing problem
by infi (Acolyte) on Dec 13, 2004 at 12:29 UTC

    Yes, my mistake on the transpose function with no return value. I have updated it correctly. I had trimmed it down to avoid warlording and posting a million lines of irrelevant code, and inadvertently chopped the return line as well :)

    Anyway, the pack/unpack method above converts to a bitstring, then back again, does it not? Using a sequence of ascii '1's and '0's was precisely what I was trying to avoid... and I *know* perl can accomplish this task in that way. But, that method increases the memory requirements of the implementation eight-fold, adds internal conversion overhead, and doesn't fall into the design requirements of the original question :>

    I hope this isn't misconstrued, but remember, this function has to transpose *every* $BUFSIZE bytes, and quickly, with low memory requirements, to be able to sit at the position in the protocol stack that it does.

    Thanks,
    Jason

      I'm not sure what you are saying; does your original example work for you but is not fast enough?

      I see you have return $out now, but I don't see you setting $out.

      Update: I reread your original post and now see where you talk about trying to avoid the very kind of approach you present there. But I don't see where the trampling you describe comes into it. Do see BrowserUk's suggestion of using vec, which is perl's builtin way of dealing with data by bits without conversion.

        Well, $out is getting set by:

        for my $col (0..($BUFSIZE-1)) { $out[$newrow] |= (1 << $col) if ($in[7 - $col] >> $row & 1); } $newrow++;

        This is setting the actual bit in $out[$newrow] if the corresponding bit from the transposition source matrix is set.

        At any rate, BrowserUk's solution appears to be ideal and small, and exactly fits the requirements; the lack of thorough awareness of the vec() function made this difficult at best. In addition, it makes possible arbitrary matrix sizes, which solved another challenge I had thought of but didn't mention in the original post.

        Thanks,
        Jason