Project: Algorithms - Code Sharing
September 05, 2010, 06:52:40 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: Created on 5/23/2009 to share algorithms and code
 
   Home   Help Search Login Register  
Pages: [1] 2
 1 
 on: December 08, 2009, 10:20:26 AM 
Started by al - Last post by Seedhom
Here is a common use of the of this elimination algorithm I used for line intersection in 2D plane.  Note that the hardest part of this is populating the array with the equations coefficients for each line as in Ax + By = C.
Code:
/**********************************************************************
* Function get_intersect_pt2
* IN : 2 lines end points --> Line 1: (l1x1, l1y1) to (l1x2, l1y2)
* Line 2: (l2x1, l2y1) to (l2x2, l2y2)
* OUT : Intersection point (x, y) by reference
*
**********************************************************************/
bool get_intersect_pt2(double l1x1, double l1y1, double l1x2, double l1y2,
 double l2x1, double l2y1, double l2x2, double l2y2,
 double *x, double *y)
{
// First: you need to create the linear equations matrix
matrix Gmat,  // The matrix to be filled by the macro from the 2D array
res;   // The matrix to hold the results returned to us
double tmp[2][3];   // our tmp 2D array with the lines equations in the format:
    // line1: A1x + B1y = C1
    // line2: A2x + B2y = C2
    // filled temp array will be
    // tmp[][] = [A1,B1,C1
    //   A2,B2,C2 ]


tmp[0][0] = l1y2 - l1y1; //A1
tmp[0][1] = l1x1 - l1x2; //B1
tmp[0][2] = tmp[0][0] * l1x1  + tmp[0][1] * l1y1; //C1

tmp[1][0] = l2y2 - l2y1; //A2
tmp[1][1] = l2x1 - l2x2; //B2
tmp[1][2] = tmp[1][0] * l2x1  + tmp[1][1] * l2y1; //C2

// Call the Init Matrix Macro to prime it with the temporary matrix
// and fill in Gmat
INITMATRIX(tmp,Gmat,2,3);

// Reduce it
if(MatGaussReduce(&Gmat,&res))
{
*x = res.m[0][0];
*y = res.m[1][0];
return true;  // True if we find intersection
}
else
{
return false; // Lines are parallel
}

}

----------------------------
Al Sabawi

 2 
 on: November 01, 2009, 07:14:17 PM 
Started by Seedhom - Last post by Seedhom
Once you create a set of functions that you like to reuse in multiple programs, you typically build them into a library.  The norm in Linux now has moved away from Static libraries (*.a) and more towards Shared Libraries (*.so).  Shared libraries can either be linked-in at compile time from a specific location on the system using -l and -L flags or can be loaded dynamically while the program is executing.  There are advantages and disadvantages for each of those 2 cases.  However, without going into depth about this, let me describe a case where dynamic loading of a shared library is most relevant.

Assume I am writing a server with the purpose to serve applications to users.  A typical case is when the user runs a client front-end application from which he makes requests to the server to execute other applications on the server side.  The requested applications has to be available to the server in the form of a loadable objects.  These loadable objects or shared libraries do not have to be predefined to the server before it starts, nor does the server need to know what they do once they are loaded.  All the server needs to know is where these libraries are in its file system and the name of the function the user needs to call.      

The example I am going to show here is not as elaborate as an application server, but it will show the technique fully.

The Shared Library

Start with the shared library I want to create with a trivial code:
Code:
#include <stdio.h>

int main(int argv, char *argc[])
{
printf("Hello World - I am loaded\n");
}
    Let us save this file as a C++ file just for kicks and call it
myloadingtest.cpp
To compile the above code as a shared library, we will do this in 2 steps:

  • (1) Compile using the -fPIC flag :
This will generate a position-independent code (PIC) so the OS dynamic loader can position it as it sees fit. Here is the compile line
[/list]
Code:
g++ -fPIC -c myloadingtest.cpp

  • (2) Generate the shared library from the object we just created:
