Sử dụng i và j làm biến trong Matlab


142

ijlà các tên biến rất phổ biến (xem ví dụ: câu hỏi nàycâu hỏi này ).

Ví dụ: trong các vòng lặp:

for i=1:10,
    % do something...
end

Khi chỉ số vào ma trận:

mat( i, j ) = 4;

Tại sao chúng không nên được sử dụng làm tên biến trong Matlab?


5
Tất nhiên tôi sẽ không gắn cờ như vậy, nhưng đánh giá từ các câu trả lời tôi sẽ nói đây là "chủ yếu dựa trên quan điểm". ;-) Cá nhân tôi sẽ không từ bỏ i, j, knhư tên biến vòng chung.
A. Donda

1
@ A.Donda tốt, đây là ý kiến của bạn ;)
Shai

@Shai, đây là câu cuối cùng của bạn trong câu hỏi này: "Tại sao chúng không nên được sử dụng làm tên biến trong Matlab?" Vì vậy, rất không rõ tại sao bạn từ chối phiên bản của tôi về câu hỏi của bạn?! Tôi đã thay đổi tiêu đề của bạn thành tiêu đề mang tính xây dựng hơn "Tại sao KHÔNG nên sử dụng i và j làm biến trong Matlab"
Seyfi

Câu trả lời:


176

Bởi vì ijcả hai chức năng biểu thị đơn vị tưởng tượng :

Vì vậy, một biến được gọi ihoặc jsẽ ghi đè lên chúng, có khả năng âm thầm phá mã làm toán phức tạp.

Các giải pháp có thể bao gồm sử dụng iijjlàm biến vòng lặp thay thế hoặc sử dụng 1ibất cứ khi nào iđược yêu cầu để đại diện cho đơn vị tưởng tượng.


42
Cũng đáng lưu ý rằng ngay cả khi bạn không phá vỡ bất cứ điều gì, thời gian thực hiện vẫn được hy sinh để giải quyết các tên ijbiến.
Eitan T

14
@Eitan: Bạn thực sự có thể sao lưu điều đó theo bất kỳ cách kết luận cụ thể nào trong phiên bản được biên soạn JIT của Matlab không? Tôi chưa bao giờ thấy nó là trường hợp (và các thử nghiệm đơn giản gọi một forvòng lặp 1 tỷ lần cho thấy không có sự khác biệt thống kê về thời gian). Đối với tất cả chúng ta biết có mã đặc biệt để xử lý chính xác điều này và sử dụng các biến khác ij(và k?) Thực sự chậm hơn một chút. Và sự khác biệt tồn tại là rất nhỏ với không tồn tại trong cuộc sống thực. Đơn giản là không có lý do KHÔNG sử dụng ijnhư các biến thông thường - chúng chỉ cần được sử dụng đúng như bất kỳ hàm Matlab nào khác.
horchler

5
@horchler Vâng, các tài liệu chính thức tuyên bố đây là trọng các lớp dữ liệu MATLAB chuẩn "có thể ảnh hưởng tiêu cực đến hiệu suất", và ở đây nó được ngụ ý để tránh trọng hằng phức tạp vì lý do tốc độ, cũng như mạnh mẽ. Trong các tài liệu cũ hơn của R2009b, nó được khuyến nghị rõ ràng chống lại các hằng số phức tạp, vì điều này có thể cản trở khả năng tăng tốc của JIT. Độ phân giải tên biến có lẽ rất nhỏ, nhưng nó có thể có ý nghĩa nếu lặp đi lặp lại hàng triệu lần.
Eitan T

14
Trong các phiên bản cổ của Matlab có thể. Tôi đã từng nhìn thấy điều đó bản thân mình. Nhưng không còn nữa với R2012a + (OS X) ít nhất. Và tôi thấy không có gì khác biệt khi gọi một forvòng lặp 1 tỷ lần và thử mọi cách sắp xếp thời gian. Tôi thấy người dùng SO mới được thông báo rằng mã hoàn toàn hợp lệ là sai vì họ đang sử dụng ijlặp lại các vòng lặp. Thành thật mà nói, thật ngớ ngẩn và mọi người đang thiếu điểm quan trọng hơn của câu hỏi này: điều đó ijthậm chí không nên được sử dụng cho đơn vị tưởng tượng nếu người ta muốn viết mã Matlab hiện đại có thể đọc được.
horchler

