高斯消元并发(未完成

想法:想在找到最大元后,开启并发多个线程(机器)一起消去下面的行(变成上三角行列式)

结果运行调用,从main那里调用,并不是局部调用、、、

残缺的代码:

#include "stdio.h"
#include "math.h"
#include "mpi.h"
#include "stdlib.h"

float *gauss(float *arr, int row, int col);
float *solution(float *arr, int row, int col, int argc, char *argv[]);
float *backProgram(float *arr, int row, int col);
float *elimination(float *arr, int row, int col, int i, int argc, char *argv[]);
int SelectIndex(float *arr, int row, int col, int i);
float *swapRow(float *arr, int row, int col, int i, int j);

void printArr(float *arr)
{
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 5; j++)
        {
            printf("%f ", arr[i * 5 + j]);
        }
        printf("\n");
    }

}


// 高斯消元函数
float *gauss(float *arr, int row, int col)
{
    //float *result = solution(arr, row, col);
    
   // return result;
}

// row 为行数, col为列数,
float *solution(float *arr, int row, int col, int argc, char *argv[])
{
    for(int i = 0; i < row; i++)
    {
//        printf("变化前来一下\n");
//          printArr(arr);        

        int maxRow = SelectIndex(arr, row, col, i);

        if(maxRow != i)
        {
            swapRow(arr, row, col, i, maxRow);
        }

        float divNum = arr[i * col + i];
        for(int k = i; k < col; k++)
        {
            arr[i * col + k] /= divNum;
        }
        
//        printf("变化后来一下\n");
//        printArr(arr);

        arr = elimination(arr, row, col, i, argc, argv); // 这里是消去下面的行,我在这里弄一下并发执行
    }

    backProgram(arr, row, col);

    return arr;
}


// 回代、求值
float *backProgram(float *arr, int row, int col)
{
    for(int i = row - 1; i>= 0; i--)
    {
        for(int j = i - 1; j >= 0; j--)
        {
            arr[j * col + col - 1] -= arr[j * col + i] * arr[i * col + col - 1];
            arr[j * col + i] = 0;
        }
    }

    return arr;
}


//消去当前行下面的所有元素
float *elimination(float *arr, int row, int col, int i, int argc, char *argv[])
{     
    // 在这里尝试添加 并发语句
    int numprocess;
    int myid;
    MPI_Status status;
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocess);

    if(myid == 0) // 0号当做是调度者的身份,让其他的线程(机器)去执行
    {
        printf("你们去执行吧,我把任务交给你们\n");
        
       // float *arrTmp;
        float *arrTmp = (float *)malloc(sizeof(float) * col * row); // 临时数组用于存储 回传的信息
        for(int i = 1; i < col - i - 1; i++)
        {
            printf("我将发送数据到%d --> %d线程\n", myid, i);
            printArr(arr);
            // 把所有的数据都发送过去, 让他们去处理
            MPI_Send(&arr, row * col, MPI_FLOAT, i, 80, MPI_COMM_WORLD); 
        }
        
        // 线程循环,
        for(int kk = 1; kk < row - i + 1; kk++)
        {
            printf("我从 %d线程接收数据,我是%d\n", kk, myid);
            MPI_Recv(&arrTmp, row * col, MPI_FLOAT, kk, 80, MPI_COMM_WORLD, &status);
           
            printf("我是线程%d, 我从%d 接收到的数据是:\n", myid, kk);
            printArr(arrTmp);
             
            // 把 列元素更新
            for(int k = i; k < col; k++)
            {
                arr[row - kk + 1 + k] = arrTmp[row - kk + 1 + k];
            }
        }
        
        printf("结束了,能走到这一步吗?\n");
    }
    else
    {
       // float *recArr;
        float *recArr =(float *)malloc(sizeof(float) * row * col); // 用于接收的数组,在这个数组里面修改,然后回传
        
        printf("我的id:%d,我要开始接收数据了\n", myid);
        MPI_Recv(&recArr, row * col, MPI_FLOAT, 0, 80, MPI_COMM_WORLD, &status);    
        
        printf("我线程%d, 接收到的数据是:\n", myid);
        printArr(recArr);

        float subNum;
        int k = row - myid + 1; 
        subNum = recArr[k * col + i];
        for(int kk = i; kk < col; kk++) // 这一行中 列的处理
        {
            recArr[k * col + kk] -= (recArr[i * col + kk] * subNum);
        }
        printf("数据处理完毕,我是线程%d, 返还数据回去\n", myid);
        printArr(recArr);
        MPI_Send(&recArr, row * col, MPI_FLOAT, 0, 80, MPI_COMM_WORLD);

    }
 
    return arr;
}


// 求最大行
int SelectIndex(float *arr, int row, int col, int i)
{
    int index = 0;
    float max = 0;
    for(int k = i * col + i; k < row * col; k += col)
    {
        if(fabs(max) < fabs(arr[k]))
        {
            max = arr[k];
            index = k;
        }

    } 
    return index / col;
}

// 两行交换
float *swapRow(float *arr, int row, int col, int i, int j)
{
    float tmp;
    for(int k = 0; k < col; k++)
    {
        tmp = arr[i * col + k];
        arr[i * col + k] = arr[j * col + k];
        arr[j * col + k] = tmp;        
    }

    return arr;
}




// 主函数
int main(int argc, char *argv[])
{
    float arr[] = {2, 3, 11, 5, 2,
                    1, 1, 5, 2, 1,
                    2, 1, 3, 2, -3,
                    1, 1, 3, 3, -3};

    printf("高斯消元之前:\n");
    printArr(arr);

    float *a = solution(arr, 4, 5, argc, argv);

    printf("\n高斯消元求解后:\n");    
    printArr(arr);

    return 0;
}

 

GG:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值