Creating a vectorized statement in MatLab to output a 5x5 Hilbert matrix

In summary: So i = (1:5)'; will make i the 5 x 5 column vector containing 1, 2, ..., 5, and it will also make j the 5 x 1 row vector containing 1, 2, ..., 5.
  • #1
chopnhack
53
3
Homework Statement
As an introduction to MatLab, we have been given various assignments to get familiar. Now on page nine I find myself getting an empty 1x0 vector instead of the anticipated 5x5 Hilbert matrix.
The problem is to create a 5x5 Hilbert matrix using vectorized statements only, no loops. (The loops I have already completed)
Relevant Equations
Each element of the Hilbert matrix is defined by 1/(i+j-1). The solution should look like:

1.0000 0.5000 0.3333 0.2500 0.2000
0.5000 0.3333 0.2500 0.2000 0.1667
0.3333 0.2500 0.2000 0.1667 0.1429
0.2500 0.2000 0.1667 0.1429 0.1250
0.2000 0.1667 0.1429 0.1250 0.1111
My first attempt was:
V=zeros(5,5)
a=1;
i=1:5;
j=1:5;
V(i:j)=a./(i+j-1)

I figured to create a 5x5 with zeros and then to return and replace those values with updated values derived from the Hilbert equation as we move through i and j.
This failed with an error of : Unable to perform assignment because the left and right side have different number of elements.

My next attempt was:
i=1:5;
j=1:5;
V = 1:(1./(i+j-1)):0.111

I began my matrix at 1, just like the Hilbert example, use the Hilbert equation for the decrementer and the end point of the 5x5 is 0.111
This failed with an error of:

V =
1×0 empty double row vector

Can anyone provide some assistance?
Thanks in advance!
 
Physics news on Phys.org
  • #2
It seems to me that you do not have a proper understanding about how the : operator works in Matlab or what certain other operations mean. Let us break it down.

chopnhack said:
My first attempt was:
V=zeros(5,5)
a=1;
i=1:5;
j=1:5;
V(i:j)=a./(i+j-1)
The four first rows do what you expect them to (although I do not understand why you pre-define a variable a). After those you will have both i and j equal to [1 2 3 4 5]. Now, the statement "i:j" in the argument does not do what you think it does. The purpose of the : operator is to create a vector with increments of 1 from i to j. It does so by just using the first element of either so the result of i:j is just a number 1 in this case. What you are writing in the fifth line is therefore:
V(1) = 1./(i+j-1)
Even though V is a matrix, you can always access its elements as enumerated vector elements, so the left-hand side actually has a meaning (in this case it is actually the element V(1,1)) and it is a single number, you are trying to assign the right-hand side to that single number. However, on the right hand side you have
1./(i+j-1)
Now, i+j is just vector addition so the result is i+j-1 = [1 3 5 7 9], which is not what you want to do. Upon taking 1./ this, you just do an element-wise division, resulting in [1 1/3 1/5 1/7 1/9]. This is a vector and you cannot assign a vector value to the single element V(1,1). This is what Matlab is telling you when it tells you the left and right have different numbers of elements.

chopnhack said:
V = 1:(1./(i+j-1)):0.111
Let us return to your use of the : operator. First of all, 1./(i+j-1) is equal to [1 1/3 1/5 1/7 1/9], just as above. This means that the : operator structure is equivalent to 1:1:0.111. You are therefore essentially telling Matlab that you want a vector starting at 1, with increments of 1, that has no elements larger than 0.111. This vector has zero elements.

In order to solve your issue, I suggest looking at creating matrices of the correct size that are valued according to row/column, call them I and J, and then work from there.
 
  • #3
Personally, I'd do this with REPMAT. I'll sketch that out in a minute, but first I want to help you understand the errors here a little more.

Code:
V=zeros(5,5)
a=1;
i=1:5;
j=1:5;
V(i:j)=a./(i+j-1)

i and j are both row vectors. That's what is created by the colon operator. So both of them are 1 x 5.
(i + j - 1) is going to be a row vector containing [1 2 3 4 5] + [1 2 3 4 5] - 1 = [2 4 6 8 10] - 1 = [1 3 5 7 9]. I'm pretty sure you didn't intend that.

(Side note: You probably noticed that you get lots of extraneous output here, for instance the contents of V after line 1. That may be useful for debugging, but otherwise you want to end your lines with semicolons.)

You don't need V(i:j) on the left since you're trying to create a 5 x 5 expression on the right. Just assign it to V.

So what you want is an expression that is 5 x 5. You aren't going to get that by adding a 1 x 5 to a 1 x 5. What in that expression told Matlab that you wanted one of those to be interpreted as a column?