12
tiết kiệm thời gian chính của tôi là khi thực hiện tìm kiếm cho ii. Tìm kiếm tôi có thể là một nỗi đau thực sự
craq

62

Đó là một thực hành tốt để tránh ijcác biến để ngăn ngừa nhầm lẫn về chúng là các biến hoặc đơn vị tưởng tượng.

Cá nhân, tuy nhiên, tôi sử dụng ijnhư các biến khá thường xuyên như là chỉ số của các vòng lặp ngắn. Để tránh các vấn đề trong mã của riêng tôi, tôi thực hiện theo một thực tiễn tốt khác về ij: không sử dụng chúng để biểu thị các số ảo. Trên thực tế, tài liệu riêng của Matlab nêu rõ :

Đối với tốc độ và cải thiện độ bền, bạn có thể thay thế phức tạp ijbằng 1i.

Vì vậy, thay vì tránh hai tên biến thường được sử dụng vì xung đột tiềm tàng, tôi rõ ràng về các số ảo. Nó cũng làm cho mã của tôi rõ ràng hơn. Bất cứ khi nào tôi thấy 1i, tôi biết rằng nó đại diện sqrt(-1)bởi vì nó không thể là một biến.


2
Nó thực sự là thực hành tốt để sử dụng 1i. Tuy nhiên, việc thay đổi ý nghĩa ijcó thể dẫn đến các lỗi khó gỡ lỗi như lỗi này .
Shai

1
@Shai Điểm tốt. Tôi đã điều chỉnh câu trả lời của mình để thừa nhận rằng tránh ijlà tốt nhất, nhưng giải thích cách thức mã hóa cá nhân của tôi không tuân theo quy tắc đó.
đánh giày

2
Lưu ý rằng tốc độ được đề cập dường như không đáng kể: stackoverflow.com/questions/18163454/
Khăn

Hoàn toàn đồng ý! Thực hành tốt là LUÔN LUÔN sử dụng 1ivà không icho toán học phức tạp. Chúng ta hãy nghĩ về số ảo như 1iicoi số ảo là một thực tiễn xấu. Không phải hướng ngược lại. Sử dụng i, ii, iiilà thực tế phổ biến trong Matlab và không có vấn đề khi người ta dính vào 1i1jcho số phức tạp. Ngoài ra Matlab tôn trọng điều này và điều này không làm giảm hiệu suất (theo như tôi đã thử nghiệm) như đã nêu trong câu trả lời trước.
SdidS

i và j không nên được sử dụng bằng mọi cách - những số đó có nghĩa là gì đó - sử dụng tên mô tả mục đích (row_n, ElementNo, listItemIndex, v.v.). Thật dễ dàng hơn cho ai đó để hiểu những gì bạn đang làm, gỡ lỗi, v.v. Thời gian thêm được dành nhiều hơn đáng để đạt được trong khả năng duy trì lâu dài cho bất cứ điều gì ngoài một kịch bản ném đi - ngay cả với Trình soạn thảo Matlab bị tụt hậu hầu hết các IDE hiện đại khác.
LightCC

27

Trong các phiên bản cũ của MATLAB, đã từng có một lý do chính đáng để tránh sử dụng ijlàm tên biến - các phiên bản ban đầu của MATLAB JIT không đủ thông minh để biết bạn đang sử dụng chúng làm biến số hay là đơn vị tưởng tượng, và do đó sẽ tắt nhiều tối ưu hóa có thể.

Do đó, mã của bạn sẽ trở nên chậm hơn chỉ bằng sự hiện diện của ijnhư các biến và sẽ tăng tốc nếu bạn thay đổi chúng thành một thứ khác. Đó là lý do tại sao, nếu bạn đọc qua nhiều mã MathWorks, bạn sẽ thấy iijjsử dụng khá rộng rãi như các chỉ số vòng lặp. Trong một thời gian, MathWorks thậm chí có thể khuyên mọi người tự làm điều đó một cách không chính thức (mặc dù họ luôn chính thức khuyên mọi người lập trình cho sự thanh lịch / duy trì hơn là bất cứ điều gì JIT hiện tại làm, vì đó là mục tiêu di chuyển của mỗi phiên bản).

