这个MATLAB代码有什么问题?

这个MATLAB代码有什么问题?,matlab,concatenation,dimensions,Matlab,Concatenation,Dimensions,我试着在MATLAB中做以下工作 global a b c d e f g h l; A=[1 3;3 2]; B=[a 0;0 b]; C=[d 0;e f]; Ctranspose=transpose(C); D=[sqrt(d) 0;0 sqrt(f)]; E=Ctranspose/D; Etranspose=transpose(E); K=A+E; M=E*D*Etranspose; for a=1:10 for b=1:10 if K==M print(a)

我试着在MATLAB中做以下工作

global a b c d e f g h l;
A=[1 3;3 2];
B=[a 0;0 b];
C=[d 0;e f];
Ctranspose=transpose(C);
D=[sqrt(d) 0;0 sqrt(f)];
E=Ctranspose/D;
Etranspose=transpose(E);
K=A+E;
M=E*D*Etranspose;

for a=1:10
  for b=1:10
    if  K==M
      print(a);
      print(b);
      print(d);
      print(e);
      print(f);
    end
  end
end
我发现以下错误:

(a)

(b)

这里怎么了

(请注意,我是MATLAB新手)


谢谢

您没有指定a b c d e f g h l的值是什么,而是指定它们是全局变量

a) 第一个错误:假设您在第6行得到一个错误,
a
b
不是标量

b) 第二个错误:(错误在第4行而不是第5行)。这里,
d
e
f
中的一个也不是标量。这里发生的是
d
e
可能是标量,但
f
不是,f是向量或矩阵。因此,矩阵的第一行与第二行的长度不同,因此存在误差


用于
循环的目的是什么<仅当
M
K
的所有元素相等时,code>M==K才会返回true,但第二行和第一列中的元素永远不会相同。如果
M
K
是同一个矩阵,那么对于
a
b
的所有值组合,代码将只打印
d
e
f
。(请注意,
a
b
for
循环中被重新定义。)

您必须更改程序的顺序

d = 4567; % some value necessary
e = 1234; % some value necessary
f = 4567; % some value necessary
for a=1:10
 for b=1:10

    A=[1 3;3 2];
    B=[a 0;0 b];
    C=[d 0;e f];
    Ctranspose=transpose(C);
    D=[sqrt(d) 0;0 sqrt(f)];
    E=Ctranspose/D;
    Etranspose=transpose(E);
    K=A+E;
    M=E*D*Etranspose;


   if  K==M
     print(a);
     print(b);
     print(d);
     print(e);
     print(f);

   end
 end
end

您似乎没有正确理解编程语言的基本概念。在编程语言中(与数学符号不同),语句是一个接一个依次执行的命令。执行该命令时,计算中需要的所有值都必须可用,因此更新的执行顺序对于预期操作是必要的。

哎哟!哎哟在你继续走这条路之前,让我直接跳进去打断你

我知道你不是一个程序员,但在生活的某个时刻(显然,这是你的!),你必须面对事实,成为一个程序员,无论是多么短暂。所以要知道,编程并不是一门真正的科学,它是一门艺术,一门手艺,如果你愿意的话,而且很容易出错。还要知道,在你之前已经有数以百万计的程序员,他们为你铺平了道路,发现了哪些方法工作得最好,哪些方法导致了某种灾难

我将描述代码中存在的六条“通往末日的道路”

列表中的第一个是使用
global
不要使用全局变量当然,它们适用于小而简单的事情,但更好、更易管理、更持久、更健壮、更不容易出错的数据传递方式是手动进行。根据经验,创建所有顶级函数时,尽可能少地依赖于其他函数/变量。这是因为全局变量在程序的状态和函数的输出之间产生了紧密耦合,这使得即使不是不可能,也很难再现任何错误,而调试(这实际上是任何程序员花费大部分时间进行的)则成了一场噩梦。此外,除运行的函数之外的任何函数都可以更改它们,以便

function testMe
    global a;
    a = 5*rand;
    someFunction;
    b = 4*a; % ERROR! or...will it? 

function someFunction
    global a;
    a = a/5;
    if a < 0.5
        someOtherFunction; end

function someOtherFunction;
    global a;
    a = {'my string'};  
