Nic*_*k_R 3 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);
      print(b);
      print(d);
      print(e);
      print(f);
    end
  end
end
我收到以下错误:
一个)
Run Code Online (Sandbox Code Playgroud)Error using + Matrix dimensions must agree. Error in trial (line 6) K=A+B
b)
Run Code Online (Sandbox Code Playgroud)Error using vertcat CAT arguments dimensions are not consistent. Error in trial (line 5) C=[d 0;e f];
这有什么不对?
(请注意,我是MATLAB的新手)
谢谢
Rod*_*uis 38
哎哟! 哎哟!让我直接跳到那里,在你继续沿着这条道路前打断你!
我知道你不是程序员,但在生活中的某些时刻(显然,这是你的!),你必须面对事实并成为一个,不管是暂时的.所以要知道编程不是真正的科学,它是一种艺术,如果你愿意的话,是一种手艺,而且很容易出错.还要知道,在你面前有数以百万计的程序员,他们为你铺平了道路,发现哪种方法效果最好,哪种方法导致了某些灾难.
我将描述代码中存在的其中六个"道路到某些厄运".
首先在列表中,是使用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'};  
将有时工作,有时失败.可能发生的更糟糕事情的一个例子:
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
没有错误,没有警告,什么都没有,但你的结果仍然是垃圾.随着您的功能变得越来越大(通常也会这样),这个错误变得越来越难以找到.花几天时间来发现这种错误并不罕见.
在您的代码中,您还可以更改全局变量a和b循环内部.这意味着任何使用a和在此完成后b调用的函数/脚本都将看到和.现在假设你在这些循环中调用一个函数,它改变了它的值.在-loop 的下一次迭代中,它的价值是多少?假设你也得到了错误的结果.你会如何找到这个错误?a=10b=10aaa
像这样的代码通常被称为"意大利面条代码",原因很明显.也许它会起作用,并且很容易编码,但最终它会让你大大减慢速度(更不用说继承你代码的人了).
防止大部分这种情况的更好方法是在较大的容器中收集数据,并明确地传递它们.假设我们使用a struct作为数据a-l:  
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 = 5;的myFunction 是不会改变的result,还是原来的data传递给函数-你已经打破了紧耦合,并阻止所有上述问题.
键入help struct或help cell在Matlab命令窗口中了解这些类型的通用容器.
列表中的第二个是使用变量名称l.这有些愚蠢,我可以简短地说:不要这样做:)与大多数人(甚至是一些程序员)相信的情况相反,你只编写了一行代码,但你读了数百个,如果不是数千个时间.最佳做法是尽可能简化阅读,而不是写作.该l只是看起来像1,不是吗?该bug k=1VS k=l仅仅是难度比现货k=mVS k=1.
列表中的第三个是关键字transpose.这有点啰嗦,不是吗?在数学中,你会使用A T,这比在所有时间写完整定义要容易得多:
B = {A IJ ➝A ジ ∀我<M⋏Ĵ<N
你通常只说B = A 牛逼.在Matlab中也是如此.所述transpose矩阵可以实现像这样:
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.';
名单上的第四位是平等K==M.它就在这里,K而且M是矩阵.表达式K==M求值逐元素,其原因后面将变得明显在编程生涯:)这意味着,K==M将再次的矩阵,尺寸相同K,并M包含0如果对应于元件K和M不相等,并且1如果这些元素是平等的.那么,if陈述会对这样一个矩阵做什么呢?在Matlab中,true只要第一个元素为真(在我看来,它应该抛出一个错误,但是哦).
这显然不是你想要的.我认为你想要的是两个矩阵中的所有元素是相等的.你最好用这个:
if all( abs(K(:)-M(:)) < eps )
其中(:)-notation表示矩阵K,M应在比较之前扩展为列向量.这是因为all()作品落单的尺寸,所以all(K==M)将仍然是一个矩阵(向量,实际上,但这是同一事物的一种特殊情况下使用不同的名称).请注意,我不使用equality(==),而是检查它们的差异是否小于某个微小的值(eps).这是因为在浮点运算(所有计算机都使用)中,乘法和平方根等运算通常会遇到舍入误差和近似/插值误差等问题.一个平等是一个非常艰难的需求,过于强硬,以评估true在大多数情况下,它在数学上应该说.您可以通过将两者的差异与一个与舍入误差(eps)相关的微小值进行比较来防止此失败检测到相等性.
列表中的第五位是您打印的方式.该print声明,其本身将发送数字到系统的默认打印机,你知道,关于它,如果它感觉就像今天的合作与墨水吐出来的纸张穆迪机:)现在,我假设你试图显示上的东西屏幕.这样做就像你开始展示事物的方式不是最好的方法:你会得到十几个未命名的非结构化值列表:
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
选项1将只显示
a = 
    1
b = 
    1
etc.
至少还会显示变量的名称及其值.选项2是更好的选择:
a: 1
b: 1
d: 3
e: 4
f: 5
a: 1
b: 2
d: 3
e: 4
f: 5
etc.
(顺便说a,b,d,e,f 一下,循环中的值永远不会改变,那么为什么要首先显示它们呢?)
列表中的第六个(也是最后一个!)是特定于Matlab的一个:for-loops.Matlab是一种基于矩阵的解释语言.它的矩阵性质只意味着每个变量本质上都是一个矩阵.解释意味着计算机的处理器不会直接看到您的代码,在计算任何内容之前,它必须经过一系列的解释和翻译.这枚硬币有两面:
根据性能,for-loop在Matlab中因为将操作带入爬行而臭名昭着.在Matlab中的方法通常是矢量化代码,例如,使用所有变量都是矩阵的事实,并对它们使用矩阵/张量运算而不是循环.这在大多数编程语言中并不是一种非常常见的方法(并且在不习惯它的程序员中会看到很多强大的,强烈的阻力),但在数学上下文中它很有意义.在求助于for循环之前,总是尝试使用矩阵/张量操作作为第一道攻击线(并且Matlab有很多它们,请注意!).
所以,这有什么错你的代码:)噢,和安德烈亚斯Hangauer已经提到,将参照声明a通过l,和所有需要被accordinly重新计算,循环内部,你会被罚款.