Nhưng đó là một thời gian dài trước đây và ngày nay, đó là một vấn đề "thây ma" thực sự ít quan trọng hơn nhiều người vẫn nghĩ, nhưng từ chối chết.

Trong bất kỳ phiên bản gần đây, nó thực sự là một sở thích cá nhân có nên sử dụng ijlàm tên biến hay không. Nếu bạn làm nhiều việc với số phức, bạn có thể muốn tránh ijlàm biến, để tránh mọi rủi ro nhỏ có thể gây nhầm lẫn (mặc dù bạn cũng có thể / thay vào đó chỉ muốn sử dụng 1ihoặc 1jít nhầm lẫn hơn và hiệu suất tốt hơn một chút ).

Mặt khác, trong công việc điển hình của tôi, tôi không bao giờ xử lý các số phức và tôi thấy mã của mình dễ đọc hơn nếu tôi cảm thấy thoải mái khi sử dụng ijnhư các chỉ số vòng lặp.


Tôi thấy rất nhiều câu trả lời ở đây nói rằng Không nên ... mà không nói ai đang làm điều đó. Đây là phạm vi đề xuất thực tế của MathWorks, từ tài liệu phát hành hiện tại cho i:

Vì tôi là một hàm, nó có thể được ghi đè và được sử dụng như một biến. Tuy nhiên, tốt nhất là tránh sử dụng i và j cho tên biến nếu bạn có ý định sử dụng chúng trong số học phức tạp. [...] Để tăng tốc và cải thiện độ bền, bạn có thể thay thế i và j phức tạp bằng 1i.


15

Như được mô tả trong các câu trả lời khác, việc sử dụng imã chung không được khuyến nghị vì hai lý do:

  • Nếu bạn muốn sử dụng số ảo, nó có thể bị nhầm lẫn hoặc ghi đè bởi một chỉ mục
  • Nếu bạn sử dụng nó như một chỉ mục, nó có thể ghi đè hoặc bị nhầm lẫn với số ảo

Theo đề xuất: 1iiiđược khuyến nghị. Tuy nhiên, mặc dù cả hai đều là những sai lệch tốt i, nhưng thật không hay khi sử dụng cả hai lựa chọn thay thế này cùng nhau.

Đây là một ví dụ tại sao (cá nhân) tôi không thích nó:

val2 = val + i  % 1
val2 = val + ii % 2
val2 = val + 1i % 3

Một người sẽ không dễ dàng bị đọc sai cho hai hoặc ba, nhưng hai và ba giống nhau.

Do đó, khuyến nghị cá nhân của tôi sẽ là: Trong trường hợp đôi khi bạn làm việc với mã phức tạp luôn sử dụng 1ikết hợp với một biến vòng lặp khác.

Ví dụ về các chỉ số chữ cái đó vì nếu bạn không sử dụng nhiều biến vòng lặp và chữ đủ: t, u, kp

Ví dụ về các chỉ số còn: i_loop, step, walk, vàt_now

Tất nhiên đây cũng là vấn đề sở thích cá nhân, nhưng không khó để tìm ra các chỉ số sử dụng có ý nghĩa rõ ràng mà không phát triển quá lâu.


1
1i biểu thị đơn vị tưởng tượng (cũng là tên biến Matlab không thể bắt đầu bằng số)
lib

2
@DennisJaheruddin: không biết xấu hổ cắm: Sử dụng cú pháp MATLAB tôi làm nổi bật UserScript cho Stack Overflow. Trong ví dụ cuối, 1isẽ có màu khác nhau như một số :)
Amro