We will need the -shared flag to tell that to the compiler. I am going to name the lib libmyloadingtest.so.  Here is the line:
Code:
g++ -shared  -o libmyloadingtest.so myloadingtest.o

    Now we have a shared library with only one entry: main(int, char **) in it.

    Now for the loading application (or server)...

    Shared Library Loader:
    Let me jump right away into the code:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <dlfcn.h>

    int main(int argc, char *argv[])
    {
            void *handle;          // Pointer to the library location
            int (*mymain)(void);   // Pointer to point to the function in the lib to execute
            char *error;           // Pointer to the error that maybe returned by the dlerror() call

            // load the shared lib using Run Time Loader lazy mode
            handle = dlopen ("./mydynlibs/libmyloadingtest.so", RTLD_LAZY);
            if (!handle)
            {
                printf("This is an error in loading \n");
                exit(1);
            }
            printf("Library loaded successfully. Finding the function we need ..\n");

            // Resolve the function call ..
            mymain = (int (*)())dlsym(handle, "main");
            if ((error = dlerror()) != NULL)  
            {
                printf("Error: I did NOT find the symbol 'main' \n");
                exit(1);
            }
            printf("Success: Symbol 'main' was found. Calling it now ..\n");
            
                  
            mymain(); // Call the function entry in the library
            
            dlclose(handle);
        }

    Save the above code as file a C++ file dynamic_libload.cpp
    To compile, use this line
    Code:
    g++ -g  dynamic_libload.cpp -o dynamic_libload -ldl

    That is it!!

    Now a couple of points:
    There are only 2 calls needed to load a shared library dynamically:
    Code:
    void *handle = dlopen ("/path/to/lib/mylibname.so", RTLD_LAZY);
    ...
    dlclose(handle);

    And 2 calls are needed for each function symbol you need to point to:
    Code:
    myfunc_ptr = (<type> (*)())dlsym(handle, "function_name");
    // if myfunc_ptr turns NULL, then call
    error = dlerror()

    Another note to make about the option used in dlopen() call:  You can either use RTLD_LAZY or RTLD_NOW.  The first is the LAZY option which allows the loader to bind the library IF and only WHEN a function call is made to one of the library functions. The NOW option forces the loader to bind and resolve all the symbols in the shared library before the dlopen() returns. That could be a waste of time if for some reason the program decides not to call any of its functions.


    - Al Sabawi (Seedhom)
      Nov. 2, 2009

     3 
     on: September 12, 2009, 10:07:37 AM 
    Started by Seedhom - Last post by Seedhom
    This is a peer-to-peer client server code to run on Winodws. It will require a winsock2 lib

    Code:
    /*
    Developer: Al Sabawi -- Vestal NY
    Reqs: Windows VC++ compiler + winsock.lib
    simple threaded server in the internet domain using TCP  
    -- peer-to-peer communication port number is hardcoded to 8808
    -- broadcast and discovery port number is hard coded to 8809
    */
    #include <stdio.h>
    #include <Winsock2.h>
    #include <sys/types.h>
    #include < time.h >
    //#include <sys/socket.h>
    //#include <netinet/in.h>
    #define bzero ZeroMemory

    const int portno=8808;
    const int broadcast_portno = 8809;

    //=======================================================================
    // Function : broadcast_thread
    // in : none
    // return : none
    // Description: To be forked in its own thread to send out a broadcast to the local subnet
    // the current broadcast message is <myhostname:my.ip.address.dotted>
    //
    void broadcast_thread(void)
    {
        unsigned int tbcaddr;       // The broadcast address.
        short port;                 // The port for the broadcast.
        struct sockaddr_in bcLocal; // local socket address for the broadcast.
        struct sockaddr_in bcaddr;  // The broadcast address for the receiver.
        SOCKET bcfd;                // The socket used for the broadcast.
        BOOL one = TRUE;            // Parameter for "setscokopt".
        int pn;                     // The number of the packet broadcasted.
        char buff[1024];            // Buffers the data to be broadcasted.
        char myhostname[100];       // hostname of local machine
        char myhostaddr[100];       // host address of local machine
        char subnetmask[100];       // Subnet mask to broadcast to
        struct in_addr myaddr;      // My host address in net format
        struct hostent* myhostent;
        char * ptr;                 // some transient vars
        int len,i;

        /* get my host name */
        gethostname(myhostname,100);

        myhostent = gethostbyname(myhostname);

        // get only the first host IP address
        sprintf(myhostaddr, "%s\n",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[0]));
        strcpy(subnetmask, myhostaddr);
        ptr = &subnetmask[0];
        len = strlen(ptr);

        // substitute the address with class C subnet mask x.x.x.255
        for(i=len;i>0;i--)
        {
    if(ptr[i] == '.')
    {
    strcpy(&ptr[i+1],"255");
    break;
    }
        }

        // Convert the broadcast address from dot notation to a broadcast address.
        if( (tbcaddr = inet_addr( subnetmask )) == INADDR_NONE )
        {
    printf("Badly formatted BC address: %d\n", WSAGetLastError());
    exit(-1);
        }

        port = htons( broadcast_portno );

        // Create the broadcast socket
        memset( &bcLocal, 0, sizeof( struct sockaddr_in));
        bcLocal.sin_family = AF_INET;
        bcLocal.sin_addr.s_addr = htonl( INADDR_ANY );
        bcLocal.sin_port = htons( 0 );  // We are letting the OS fill in the port number for the local machine.
        bcfd  = socket( AF_INET, SOCK_DGRAM, 0 );

        // If there is an error, report it and  terminate.
        if( bcfd == INVALID_SOCKET  )
    {
    printf("Unable to allocate broadcast socket.: %d\n", WSAGetLastError());
    exit(-1);
        }

        // Mark the socket for broadcast.
        if( setsockopt( bcfd, SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) )
            == SOCKET_ERROR )
    {
    printf("Could not set socket to broadcast.: %d\n", WSAGetLastError());
    exit(-1);
        }

        // Bind the address to the broadcast socket.
        if(bind(bcfd, (struct sockaddr *) &bcLocal, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
    {
    printf("Could not bind address to BC socket.: %d\n", WSAGetLastError());
    exit(-1);
        }

        // Record the broadcast address of the receiver.
        bcaddr.sin_family = AF_INET;
        bcaddr.sin_addr.s_addr = tbcaddr;
        bcaddr.sin_port = port;

        // Send this machine's host name and address in hostname:n.n.n.n format
        for( pn = 1; ; pn++ )
    {
           Sleep( 1000 ); // send out broadcast every 10 seconds
      gethostname(myhostname,100);
      myhostent = gethostbyname(myhostname);
      sprintf(myhostaddr, "%s\n",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[0]));
      sprintf(buff,"%s:%s",myhostname,myhostaddr);

            // Broadcast the packet to the subnet
            if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr
                        , sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
    {
    printf("Sendto error: %d\n", WSAGetLastError());
    exit(-1);
            }
    else
    printf("Broadcasting to %s the message: %s\n",subnetmask,buff);

        }

    }
    //=======================================================================
    // Function : discovery_response_thread
    // in : none
    // return : none
    // Description: To be forked in its own thread to listen and respond to broadcasts from
    // other servers
    //
    void discovery_response_thread(void )
    {
        short port;                 // The port for the broadcast.
        struct sockaddr bcSender; // local socket address for the broadcast.
        struct sockaddr_in bcaddr;  // The broadcast address for the receiver.
        SOCKET bcfd;                // The file descriptor used for the broadcast.
        BOOL one = TRUE;            // Parameter for "setscokopt".
        char buff[10024];            // Buffers the data to be broadcasted.
        int alen;
        int nb;                     // The number of bytes read.

        port = htons( broadcast_portno );

        
        // Prepare to receive the broadcast.
        bcfd = socket(AF_INET, SOCK_DGRAM, 0);
        if( bcfd == INVALID_SOCKET )
    {
    printf("socket failed: %d\n", WSAGetLastError());
    exit(-1);
    }
        // Create the address we are receiving on.
        memset( (char*)&bcaddr, 0, sizeof(bcaddr));
        bcaddr.sin_family = AF_INET;
        bcaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        bcaddr.sin_port = port;
        
        if(bind( bcfd,  (struct sockaddr *)&bcaddr, sizeof(bcaddr) ) == SOCKET_ERROR )
    {
    printf("bind failed: %d\n", WSAGetLastError());
    exit(-1);
    }

        // Keep getting packets forever.
        for( ; ; )
    {
            alen = sizeof(struct sockaddr);
            if( (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) == SOCKET_ERROR  )
    {
    printf("recvfrom failed: %d\n", WSAGetLastError());
    exit(-1);
    }
    printf( "messages received: %s\n", buff );
        }    

    }

    //=======================================================================
    // Function : client_thread
    // in : int socket from the server to communicate with a single client  
    // return : none
    // Description: To be forked in its own thread to exchange TCP packets with a remote client
    // uses non-blocking sock option
    //

    void client_thread( int newsockfd)
    {
    int n;
    char buffer[2048];
    char msg[500];
         unsigned long argp = 1;
    int rcv_ret = 0;
    time_t ltime;

    bzero(buffer,2048);

    n = ioctlsocket(newsockfd,FIONBIO,&argp);
    if (n == SOCKET_ERROR)
    {
    printf("ioctlsocket failed: %d\n", WSAGetLastError());
    exit(-1);
    }

    // receive and send to peer
    while (1)
    {
    rcv_ret = recv(newsockfd, buffer, 2048, 0);

    if (rcv_ret == SOCKET_ERROR)
    {
    if(WSAGetLastError() == WSAEWOULDBLOCK)
    {
    // more data could be coming -- we continue to recv
    continue;
    }
    else
    {
    // recv failed to terminate and exit
    printf("recv failed: %d\n", WSAGetLastError());
    printf("Terminating connection\n");
    break;
    }
    }
    if(rcv_ret == 0) // remote peer closed the socket -- we exit the thread
    {
    printf("Remote peer closed connection -- Exiting\n");
    break;
    }
    else if (rcv_ret > 0) // we got data
    {
    printf("received data = %d\n", rcv_ret);
    printf("Here is the message: %s\n",buffer);
    *buffer = buffer[rcv_ret];
    time(&ltime);
    sprintf(msg,"Hello, My time is %s",ctime( &ltime ));
    n = send(newsockfd,msg,strlen(msg),0);
    if (n < 0)
    {
    printf(" send() error:%d", WSAGetLastError());
    exit(-1);
    }
    continue;
    }
    }

    n = shutdown(newsockfd, 0);
    if (n == SOCKET_ERROR)
    {
    printf("shutdown failed: %d\n", WSAGetLastError());
    closesocket(newsockfd);
    WSACleanup();
    return ;
    }
    else
    printf("closed connection\n");

    return ;
    }
    //=======================================================================
    // Function : server_thread
    // in : int socket from the server to communicate with a single client  
    // return : none
    // Description: To be forked in its own thread to exchange TCP packets with a remote client
    // uses non-blocking sock option
    //

    void server_thread(void)
    {
    int ret;
    int sockfd, newsockfd, clilen;
        struct sockaddr_in serv_addr, cli_addr;
    DWORD ThreadId;

    // create a tcp socket
    // Options :
    // AF_INET  : The Internet Protocol version 4 (IPv4) address family.
    // AF_INET6 : The Internet Protocol version 6 (IPv6) address family.
    // SOCK_STREAM : A socket type that provides sequenced, reliable, two-way,
    //  connection-based byte streams with an OOB data transmission
    //  mechanism. This socket type uses the Transmission Control Protocol (TCP)
    //  for the Internet address family (AF_INET or AF_INET6).
    // SOCK_DGRAM : A socket type that supports datagrams, which are connectionless,
    //  unreliable buffers of a fixed (typically small) maximum length. This
    //  socket type uses the User Datagram Protocol (UDP) for the Internet address
    //  family (AF_INET or AF_INET6).
    // IPPROTO_TCP : The Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type parameter is SOCK_STREAM.
    // IPPROTO_UDP : The User Datagram Protocol (UDP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type parameter is SOCK_DGRAM.
        sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (sockfd == INVALID_SOCKET)
    {
    printf("ERROR opening socket:%d", WSAGetLastError());
    exit(-1);
    }

        bzero((char *) &serv_addr, sizeof(serv_addr));
        //portno = atoi(argv[1]);
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        serv_addr.sin_port = htons(portno);

    ret = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
        if (ret == SOCKET_ERROR)
    {
    printf("ERROR bind() error:%d", WSAGetLastError());
    exit(-1);
    }

    ret = listen(sockfd,5);
    if(ret == SOCKET_ERROR)
    {
            printf("ERROR on listen() error:%d", WSAGetLastError());
    exit(-1);
    }

        clilen = sizeof(cli_addr);

    do
    {
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen);
    if(newsockfd == INVALID_SOCKET)
    {
    printf("ERROR on accept() error:%d", WSAGetLastError());
    exit(-1);
    }

    printf("Got a connection\n");
    CreateThread (
                0, // Security attributes
                0, // Stack size
                (LPTHREAD_START_ROUTINE) &client_thread,
                (LPVOID) newsockfd,
                0,
                &ThreadId);
    }
    while(1);

    }
    //=======================================================================
    // Function : main entry point
    // in : port number for the server to listen on
    // return : int
    // Description: to invoke, c:\server 8808 -> This will make the server listen on port 8808
    //
    //

    int main(int argc, char *argv[])
    {
    //int ret;
    //int sockfd, newsockfd, portno, clilen;
        //struct sockaddr_in serv_addr, cli_addr;
    DWORD ThreadId;
    WORD wVersionRequested;
    WSADATA wsaData;
        int err;

        if (argc < 2)
    {
             fprintf(stderr,"ERROR, no port provided\n");
             exit(1);
        }

    /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
        wVersionRequested = MAKEWORD(2, 2);
        err = WSAStartup(wVersionRequested, &wsaData);

    CreateThread (
                0, // Security attributes
                0, // Stack size
                (LPTHREAD_START_ROUTINE) &discovery_response_thread,
                (LPVOID) NULL,
                0,
                &ThreadId);
    CreateThread (
                0, // Security attributes
                0, // Stack size
                (LPTHREAD_START_ROUTINE) &broadcast_thread,
                (LPVOID) NULL,
                0,
                &ThreadId);
    CreateThread (
                0, // Security attributes
                0, // Stack size
                (LPTHREAD_START_ROUTINE) &server_thread,
                (LPVOID) NULL,
                0,
                &ThreadId);

    Sleep(10000000); // TO DO: add code to interact with user later

    }

     4 
     on: July 05, 2009, 04:32:54 AM 
    Started by al - Last post by al
    Please take 10 seconds to tell us what you think.  Thank you!!

     5 
     on: July 04, 2009, 03:59:02 PM 
    Started by al - Last post by al

    Blue Sky - Perfect Score: http://www.youtube.com/watch?v=ym9kobJDOuI
    Boot Camp : http://www.youtube.com/watch?v=LMo7siERXho

     6 
     on: June 15, 2009, 06:44:51 PM 
    Started by al - Last post by al
    I tried to reduce this to a simple 2 functions for solving a set of linear simultaneous equations in c.  First augment the equations with the results in one ( N X N+1) matrix, then run it through the Gauss-Jordan algorithm to be reduced.  I explained the Gauss Jordan algorithm almost line by line with printing too.  Here is what you need :


    Code:
    #define MAX_ROWS   100  
    #define MAX_COL   100

    //Matrix main struct
    struct matrix
    {
       double m[MAX_ROWS][MAX_COL];
       int r;
       int c;
    };

    // Macros

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // PRINTMATRIXP Macro can be called to print a matrix of type pointer to "struct matrix" to
    // standard output
    //
    // Macro PRINTMATRIXP take the following arguments
    //         1- MAT:   A POINTER Matrix of type struct matrix
    #define PRINTMATRIXP(MAT) {int i,j;for(i=0;i<MAT->r;i++){for(j=0;j<MAT->c;j++){printf("%10.5f\t",MAT->m[j]);}printf("\n");}printf("\n");}
    ////////////////////////////////////////////////////////////////////////////////////////////////


    ////////////////////////////////////////////////////////////////////////////////////////////////
    // PRINTMATRIX Macro can be called to print a matrix of type "struct matrix" to standard output
    //
    // Macro PRINTMATRIX take the following arguments
    //         1- MAT:   A NON-POINTER Matrix of type struct matrix
    #define PRINTMATRIX(MAT) {int i,j;for(i=0;i<MAT.r;i++){for(j=0;j<MAT.c;j++){printf("%10.5f\t",MAT.m[j]);}printf("\n");}printf("\n");}
    ////////////////////////////////////////////////////////////////////////////////////////////////



    ////////////////////////////////////////////////////////////////////////////////////////////////
    // INITMATRIX is a Macro for inititializing and priming a NON-POINTER matrix structure with the
    // your values from a 2 diminsional array you supply
    //
    // Macro INITMATRIX take the following arguments
    //         1-   TMP: A 2 diminsional array matrix with values set
    //         2-   MAT: The matrix you declated in you program (non-pointer)
    //         3-   ROW: The number of rows in the matrix  
    //         4-   COL: The number of columns in the matrix
    #define INITMATRIX(TMP,MAT,ROW,COL) {MAT.r=ROW;MAT.c=COL;COPYARRAY(TMP,MAT);}
    ////////////////////////////////////////////////////////////////////////////////////////////////

    // Called with 2 Matrices and will return a one augmented matrix
    bool MatAugment2Mats(matrix *mat1, matrix *augmat, matrix *res)
    {
       int i=0, j=0, k=0, l=0;

       if(mat1->r!=augmat->r)
          return false;

       // Initialize result matrix
       res->c=mat1->c+augmat->c;
       res->r = mat1->r;
       for(i=0;i<res->r;i++)
          for(j=0;j<res->c;j++)
             res->m[j] = 0;

       for(i=0;i<res->r;i++)
       {
          for(j=0;j<res->c;j++)
          {
             if(j<mat1->c)
                res->m[j] =mat1->m[j];
             else
                res->m[j] =augmat->m[j-mat1->c];

          }
       }
       return true;
    }


    // called with one augmented matrix of equations and results and will reduce them to identity matrix and return the result matrix in NX1
    bool MatGaussReduce(matrix *Amat,  matrix *res)
    {
    int i=0, j=0, k=0;
    int max =0;
    double temp=0.0;

    res->c = 1;
    res->r = Amat->r;
    for (i=0;i<res->r;i++)
                 res->m[i][0] = 0.0;

    cout<<"For each column:"<<endl;

    // for each column
    for (i = 0; i < Amat->r; ++i)
    {
    // find the pivot element; look for the largest element
    // and move up the reduction triangle
    max = i; // assume it is the current row
    for (j = i + 1; j < Amat->r; ++j) // scan the rows below for a larger element
    if (Amat->m[j][i] > Amat->m[max][i]) // if found get the element row 'max'
    max = j;

    cout<<"column "<<i+1<<" Pivot = "<<Amat->m[max][i]<<endl;

    // Reorder the matrix so the pivot is at the diagonal
    for (j = 0; j < Amat->r + 1; ++j)
    {
    temp = Amat->m[max][j];
    Amat->m[max][j] = Amat->m[i][j];
    Amat->m[i][j] = temp;

    }
    cout<<"After reordering  .."<<endl;
    PRINTMATRIXP(Amat);

    cout<<"For each column "<<endl;
    for (j = Amat->r; j >= i; --j)
    {
    cout<<"For column "<<j+1<<endl;
    for (k = i + 1; k < Amat->r; ++k)
    {
    cout<<"Substract "<< Amat->m[k][i]/Amat->m[i][i] * Amat->m[i][j]<<" from row "<<k+1<<" column "<<j+1<<endl;
    Amat->m[k][j] -= Amat->m[k][i]/Amat->m[i][i] * Amat->m[i][j];
    PRINTMATRIXP(Amat);

    }
    cout <<"Now we have "<<endl;
    PRINTMATRIXP(Amat);
    }

    }

    // check that the bottom factor is not Zero (approximate to 0.00001), if it is, then we have no solution
    if((Amat->m[Amat->r-1][Amat->c-2] <0.00001) && (Amat->m[Amat->r-1][Amat->c-2] >-0.00001))
    return false; // there is NO solution, return false

    cout <<"Now back substitution from the bottom "<<endl;
    for (i = Amat->r - 1; i >= 0; --i)
    {

    Amat->m[i][Amat->r] = Amat->m[i][Amat->r] / Amat->m[i][i];
    Amat->m[i][i] = 1;

    for (j = i - 1; j >= 0; --j)
    {

    Amat->m[j][Amat->r] -= Amat->m[j][i] * Amat->m[i][Amat->r];
    Amat->m[j][i] = 0;

    }
    cout<<"For row "<<i+1<<endl;
    PRINTMATRIXP(Amat);
    }

    // copy the last column in the augmented matrix to the result matrix
    for (i=0;i<res->r;i++)
    res->m[i][0] = Amat->m[i][Amat->r];

    return true;
    }


    int main()
    {
       matrix   res, res2,Gmat, Gaug;

       //--------------------------------------------------------------------------------------------------
       // GAUSS Elimination
       // You can either create 2 matrices and augment them then solve the augmented
       // matrix as in the example below **OR** build a matrix already augmented with the results (not shown)
       // First: you need to create the linear equations matrix
       double tmp4[][3]=
       {   {1,1,2},
          {-1,-2,3},
          {3,-7,4}
       };
       // Second: Call the Init Matrix Macro to prime it with the temporary matrix
       INITMATRIX(tmp4,Gmat,3,3);

       // Create the result matrix
       double tmp5[][1]=
       {   {8},
          {1},
          {10}
       };
       INITMATRIX(tmp5,Gaug,3,1);

       // Augment the 2 matrices into 1 using the MatAugment2Mats() function
       if(!MatAugment2Mats(&Gmat, &Gaug, &res))
       {
          printf("Error: The 2 matrices cannot be augmented due to row numbers mismatch!! \n");
       }
       else
       {
          // Print the full aumented matrix before the elimination call
          printf("Gauss Elimination:: Printing ORIGINAL Matrix (%dX%d)\n",res.r,res.c);
          printf("Original set of equations:\n");
          PRINTMATRIX(res);  

          // if there is a solution find it and print it
          if(MatGaussReduce(&res,&res2))
          {
             printf("Gauss Elimination:: Printing RESULT Matrix (%dX%d)\n",res.r,res.c);
             PRINTMATRIX(res);  
          }
          else
          {
             // MatGaussReduce() can return a false if there is inconsistencies OR the set of equations
             // cannot be solved (has infinate solutions/indeterministic )
             printf("Error: Either bad matrix or the matrix is indeterministic!! \n");
             printf("Reduced Matrix:\n");
             PRINTMATRIX(res);
          }
       }



    }

     7 
     on: June 15, 2009, 08:51:45 AM 
    Started by Seedhom - Last post by Seedhom
    I just posted Beta 5 today (June 15/2009) on alsabawi.com with bug fixes and the completion of the endings. Also try the "SUICIDAL BRIDGE" using the hard option. I think you will like it.  I can make it harder if I get comments it is not hard enough!!  Smiley

     8 
     on: June 08, 2009, 04:14:02 PM 
    Started by al - Last post by al

    simple rotate a line around sx1,sy1, the other end moves theta in rad.

    Code:

    void RotateLine(double sx1, double sy1,double delta_x1, double delta_y1, double theta)
    {
    double delta_x2, delta_y2;
           double  new_x2,new_y2;

        delta_x2=(delta_x1*cos(theta))-(delta_y1* sin(theta));
        delta_y2=(delta_x1*sin(theta))+(delta_y1* cos(theta));

       // the rotated end
        new_x2 = sx1+delta_x2;
        new_y2 = sy1-delta_y2;
       

    }




     9 
     on: June 08, 2009, 01:44:34 PM 
    Started by al - Last post by al
    This function uses SDL_Draw library to draw a line directly to screen surface -- you need that only for the Draw_Line(screen,x11,y11,x22,y22,color); at the end (which I commented out) -- but this is an implementation of  Liang-Barsky algorithm for line clipping with in a box/window.  You need to define SCREEN_WIDTH and SCREEN_HEIGHT to match the rectangle of the window that will clip the line at the edges. The 4 corners of the window are wxmin, wymin , wxmax , wymax.  OR you can pass the clipping borders in as a rectangle.



    Code:
    // void sDrawLine(int x1, int y1, int x2, int y2, Uint32 color )
    // Draw a clipped line in within a box
    // Line Cliping using Liang-Barsky algorithm
    // IN : start and end of line from x1,y1 to x2,y2
    //      32bit color
    //****************************************************************

    void sDrawLine(int x1, int y1, int x2, int y2, Uint32 color )
    {
    // using Liang-Barsky line clipping algorithm
    int i;
    int wxmin =1, wymin=1 , wxmax=SCREEN_WIDTH-1 , wymax = SCREEN_HEIGHT-1;
    float u1 = 0.0  , u2 = 1.0 ;

    int  p1 , q1 , p2 , q2 , p3 , q3 , p4 ,q4 ;
    float r1 , r2 , r3 , r4 ;
    int x11 , y11 , x22 , y22 ;

    for(i=-2;i<2;i++)
    {
    p1 = -(x2 - x1 ); q1 = x1 - wxmin ;
    p2 = ( x2 - x1 ) ; q2 = wxmax - x1 ;
    p3 = - ( y2 - y1 ) ; q3 = y1 - wymin ;
    p4 = ( y2 - y1  ) ; q4 = wymax - y1 ;
    if( ( ( p1 == 0.0 ) && ( q1 < 0.0 ) ) ||
    ( ( p2 == 0.0 ) && ( q2 < 0.0 ) ) ||
    ( ( p3 == 0.0 ) && ( q3 < 0.0 ) ) ||
    ( ( p4 == 0.0 ) && ( q4 < 0.0 ) ) )
        {
      //Line is rejected Do nothing

        }
    else
    {
    if( p1 != 0.0 )
    {
    r1 =(float) q1 /p1 ;
    if( p1 < 0 )
    u1 = max(r1 , u1 );
    else
    u2 = min(r1 , u2 );
    }
    if( p2 != 0.0 )
    {
    r2 = (float ) q2 /p2 ;
    if( p2 < 0 )
    u1 = max(r2 , u1 );
    else
    u2 = min(r2 , u2 );

    }
    if( p3 != 0.0 )
    {
    r3 = (float )q3 /p3 ;
    if( p3 < 0 )
    u1 = max(r3 , u1 );
    else
    u2 = min(r3 , u2 );
    }
    if( p4 != 0.0 )
    {
    r4 = (float )q4 /p4 ;
    if( p4 < 0 )
    u1 = max(r4 , u1 );
    else
    u2 = min(r4 , u2 );
    }

    if( u1 > u2 )
    {
    //printf("line rejected\n");
    }
    else
    {
    x11 = x1 + u1 * ( x2 - x1 ) ;
    y11 = y1 + u1 * ( y2 - y1 ) ;

    x22 = x1 + u2 * ( x2  - x1 );
    y22 = y1 + u2 * ( y2 - y1 );

    //Draw_Line(screen,x11,y11,x22,y22,color);
    }
    }
    x1=x1+i; y1=y1+i; x2=x2+i; y2=y2+i;
    }
    }

     10 
     on: June 08, 2009, 01:18:17 PM 
    Started by al - Last post by al
    A useful very simple function if you don't want to mess with rotation matrices.  Make sure to convert angle to Rad from degrees if that is what you are using.

    Code:
    //**************************************************************
    // Rotate a line around a center point by an angle theta
    // IN: ref Array of 4 doubles for (x1,y1) to (x2,y2) line
    //    center point (cx,cy)
    //    Rotation angle theta in Rad
    //    pass in 32bit color if you want to add a draw line call
    //***************************************************************************
    void RotateLine2 (double center[2], double (&line)[4],double theta, Uint32 color)
    {
    double length = 0.0;
    double cx_x1,cy_y1,cx_x2,cy_y2;

    cx_x1 = line[0] - center[0];
    cy_y1 = line[1] - center[1];
    cx_x2 = line[2] - center[0];
    cy_y2 = line[3] - center[1];

        line[0]= center[0] - ((int)(cx_x1*cos(theta)))-((int)(cy_y1* sin(theta)));
        line[1]= center[1] - ((int)(cx_x1*sin(theta)))+((int)(cy_y1* cos(theta)));

        line[2]= center[0] - ((int)(cx_x2*cos(theta)))-((int)(cy_y2* sin(theta)));
        line[3]= center[1] - ((int)(cx_x2*sin(theta)))+((int)(cy_y2* cos(theta)));
    }

    Pages: [1] 2
    Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!