3

Let's say I have a matrix that has X rows and Y columns. The total number of elements is X*Y, correct? So does that make n=X*Y?

for (i=0; i<X; i++)
{
   for (j=0; j<Y; j++)
   {
      print(matrix[i][j]);
   }
}

Then wouldn't that mean that this nested for loop is O(n)? Or am I misunderstanding how time complexities work?

Generally, I thought all nested for loops were O(n^2), but if it goes through X*Y calls to print(), doesn't that mean that the time complexity is O(X*Y) and X*Y is equal to n?

vgmoose
  • 445
  • 4
  • 10

4 Answers4

1

If you have a matrix of size rows*columns, then the inner loop (let's say) is O(columns), and the nested loops together are O(rows*columns).

You are confusing a problem size of N for a problem size of N^2. You can either say your matrix is size N or your matrix is size N^2, though unless your matrix is square you should say that you have a matrix of size Rows*Columns.

ninjagecko
  • 88,546
  • 24
  • 137
  • 145
1

You are right when you say n = X x Y but wrong when you say the nested loops should be O(n). The meaning of nested loop can be understood if you dry run your code. You will notice that for each iteration of the outer loop the inner loop runs n (or what ever is the size condition) times. Hence, by simple math, you can deduce that its O(n^2). But, if you had just one loop when you will be iterating over (X x Y) (Eg: for(i = 0; i<(X*Y); i++) elements, then it will be O(n) cause you are not restarting your iteration at any point of time. Hope this makes sense.

noMAD
  • 7,744
  • 19
  • 56
  • 94
0

Generally, I thought all nested for loops were O(n^2),

You are wrong about that. What confuses you I guess is that often people use as an example square(X==Y) matrix so complexity is n*n(X==n,Y==n).

If you want to practise your O(*) skills try to figure out why matrix multiplication is O(n^3). IF you dont know the algorithm for matrix multiplication it is easy to find it online.

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
0

This answer was written hastily and received a few downvotes, so I decided to clarify and rewrite it

Time complexity of an algorithm is an expression of the number of operations of the algorithm in terms of the size of the problem the algorithm is intended to solve.

There are two sizes involved here.

  1. The first size is the number of elements of the matrix X × Y This corresponds to what is known in complexity theory as the size of input. Let k = X × Y denote the number of elements in the matrix. Since the number of operations in the twin loop is X × Y, it is in O(k).

  2. The second size is the number of columns and rows of the matrix. Let m = max(X,Y). The number of operations in the twin loop is in O(m^2). Usually in Linear Algebra this kind of size is used to characterize the complexity of matrix operations on m × m matrices.

When you talk about complexity you have to specify precisely how you encode an instance problem and what parameter you use to specify its size. In Complexity Theory we usually assume that the input to an algorithm is given as a string of characters coming from some finite alphabet and measure the complexity of an algorithm in terms of an upper bound on the number of operations on an instance of a problem given by a string of length n. That is in Complexity Theory n is usually the size of input.

In practical Complexity Analysis of algorithms we often use other measures of the size of an instance that are more meaningful in specific context. For instance if A is a connectivity matrix of a graph, we may use the number of vertices V as a measure of complexity of an instance of a problem, or if A is a matrix of a linear operator acting on a vector space, we may use the dimension of a vector space as such a measure. For square matrices the convention is to specify the complexity in terms of the dimension of the matrix, that is to measure the complexity of algorithms acting upon n × n matrices in terms of n. It often makes practical sense and also agrees with the conventions of a specific application field even if it may contradict the conventions of Complexity Theory.

Let us give the name Matrix Scan to our twin loop. You may legitimately say that if the size of an instance of Matrix Scan is the length of a string encoding of a matrix. Assuming bounded size of the entries it is the number of elements in the matrix, k. Then we can say the complexity of Matrix Scan is in O(k). On the other hand if we take m = max(X,Y) as a parameter that characterizes the complexity of an instance, as is customary in many applications, then the complexity Matrix Scan for an X×Y matrix will is also in O(m^2). For a square matrix X = Y = m and O(k) = O(m^2).

Notice: Some people in the comments asked whether we can always find an encoding of the problem to reduce any polynomial problem to a linear problem. This is not true. For some algorithms the number of operations grows faster than the length of the string encoding of their input. For instance, there is no algorithm to multiply two m×m matrices with θ(m^2) number of operations. Here the size of input grows as m^2, however Ran Raz proved that the number of operations grows at least as fast as m^2 log m. If n is in O(m^2) then m^2 log m is in O(n log n) and the best known algorithms complexity grows as O(m^(2+c)) = O(n^(1+c/2)), where c is at least 0.372 for versions of Coppersmith-Winograd algorithm and c = 1 for the common iterative algorithm.

Dima Chubarov
  • 16,199
  • 6
  • 40
  • 76
  • 1
    How do you deduct ``O(m^2) = O(n)``? That's obviously wrong! Would it work like that we would just put every polynomial problem to linear space :) – user221931 Mar 04 '14 at 03:34
  • You say: ``In general let m = max(X,Y) then O(m^2) = O(n)``. That is just blatantly wrong no matter how you puy it. But ``O(X*Y)=O(n^2)`` is perfectly valid, you don't need to ``n=max(X,Y)`` since it's big O not big Theta notation and it is implied. The way you have your answer now, you claim that "a nested loop is O(n)", if you make a paper and prove it you're in for a Nobel :) – user221931 Mar 04 '14 at 15:42
  • And to clarify for OP and anyone else, ``O(X*Y)`` is ``O(n^2)``, because X and Y are variables. ``O(X*Y)`` can be ``O(n)`` ONLY if X OR Y is a constant (no matter how big), because it won't grow. Finally ``O(X*Y)`` can be ``O(1)`` ONLY if X AND Y are constants, then the function can't grow and it takes the same time to execute. – user221931 Mar 04 '14 at 15:52
  • Honestly, it's as simple as 1+1=2 in regard to big O notation: nested loops are O(n^2) because you have N iterations repeated over N iterations, that's N^2 in total. And O(n^2) can't be equal to O(n) like you have it, that is mathematically and logically absurd, can't you recognize that? If it would be the case then there would be no polynomial space because every problem could be "relaxed" to a linear one. So, try it yourself with some numbers or check [this](http://pages.cs.wisc.edu/~vernon/cs367/notes/3.COMPLEXITY.html#youtry3). The O(n) in the first example evolves NON nested loops. – user221931 Mar 04 '14 at 17:37
  • Did you try to actually _test_ your code? Cause [I did and guess what](http://jsfiddle.net/q4Y3w/). – user221931 Mar 04 '14 at 22:36