没有错误,没有警告,什么都没有,但是你的结果仍然是垃圾。随着你的函数越来越大(通常情况下,它们会),这个错误越来越难发现。花上好几天的时间来发现这种错误并不罕见

在代码中,还可以更改循环中的全局变量
a
b
。这意味着,任何使用
a
b
的函数/脚本,在该函数/脚本完成后被调用,将看到
a=10
b=10
。现在假设您在这些循环中调用一个函数,该函数更改
a
的值。在
a
循环的下一次迭代中,
a
的值是多少?假设你也得到了错误的结果。你将如何着手找出那个错误

出于显而易见的原因,这样的代码通常被称为“意大利面代码”。也许它会工作,并且很容易编码,但最终它会让你的速度大大降低(更不用说继承你代码的人了)

防止这种情况发生的更好方法是在更大的容器中收集数据,并显式地传递它们。假设我们对数据
a-l
使用
struct

data = struct(...
    'a', a,...
    'b', b,...
    'c', c,...
    'd', d,...
    'e', e,...
    'f', f,...
    'g', g,...
    'h', h,...
    'l', l);
所以你可以说

result = myFunction(data);
访问
myFunction
中的数据如下:
data.a
获取
a
的值,或者
data.f
获取
f
的值,等等,说
data.k=5myFunction
中的code>不会更改
结果
,也不会更改传递给函数的原始
数据
——您已经打破了紧密耦合并防止了上述所有问题

在Matlab命令窗口中键入
help struct
help cell
,以了解这些类型的通用容器

列表中的第二个使用变量名
l
。这有点傻,我可以简短地说:不要那样做:)与大多数人(甚至一些程序员)所相信的相反,你只写一行代码,但你读了几百遍,甚至几千遍。最好的做法是让阅读尽可能简单,而不是写作。
l
看起来就像
1
,不是吗?缺陷
k=1
vs
k=l
k=m
vs
k=1
更难发现

列表中的第三个是关键字
转置
。有点冗长,不是吗?在数学中,你会使用AT,这比一直写完整的定义要容易得多:

B={Aij➝ 阿吉∀ 我⋏
function testMe
    global a, b;
    a = 5; b = 6;
    result = someCalculation;
    result = a*b*result;


function someFunction
    global a;
    a = sin(pi/rand); % INTENTIONAL

    % do LOTS of stuff here

    for a = 1:10 % OOPS! unintentional use of variable name
        % do stuff
        if (some weird condition)
            break; end
    end
data = struct(...
    'a', a,...
    'b', b,...
    'c', c,...
    'd', d,...
    'e', e,...
    'f', f,...
    'g', g,...
    'h', h,...
    'l', l);
result = myFunction(data);
Actrans = A' ; % conjugate transpose
Atrans  = A.'; % regular transpose
A = [1 3;3 2];
B = [a 0;0 b];
C = [d 0;e f];    
D = [sqrt(d) 0;0 sqrt(f)];
E = C.'/D;    
K = A+E;
M = E*D*E.';
if all( abs(K(:)-M(:)) < eps )
1     % which would be the value of 'a'
1     % which would be the value of 'b'
3     % which would be the value of 'd'
4     % which would be the value of 'e'
5     % which would be the value of 'f'
...
if all( abs(K(:)-M(:)) < eps )

    % option 1
    a
    b
    d   % NOTE: not terminating with semicolon
    e
    f

    % option 2
    fprintf(...
        'a: %d\n, b: %d\n, d: %d\n, e: %d\n, f: %d\n\n', a,b,d,e,f); 

end
a = 
    1
b = 
    1
etc.
a: 1
b: 1
d: 3
e: 4
f: 5

a: 1
b: 2
d: 3
e: 4
f: 5

etc.
global a b c d e f g h l;
A = [1 3; 3 2];
B = [a 0; 0 b];
C = [d 0; e f];
Ctranspose = transpose(C);
D = [sqrt(d) 0; 0 sqrt(f)];
E = Ctranspose / D;
Etranspose = transpose(E);
K = A + E;
M = E * D * Etranspose;

for a = 1:10
    for b = 1:10
        if  K == M
            print(a);
            print(b);
            print(d);
            print(e);
            print(f);
        end
    end
end