Regressão Linear em Socket Programming C++

Oi,alguém me pode ajuda em cria um server com pthreads para uma fonte de dados que envia pares de números inteiros separados por vírgula (xi, yi),não tou conseguindo.

Para ai aplicar uma regressão linear sobre um conjunto de n amostras (uma janela de tempo), e calcula os parâmetros de uma linha em que a equação é Y = aX + b.
Duas janelas consecutivas tem de compartilhar 50% dos dados (a segunda metade da primeira janela corresponde à primeira metade da segunda janela).

Após o cálculo dos parâmetros da linha de regressão, tem que verifica o erro quadrático médio da aproximação.

#include<iostream>

#define S 50

using namespace std;
int main()
{
 int n, i;
 float x[S], y[S], sumX=0, sumX2=0, sumY=0, sumXY=0, a, b;

 /* Input */
 cout<<"How many data points? ";
 cin>>n;

 cout<<"Enter data:"<< endl;

 for(i=1;i<=n;i++)
 {
  cout<<"x["<< i <<"] = ";
  cin>>x[i];
  cout<<"y["<< i <<"] = ";
  cin>>y[i];
 }

 /* Calculating Required Sum */
 for(i=1;i<=n;i++)
 {
  sumX = sumX + x[i];
  sumX2 = sumX2 + x[i]*x[i];
  sumY = sumY + y[i];
  sumXY = sumXY + x[i]*y[i];
 }
 /* Calculating a and b */
 b = (n*sumXY-sumX*sumY)/(n*sumX2-sumX*sumX);
 a = (sumY - b*sumX)/n;

 /* Displaying value of a and b */
 cout<<"Calculated value of a is "<< a << "and b is "<< b << endl;
 cout<<"Equation of best fit is: y = "<< a <<" + "<< b<<"x";

 return(0);
}

O server precisa ser em C++? Ou pode usar alguma outra lib de outra linguagem pra subir?

Não sou especialista em C++ mas creio que você vai precisar definir quais dados serão utilizados por quais threads…

Talvez ajude:

https://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm

Qual o sistema e IDE que você está utilizando?

Sim, o server tem de ser em C++, eu tou utilizando o code blocks para fazer só que nao tou sabendo como adaptar.

E que só tou querendo o server ,porque o cliente eu tenho já

Esse, foi o servidor que estou fazendo mas não tá dando certo :

#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include<math.h>
#include <pthread.h>
#define SIZE 70
#define PORT 65432

void * LinearRegression(void *);
using namespace std;
char buffer[1024] = {0};
char previousBuffer[1024];
int main(int argc, char const *argv[])
{
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char hello[] = "Hello from server";
    static int counter = 0;
    double result = 0;
    pthread_t s;    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }    // Forcefully attaching socket to the port 65432
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                   &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );    // Forcefully attaching socket to the port 65432
    if (bind(server_fd, (struct sockaddr *)&address,
             sizeof(address))<0)
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
                             (socklen_t*)&addrlen))<0)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    while(true)
    {
        valread = read( new_socket, buffer, 1024);
        buffer[valread]=0;
        printf("%s\n",buffer );
        {
            for(int i=0; i<SIZE; i++)
            {
                if(previousBuffer[i] != buffer[i])
                    counter++;
            }
        }
        pthread_create(&s,NULL,&LinearRegression,NULL);
        pthread_join(s,NULL);
        printf(" Linear Regression: %d\n\n*******************************************************************************\n\n",counter);
        counter = 0;
    }
    for ( int i=0; i<SIZE; i++)
        previousBuffer[i] = buffer[i];
}
send(new_socket, hello, strlen(hello), 0 );
printf("Hello message sent\n");
return 0;
}
void * LinearRegression(void * arg)
{
    string string1(buffer);
    string string2(previousBuffer);
    size_t strlen1 = string1.size();
    size_t strlen2 = string2.size();
    size_t length1 = strlen1-1;
    size_t length2 = strlen2;
    double matches = 0;
    float x[S], y[S], sumX=0, sumX2=0, sumY=0, sumXY=0, a, b;
    int i = 0;
    int n = 0;
    double result = 0;
    while (i < length1 && n < length2)
    {
        string a = string1.substr(i, 2);
        string b = string2.substr(j, 2);
        int cmp = a.compare(b);
        if (cmp == 0)
            matches = matches+2;
        ++i;
        ++n;
        /* Calculating a and b */
        b = (n*sumXY-sumX*sumY)/(n*sumX2-sumX*sumX);
        a = (sumY - b*sumX)/n;
        return(0);
    } /* Displaying value of a and b */
    result = matches / (length1 + length2) ;
    cout<<"Calculated value of a is "<< a << "and b is "<< b << endl;
    cout<<"Equation of best fit is: y = "<< a <<" + "<< b<<"x";
    printf(" LinearRegression: %.3f\n", result);
}

Olá @Sofia_c

Só por curiosidade eu copiei e colei o seu código no VSCode e ele me deu o seguinte retorno na parte de saída de erros:

