good chemistry is complicated,
and a little bit messy -LW
RE: Matrix Multiplierby BlaisePascal (Monk)
|on Sep 10, 2000 at 08:49 UTC ( #31784=note: print w/replies, xml )||Need Help??|
Y'know, until now, I never noticed that "d/l code" anchor right below the "comment on this" anchor. The things you learn every day...
Suggestions subroutine by subroutine...
getmatrix: Pre-defining $input to 1 to prime the while, then checking for valid input at the bottom after you have read it is a little hard to understand. You could accomplish the same thing by making the read from <STDIN> as part of the while, with <while ($input = <STDIN>). That would allow you to eliminate the $input &&... at the end as well.
Going one step further, every use of $input at that point is in locations that default to $_, so you can eliminate it all together. I'd recommend, for clarity sake, also renaming @input to @matrix, since that's what it is.
checkmatrix: This is short enough that there really isn't much to suggest for improvement. The one thing I would suggest, though is moving the $rowlength assignment out of the loop. First, for clarity, second for efficiency. That and get rid of @row, it's unnecessary.
And I just noticed... ne is for string comparison, not numeric. Since you are dealing with numbers, use !=.
As a matter of style, I'd have this return some boolean value rather than simply up and dying. It allows the caller to decide what to do with a broken matrix.
printmatrix: If that's how you want to format matrices, good enough for me. Not much to criticize here. (This included for completeness).
getdimen: This is really not clear what you are doing. Obviously, you wanted to get the number of rows and columns, but it seems a round-about way to get them. Especially the for loop with an unguarded last, meaning the loop will execute only once. Not clear at all. I'll do a total rewrite:
getproduct: This is the heart of your routine. The major thing I'll mention here is that you can do something like $product[$i][$j] += $a[$i][$k]*$b[$k][$j]; directly, and perl will DWIM correctly. You don't even need to pre-initialize @product. Using that would make your matrix multiply much simpler to understand. This also eliminates most of your "temp" variables.
The other thing I'd do is make product responsible for validating it's arguments and extracting the info it needs directly, rather than expect it to be called in.
Now, if I got the multiplication wrong, it's easy to see what my mistake was (I haven't done linear algebra in a while, I might have the rows/columns mixed up, for instance).
Perl is very good at having the features that DWIM when you need them to. Trying to go overboard with pushes, temp arrays, etc are not necessarily the way to go. As a general rule, I'd say that if you have to force it to do what you want, there might be an easier way...
Hope this helps...
In Section Code Catacombs