All pastes #676549 Raw Edit

Unnamed

public cpp v1 · immutable
#676549 ·published 2007-08-31 04:54 UTC
rendered paste body
/** * Simple matrix multiplier with shake * * Authors: *  Gregor Richards * * License: *  Copyright (c) 2007  Gregor Richards * *  Permission is hereby granted, free of charge, to any person obtaining a *  copy of this software and associated documentation files (the "Software"), *  to deal in the Software without restriction, including without limitation *  the rights to use, copy, modify, merge, publish, distribute, sublicense, *  and/or sell copies of the Software, and to permit persons to whom the *  Software is furnished to do so, subject to the following conditions: * *  The above copyright notice and this permission notice shall be included in *  all copies or substantial portions of the Software. * *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *  DEALINGS IN THE SOFTWARE. */module shakematrix;import tango.io.Stdout;import tango.stdc.stdlib;import shake.Actor;import shake.Message;class Matrix {    public:        this(real[] sv, int sw, int sh)        {            v = sv.dup;            while (v.length < sw * sh)                v ~= 0.0;            _w = sw;            _h = sh;        }        /** Get a value out of the matrix */        real opIndex(int x, int  y)        {            assert(x >= 0 && x < w && y >= 0 && y < h);            return v[w*y + x];        }        /** Set a value into the matrix */        void opIndexAssign(real sv, int x, int y)        {            assert(x >= 0 && x < w && y >= 0 && y < h);            v[w*y + x] = sv;        }        /** Accessor */        int w() { return _w; }        /** ditto */        void w(int sw) { _w = sw; }        /** ditto */        int h() { return _h; }        /** ditto */        void h(int sh) { _h = sh; }    private:        real[] v;        int _w, _h;}/** The actor that receives all of the multiplied matrix values */class MatrixMultiplier : Actor {    public:        this (Matrix sl, Matrix sr)        {            assert(sl.w == sr.h);            l = sl;            r = sr;            res = new Matrix([], sr.w, sl.h);            togo = sr.w * sl.h;        }        Matrix l, r, res;        int togo;}/** The message that tells the matrix multiplier to start multiplying matrices */class MatrixMultiply : Message {    public:        void handle(Actor a)        {            auto mm = cast(MatrixMultiplier) a;            assert(mm !is null);            // create five node multipliers            Actor[] nms;            for (int i = 0; i < 5; i++) {                Actor nm = new Actor;                nms ~= nm;                nm.start();            }            // and a delegater to manage them            Delegater d = new Delegater(nms);            // then send messages for each row and column            for (int y = 0; y < mm.res.w; y++) {                for (int x = 0; x < mm.res.h; x++) {                    d.enqueue(new CellMultiply(mm, mm.l, mm.r, x, y));                }            }            d.start();        }}/** The message to generate the value for a cell */class CellMultiply : Message {    public:        this(Actor ssender, Matrix sl, Matrix sr, int sx, int sy)        {            super(ssender);            l = sl;            r = sr;            x = sx;            y = sy;        }        void handle(Actor a)        {            real res = 0;            // go element-by-element            for (int i = 0; i < l.w; i++) {                res += l[i, y] * r[x, i];            }            // now send the message back to the host            sender.enqueue(new CellSet(x, y, res));        }    private:        Matrix l, r;        int x, y;}/** The message to set a cell */class CellSet : Message {    public:        this(int sx, int sy, real sv)        {            x = sx;            y = sy;            v = sv;        }        void handle(Actor a)        {            auto mm = cast(MatrixMultiplier) a;            assert(mm !is null);            // set it            mm.res[x, y] = v;            mm.togo--;            // if we have no more to go, we're done            if (mm.togo == 0) {                synchronized (Stdout) {                    for (int y = 0; y < mm.res.h; y++) {                        for (int x = 0; x < mm.res.w; x++) {                            Stdout(mm.res[x, y])(" ");                        }                        Stdout.newline;                    }                }                exit(0);            }        }    private:        int x, y;        real v;}int main(){    MatrixMultiplier mm = new MatrixMultiplier(            new Matrix(                [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 ], 5, 4),            new Matrix(                [ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ], 4, 5));    mm.start();    mm.enqueueSync(new MatrixMultiply);    return 0;}