2
Trực tiếp từ doc idoc j: "Để tăng tốc và cải thiện độ bền, bạn có thể thay thế i và j phức tạp bằng 1i." IMO, trong Matlab hiện tại không có lý do gì để không sử dụng ijtrong các vòng lặp, v.v., hoặc sử dụng bất cứ thứ gì ngoài 1iviệc biểu thị đơn vị tưởng tượng ( 1jcũng hoạt động). Ngoại lệ duy nhất là khi chuyển các chuỗi sang công cụ Symbolic luôn không tương thích một chút. Lạ đó help 1idoc 1ikhông làm việc mặc dù.
horchler

11

Nó đã chỉ ra rằng đó 1ilà một cách chấp nhận và rõ ràng để viết sqrt(-1), và như vậy không cần phải tránh sử dụng i. Sau đó, một lần nữa, như Dennis đã chỉ ra ( https://stackoverflow.com/a/13613729/1967394 ), thật khó để thấy sự khác biệt giữa 1iii. Đề nghị của tôi: sử dụng 1jnhư hằng số tưởng tượng nếu có thể. Đó là thủ thuật tương tự mà các kỹ sư điện sử dụng - họ sử dụng jcho sqrt(-1)iđã được sử dụng cho hiện tại .

Cá nhân tôi không bao giờ sử dụng ij; Tôi sử dụng iijjlàm các biến chỉ mục tốc ký, (và kk, ll, mm, ...) và 1jkhi tôi cần sử dụng các số phức.


2
"nó có thể được khó để thấy sự khác biệt giữa 1iii" Và thậm chí nhiều hơn sự khác biệt giữa 1lvà giữa O0. Đó là lý do tại sao bước đầu tiên tôi làm trong bản cài đặt MATALB mới là thay đổi kích thước phông chữ mặc định.
glglgl

6

Nhầm lẫn với các đơn vị tưởng tượng đã được đề cập ở đây nhưng có một số lý do khác thường hơn tại sao những cái này và các tên biến đơn chữ cái khác đôi khi không được khuyến khích.

  1. MATLAB cụ thể: nếu bạn đang sử dụng bộ mã hóa để tạo nguồn C ++ từ mã MATLAB của mình (không, thật kinh khủng) thì bạn được cảnh báo rõ ràng không sử dụng lại các biến vì các xung đột gõ.

  2. Nói chung, và tùy thuộc vào IDE của bạn, một tên biến đơn có thể gây ra sự tàn phá với các công cụ tô sáng và tìm kiếm / thay thế. MATLAB không gặp phải vấn đề này và tôi tin rằng Visual Studio đã không gặp vấn đề gì trong một thời gian nhưng các tiêu chuẩn mã hóa C / C ++ như MISRA, v.v. có xu hướng khuyên họ nên làm phiền họ.

Về phần tôi, tôi tránh tất cả các biến đơn, mặc dù có những lợi thế rõ ràng để thực hiện trực tiếp các nguồn toán học. Phải mất thêm một chút nỗ lực trong vài trăm lần đầu tiên bạn làm điều đó nhưng sau đó bạn ngừng chú ý và những lợi thế khi bạn hoặc một số linh hồn đáng thương khác đến đọc mã của bạn là quân đoàn.


4

Bất kỳ mã không tầm thường nào cũng chứa nhiều forvòng lặp và các thực tiễn tốt nhất khuyên bạn nên sử dụng tên mô tả cho biết mục đích và phạm vi của nó. Đối với lần xa xưa (và trừ khi kịch bản 5-10 đường của mình rằng tôi sẽ không tiết kiệm), tôi đã luôn luôn được sử dụng tên biến như idxTask, idxAnotherTaskidxSubTaskvv

Hoặc ít nhất là nhân đôi chữ cái đầu tiên của mảng mà nó đang lập chỉ mục, ví dụ như lập sschỉ mục subjectList, ttlập chỉ mục taskList, nhưng không iihoặc jjkhông giúp tôi dễ dàng xác định mảng nào chúng được lập chỉ mục trong nhiều vòng lặp của tôi.


3

Theo mặc định ijđứng cho đơn vị tưởng tượng. Vì vậy, theo quan điểm của MATLAB, sử dụng inhư một biến bằng cách nào đó giống như sử dụng 1như một biến.


5
Tôi không nghĩ nó khá như thế. i là tên biến hợp lệ, vì vậy bạn thực sự có thể sử dụng i và j làm tên biến. Nó sẽ, như một câu trả lời trước đó đề cập, che dấu ý nghĩa tưởng tượng. 1 không phải là một tên biến hợp pháp. nó hoàn toàn tốt nếu bạn không bao giờ sử dụng số phức.
thang

@thang đó là lý do tại sao tôi nói "bằng cách nào đó" và không "thích". Tôi biết có một sự khác biệt. OP hỏi tại sao chúng không nên được sử dụng, tôi đã cố gắng giải thích rằng đó là vì chúng đã thể hiện một số.
yo '

2
ok, xin lỗi, tôi không biết bằng cách nào đó có nghĩa là gì. đối với tôi nó rõ ràng khác biệt bởi vì, bạn không thể sử dụng 1 như một biến ngay cả khi bạn muốn ... nhưng tôi thấy bạn đến từ đâu.
thang

bạn có thể sử dụng chúng, vì bạn cũng có thể sử dụng các tên hàm hiện có cho các biến (và đồng thời làm hỏng các hàm / hằng số dựng sẵn đó để sử dụng tiếp). Cho dù bạn thực sự muốn đó là một điều khác (câu trả lời đơn giản: không)
Gunther Struyf

1
Xin lỗi, nhưng lời giải thích này không có ý nghĩa. Các ijthực sự là các hàm trả về giá trị của đơn vị tưởng tượng. Có thể sử dụng một biến có cùng tên với một hàm trong một phạm vi. Điều này tuy nhiên sẽ che bóng chức năng.
patrik

2

Trừ khi bạn là một người dùng rất bối rối, tôi nghĩ rằng có rất ít rủi ro trong việc sử dụng tên biến ij và tôi sử dụng chúng thường xuyên. Tôi chưa thấy bất kỳ dấu hiệu chính thức nào cho thấy nên tránh thực hành này.

Mặc dù đúng là việc tạo bóng cho đơn vị tưởng tượng có thể gây ra một số nhầm lẫn trong một số ngữ cảnh như được đề cập trong các bài đăng khác, nhưng về tổng thể, tôi chỉ đơn giản không xem đó là một vấn đề lớn. Có nhiều điều khó hiểu hơn bạn có thể làm trong MATLAB, ví dụ như xác địnhfalse=true

Theo tôi, lần duy nhất bạn có thể nên tránh chúng là nếu mã của bạn đặc biệt liên quan đến các số ảo.


Bạn có thể vui lòng bình luận khi bỏ phiếu xuống. Ví dụ với liên kết Mathworks chỉ ra rằng thực tiễn không được khuyến nghị (điều này đã được tuyên bố bởi nhiều người đăng mà không tham khảo bất kỳ hướng dẫn chính thức nào). Trong thực tế, sử dụng 'i' trong các vòng lặp đang được Mathworks sử dụng trong các ví dụ chính thức. Theo kinh nghiệm của tôi, nó làm cho mã rõ ràng và súc tích và là thông lệ rất phổ biến.
gregswiss

1
Trích dẫn tài liệu "Vì ilà một hàm, nó có thể được ghi đè và sử dụng như một biến. Tuy nhiên, tốt nhất là tránh sử dụng ijcho các tên biến nếu bạn có ý định sử dụng chúng trong số học phức tạp." Điều đó, kết hợp với nhận xét của Eitan T về câu trả lời của Oliver (tôi đoán anh ấy đã hẹn giờ) dường như là bằng chứng đầy đủ.
Adriaan

1
Cũng lưu ý rằng đã có câu trả lời từ năm 2013 với nhận xét được đề cập bởi @Adriaan.
Andras Deak

1
vì vậy tài liệu nêu rõ NẾU bạn có ý định sử dụng số học phức tạp, nếu không thì không áp dụng - không biết tại sao mọi người lại quá bận tâm về nó ở đây! Tôi chỉ đưa ra một quan điểm thay thế.
gregswiss
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.