No caso exitem alguns erros de identificadores que não foram definidos ou mesmo ausência de ; (ponto e virgula). Eu acho que em alguns casos está faltando {} (chaves).

Particularmente não consigo corrigir o seu código porque não tenho noção alguma de C/C++, contudo acho que é questão de revisar a declaração de algumas variáveis e ponteiros.

Na linha 78 por exemplo você utiliza um método send(), contudo ele não está sendo definido/importado em lugar algum?

O erro do send() não era a declaração como eu citei a cima, na realidade você tem um loop for que estava sem as chaves, por isso estava dando erro:

Antes:

for ( int i=0; i<SIZE; i++)
        previousBuffer[i] = buffer[i];
}
send(new_socket, hello, strlen(hello), 0 );
printf("Hello message sent\n");
return 0;
}

Depois:

for ( int i=0; i<SIZE; i++)
    {
        previousBuffer[i] = buffer[i];
    }
    send(new_socket, hello, strlen(hello), 0 );
    printf("Hello message sent\n");
    return 0;

Só não sei se o send() deve ficar fora ou fazer parte do loop. Mais no geral você vai precisar revisar o código e analisar os códigos de erro :laughing:.

Olá @ natorsc,
Pois é que eu fiz esse servidor e tentei implementa a regressão linear lá,só que nenhum deles ta funcionando bem, nem de uma forma mais simples com as pthreads

Você esta misturando C com C++, o que não é recomendado (isso é nítido ao perceber que você ta usando iostream do C++ junto do stdio.h do C).

Pois esta bem não tinha visto isso, eu vou fazer tudo de novo, mas uma coisa,por exemplo:

Tenho aqui esse exemplo de servidor,em que lugar tenho de incrementar a parte da regressão linear?

 //regressão linear

    double x[] = {1, 2, 4, 3, 5};
    double y[] = {1, 3, 3, 2, 5};
     
    double b0 = 0;
    double b1 = 0;
    double alpha = 0.01;
     
    for (int i = 0; i < 20; i ++) {
        int idx = i % 5;
        double p = b0 + b1 * x[idx];
        double err = p - y[idx];
        b0 = b0 - alpha * err;
        b1 = b1 - alpha * err * x[idx];
    }

//server

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netdb.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <sys/ioctl.h>

#include <pthread.h>

void * Servidor( void * arg)

{

/*Buffer de entrada (armazena buffer do cliente)*/

char buffer_do_cliente[256];

/*Cast do ponteiro*/

int sockEntrada = *( int *) arg;

/*Loop "infinito"*/

printf ( "Aguardando as mensagens... " );

for (;;)

{

/*Le o que vem do cliente*/

read(sockEntrada, buffer_do_cliente, sizeof (buffer_do_cliente));

if ( strcmp (buffer_do_cliente, "sair" ) != 0)

{

/*Se buffer == sair cai fora*/

printf ( "%s\n" ,buffer_do_cliente);

}

else

{

/*Encerra o descritor*/

close(sockEntrada);

/*Encerra a thread*/

pthread_exit(( void *) 0);

}

}

}

int configuracaoServidor()

{

/*Cria o descritor*/

int sockfd;

/*Declaracao da estrutura*/

struct sockaddr_in serverAddr;

/*Cria o socket*/

if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

{

printf ( "Erro no Socket\n" );

exit (1);

}

/*Zera a estrutura*/

memset (&serverAddr, 0, sizeof (serverAddr));

/*Seta a familia*/

serverAddr.sin_family = AF_INET;

/*Seta os IPS (A constante INADDR_ANY e todos os ips ou qualquer ip) htonl -> conversao*/

serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

/*Define a porta*/

serverAddr.sin_port = htons(6881);

/*Faz a bindagem (cola, gruda, conecta seja o que for)*/

if (bind(sockfd, ( struct sockaddr *) & serverAddr, sizeof (serverAddr)) < 0)

{

printf ( "Erro no Socket\n" );

exit (1);

}

/*Fica na escuta de ate 5 clientes*/

if (listen(sockfd, 5) < 0)

{

printf ( "Erro no Socket\n" );

exit (1);

}

return sockfd;

}

int main()

{

system ( "clear" );

/*Declaracao da estrutura*/

struct sockaddr_in serverAddr;

/*Retorna da funcao e o descritor*/

int sockfd = configuracaoServidor();

/*Loop "infinito"*/

while (1)

{

int clienteSockfd;

struct sockaddr_in clienteAddr;

/*tamanho da estrutura*/

unsigned int clntLen;

clntLen = sizeof (clienteAddr);

/*declara uma thread*/

pthread_t thread ;

/*Fica no aguardo da conexao do cliente*/

if ((clienteSockfd = accept(sockfd, ( struct sockaddr *) & clienteAddr, &clntLen)) < 0)

{

printf ( "Erro no Socket\n" );

exit (1);

}

/*Inicializa a thread*/

if (pthread_create(& thread , NULL, Servidor, &clienteSockfd) != 0)

{

printf ( "Erro na Thread\n" );

exit (1);

}

pthread_detach( thread );

}

exit (0);

}