Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档
资料存档 资料存档
回复
 
主题工具 显示模式
旧 2019-12-06, 07:47   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
默认 算法在C语言中工作正常,但在Matlab中给出错误结果

我得到了C代码来解决我在这里描述的工作。我通过取Ef [1180 ,:]的最小值(称为Ef [1180,x] )来构成向量Ps_trace ,并将Ef [1180,x] .Ps的对应值保存到Ps_trace [1180]中 。然后我检查什么是Ef中[1180,x]中的由下列这是Ef中[1180,x]中的计算期间设置的指针的前身=> Ef中[1180中,x]。既往 。重复此过程,直到得到完整的Ps_trace向量。如您所见, Ef仅取决于Ps ,因此,如果我们采用Ps_trace并在1180个步长后使用它来计算Ef ,则最终应得到与Ef [1180,x]完全相同的值。

我知道,令人困惑的东西。但是,C代码正确地完成了,实际上我最终得到了相同的Ef值。然后,我尝试将此代码尽可能精确地复制到matlab。我不知道如何在matlab中正确地执行指针操作,因此我只有一个大小为2的向量,其中包含前任的相应矩阵索引。

在C程序中,我将Ps_trace保存到一个二进制文件中,并将此数据加载到Matlab中(没有错误,我对此进行了非常彻底的验证)。然后,我将其与Matlab脚本生成的Ps_trace进行比较,它们完全不同!现在,我知道C程序生成的Ps_trace向量是100%正确的,因此它必须在Matlab脚本中。

我必须将代码交给Matlab,而不是C。由于无法正常工作,我今天早些时候决定首先在C中实现我的解决方案。我整天都在为这种转换而苦恼。也许你们中的一位会看到我做错了。我一直盯着屏幕看了很久,以至于我看不到它了。

这是C代码:

#include #include #define N 1180 #include "Pr.h" #define ES_MAX 650 #define PS_MIN -21 #define PS_MAX 21 #define A_M 2.42 #define B_M 2.5 #define INF_FLOAT 9999999999999999999999.9 #define INF_INT 999999999 #define max(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; }) typedef struct EF { float value; int Ps; struct EF *previous; } Ef_t; union { char asBytes[4]; float asFloat; int asInt; } converter; int main(void) { Ef_t **Ef = (Ef_t **)malloc((N + 1) * sizeof(Ef_t *)); for(int i = 0; i < N + 1; i++) { Ef[i] = (Ef_t *)malloc((ES_MAX + 1) * sizeof(Ef_t)); for(int j = 0; j < ES_MAX + 1; j++) { Ef[i][j].value = INF_FLOAT; Ef[i][j].Ps = INF_INT; Ef[i][j].previous = NULL; } } Ef_t *pointer; float min_Ef = INF_FLOAT; int min_Ef_index; char msg[64]; for(int n = 0; n < N + 1; n++) { Pr[n] = Pr[n] / 1000.0; } for(int Ps = PS_MIN; Ps = 0) { Ef[1][Es].value = A_M * max(Pr[0] - (float)Ps, 0.0) + B_M; Ef[1][Es].Ps = Ps; } } for(int n = 2; n < N + 1; n++) { for(int Ps = PS_MIN; Ps previous; } for(int n = 1; n < N + 1; n++) { snprintf(msg, sizeof(msg), "%d\n", Ps_trace[n]); printf(msg); } float Ef_test[N + 1]; Ef_test[0] = 0.0; for(int n = 1; n < N + 1; n++) { Ef_test[n] = Ef_test[n - 1] + A_M * max(Pr[n] - (float)Ps_trace[n], 0.0) + B_M; } snprintf(msg, sizeof(msg), "Ef_test[%d] = %f\n", N, Ef_test[N]); printf(msg); FILE *f = fopen("Ps.bin", "wb"); for(int n = 1; n < N + 1; n++) { converter.asFloat = (float)Ps_trace[n]; for(int i = 0; i < 4; i++) { fwrite(&converter.asBytes[i], sizeof(char), 1, f); } } fclose(f); getchar(); return 1; } 这是Matlab代码:

clear all; close all; clc; load Pr Pr = Pr / 1000.0; N = 1180; ES_MAX = 650; PS_MIN = -21; PS_MAX = 21; A_M = 2.42; B_M = 2.5; Ef(1:N, 1:ES_MAX + 1) = Ef_t; for Ps = PS_MIN:1:PS_MAX Es = -Ps; if(Es >= 0) Ef(1, Es + 1).value = A_M * max(Pr(1) - Ps, 0.0) + B_M; Ef(1, Es + 1).Ps = Ps; end end for n = 2:1:N for Ps = PS_MIN:1:PS_MAX for Es = 0:1:ES_MAX Es_old = Es + Ps; if( (Ps = 0) && (Es_old < ES_MAX) ) tmp = Ef(n - 1, Es_old + 1).value + A_M * max(Pr(n) - Ps, 0.0) + B_M; if(tmp < Ef(n, Es + 1).value) Ef(n, Es + 1).value = tmp; Ef(n, Es + 1).Ps = Ps; Ef(n, Es + 1).previous = [n - 1, Es_old + 1]; end end end end end [min_Ef, min_Ef_index] = min([Ef(N, :).value]) Ps_trace = -Inf * ones(N, 1); pointer = [N, min_Ef_index]; for n = N:-1:1 Ps_trace(n) = Ef(pointer(1), pointer(2)).Ps; if(n > 1) pointer = Ef(pointer(1), pointer(2)).previous; end end Ef_test = -Inf * ones(N, 1); Ef_test(1) = 0; Ps_from_c = fread(fopen('Ps.bin'), 1180, 'float'); comp_matlab_c = [Ps_trace, Ps_from_c] 这是我用来模拟C的struct函数的Ef_t.m文件:

classdef Ef_t properties value = Inf; Ps = Inf; previous = -ones(2, 1); end end 欢迎对我的代码提出一些一般性批评,但是我最需要有关Ps_trace问题的帮助。我的最后一个选择是将代码仍然交到C中并丢分。



更多&回答...
poster 当前离线   回复时引用此帖
回复


发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛禁用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 01:16


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.