So you should be thinking first of all in terms of the transpose operator ('). For instance i = (1:5)'; will make i the 5 x 1 column vector containing 1, 2, ..., 5.

chopnhack said:
This failed with an error of : Unable to perform assignment because the left and right side have different number of elements.
Because the right side is 1 x 5.

Code:
My next attempt was:
i=1:5;
j=1:5;
V = 1:(1./(i+j-1)):0.111

The colon operator is not vectorized.

OK, I said that I'd do it with REPMAT. The REPMAT makes a larger vector or matrix by replicating a smaller one. So (big hint) for instance if you create a 1 x 5 column vector and want to make a 5 x 5 matrix which has that in each column, you can do repmat(x, 1, 5); That is copying it 1 time in the vertical direction and 5 times in the horizontal direction.

Your first attempt was closer, but what you want to be manipulating are 5 x 5 matrices so that your result has the right shape and contains all the combinations.

So imagine the matrix expression 1./(I + J - 1) where I and J are 5 x 5 matrices constructed to give the right combination in each position. What's in those matrices? How do you construct them with REPMAT?
 
  • #4
Another very tricky and idiomatic solution would use MESHGRID. Just try typing [X, Y] = meshgrid(1:5, 1:5) without the semicolon so you see the result, and examine the output, and think about that in terms of your expression.
 
  • #5
RPinPA said:
OK, I said that I'd do it with REPMAT.
I do not think this is the easiest way. Meshgrid is more suitable for this task.
 
  • #6
Orodruin said:
I do not think this is the easiest way. Meshgrid is more suitable for this task.

Which I saved for the followup reply, apparently typed while you were typing this :cool:

As this appears to be a beginning Matlab class, I wasn't sure how tricky to get so was trying to go for more elementary operations.
 
  • #7
Also, if you want to save typing, [I,J] = meshgrid(1:5) works fine. You could also use I = meshgrid(1:5,1:5) and replace J everywhere with I'. It will be equivalent.
 
  • #8
Thank you gents!

I=1:5;
J=transpose(1:5);
V=1./(I+J-1)

I think I got it - by transposing one matrix, MATLAB implicitly extends zeros to create a 5x5 matrix before beginning the operation for V=. Then each value starting at 1,1 fills in the matrix, 1 then 0.5 across the first row,
etc.

Thanks!
 
  • #9
Don't have Matlab on this computer but I'd be very surprised if that worked. I is 1 x 5, J is 5 x 1 and so (I + J - 1) won't work.

chopnhack said:
matlab implicitly extends zeros to create a 5x5 matrix

No, I don't think Matlab would do that. As I said, I can't do the experiment right now.
 
  • #10
Input:
I=1:5;
J=transpose(1:5);
V=1./(I+J-1)

output as copied from Matlab:
V = 5×5
1.0000 0.5000 0.3333 0.2500 0.2000
0.5000 0.3333 0.2500 0.2000 0.1667
0.3333 0.2500 0.2000 0.1667 0.1429
0.2500 0.2000 0.1667 0.1429 0.1250
0.2000 0.1667 0.1429 0.1250 0.1111
 
  • #11
Well, color me shocked.
What is J?
What is (I + J - 1)?
 

FAQ: Creating a vectorized statement in MatLab to output a 5x5 Hilbert matrix

What is a Hilbert matrix?

A Hilbert matrix is a square matrix in which the elements are defined by the formula Aij = 1/(i+j-1). It is a special type of matrix that is commonly used in numerical analysis and linear algebra.

Why would I want to create a vectorized statement in MatLab to output a 5x5 Hilbert matrix?

Creating a vectorized statement in MatLab allows for a more efficient and concise way of generating a Hilbert matrix. It also allows for easier manipulation and analysis of the matrix.

What is the advantage of using a vectorized statement over a for loop?

Using a vectorized statement eliminates the need for a for loop, which can be time-consuming and less efficient. It also allows for faster execution of the code and reduces the chances of errors.

Can I modify the code to output a different sized Hilbert matrix?

Yes, the code can be modified to output a Hilbert matrix of any size by changing the dimensions in the vectorized statement. You can also use a variable to specify the size of the matrix.

How can I use the Hilbert matrix generated by the vectorized statement in my research or experiments?

The Hilbert matrix can be used in a variety of applications, such as solving systems of linear equations, interpolation, and numerical integration. It is also commonly used as a test case for evaluating the accuracy of numerical algorithms. Depending on your specific research or experiment, the Hilbert matrix may have various uses and applications.

Back
Top