Reshaping 3D array to 2D - matlab

Check out following toy example:
m = 3;
n = 3;
Y = rand(m,n,2);
for example gives me
y(:,:,1) =
0.8314 0.3993 0.6569
0.8034 0.5269 0.6280
0.0605 0.4168 0.2920
y(:,:,2) =
0.4317 0.1672 0.1981
0.0155 0.1062 0.4897
0.9841 0.3724 0.3395
now when I reshape it using
reshape(Y,m*n,2)
it disturbs the order and gives me,
0.8314 0.4317
0.8034 0.0155
0.0605 0.9841
0.3993 0.1672
0.5269 0.1062
0.4168 0.3724
0.6569 0.1981
0.6280 0.4897
0.2920 0.3395
because here 2nd row should be
0.3993 0.1672
this can be crosschecked before reshaping by
Y(1,1,:)
Y(1,2,:)
etc.
The order changes.
PS : I have huge data to be fed in Neural network and this affects the way my weights are being multiplied.

Add in permute there and then reshape, like so -
reshape(permute(y,[2,1,3]),[],size(y,3))
Sample run -
>> y
y(:,:,1) =
0.8314 0.3993 0.6569
0.8034 0.5269 0.628
0.0605 0.4168 0.292
y(:,:,2) =
0.4317 0.1672 0.1981
0.0155 0.1062 0.4897
0.9841 0.3724 0.3395
>> reshape(permute(y,[2,1,3]),[],size(y,3))
ans =
0.8314 0.4317
0.3993 0.1672
0.6569 0.1981
0.8034 0.0155
0.5269 0.1062
0.628 0.4897
0.0605 0.9841
0.4168 0.3724
0.292 0.3395

Related

Changing correlation matrix into covariane matrix Matlab

I'm trying to change a correlation matrix into co-variance matrix...
Importing some data, I found the co-variance (sigma_a)
sigma_a = (sigma_d + (mu_d'+1)*(mu_d+1)).^N - (mu_d'+1).^N *(mu_d+1).^N;
Which returns...
0.1211 0.0231 0.0422 0.0278 0.0411 0.0354 0.0289 0.0366 0.0343 0.0165
0.0231 0.0788 0.0283 0.0242 0.0199 0.0248 0.0219 0.0199 0.0253 0.0140
0.0422 0.0283 0.1282 0.0339 0.0432 0.0366 0.0321 0.0399 0.0420 0.0216
0.0278 0.0242 0.0339 0.0554 0.0261 0.0294 0.0312 0.0269 0.0297 0.0164
0.0411 0.0199 0.0432 0.0261 0.0849 0.0289 0.0271 0.0371 0.0317 0.0173
0.0354 0.0248 0.0366 0.0294 0.0289 0.0728 0.0293 0.0400 0.0339 0.0149
0.0289 0.0219 0.0321 0.0312 0.0271 0.0293 0.0454 0.0276 0.0309 0.0135
0.0366 0.0199 0.0399 0.0269 0.0371 0.0400 0.0276 0.0726 0.0356 0.0162
0.0343 0.0253 0.0420 0.0297 0.0317 0.0339 0.0309 0.0356 0.0715 0.0198
0.0165 0.0140 0.0216 0.0164 0.0173 0.0149 0.0135 0.0162 0.0198 0.0927
Then I found the correlation matrix (rho)
rho = inv(sqrt(diag(diag(sigma_a))))*sigma_a*inv(sqrt(diag(diag(sigma_a))));
Which returns...
1.0000 0.2365 0.3388 0.3396 0.4050 0.3772 0.3897 0.3899 0.3686 0.1556
0.2365 1.0000 0.2812 0.3656 0.2437 0.3274 0.3658 0.2631 0.3377 0.1638
0.3388 0.2812 1.0000 0.4027 0.4141 0.3792 0.4199 0.4133 0.4382 0.1985
0.3396 0.3656 0.4027 1.0000 0.3809 0.4638 0.6221 0.4246 0.4728 0.2295
0.4050 0.2437 0.4141 0.3809 1.0000 0.3681 0.4366 0.4732 0.4068 0.1948
0.3772 0.3274 0.3792 0.4638 0.3681 1.0000 0.5093 0.5499 0.4707 0.1813
0.3897 0.3658 0.4199 0.6221 0.4366 0.5093 1.0000 0.4797 0.5428 0.2079
0.3899 0.2631 0.4133 0.4246 0.4732 0.5499 0.4797 1.0000 0.4936 0.1971
0.3686 0.3377 0.4382 0.4728 0.4068 0.4707 0.5428 0.4936 1.0000 0.2435
0.1556 0.1638 0.1985 0.2295 0.1948 0.1813 0.2079 0.1971 0.2435 1.0000
I know there is the function corrcov() in matlab that finds the correlation matrix... So I tried,
corrcov(sigma_a)
I compared the results and both corrcov(sigma_a) and rho produced the same correlation matrix.
However then I wanted to change all of the pairwise correlations by exactly +0.1. Which I did, with
rho_u = (rho + .1) - .1*eye(10);
And I got the following correlation matrix...
1.0000 0.3365 0.4388 0.4396 0.5050 0.4772 0.4897 0.4899 0.4686 0.2556
0.3365 1.0000 0.3812 0.4656 0.3437 0.4274 0.4658 0.3631 0.4377 0.2638
0.4388 0.3812 1.0000 0.5027 0.5141 0.4792 0.5199 0.5133 0.5382 0.2985
0.4396 0.4656 0.5027 1.0000 0.4809 0.5638 0.7221 0.5246 0.5728 0.3295
0.5050 0.3437 0.5141 0.4809 1.0000 0.4681 0.5366 0.5732 0.5068 0.2948
0.4772 0.4274 0.4792 0.5638 0.4681 1.0000 0.6093 0.6499 0.5707 0.2813
0.4897 0.4658 0.5199 0.7221 0.5366 0.6093 1.0000 0.5797 0.6428 0.3079
0.4899 0.3631 0.5133 0.5246 0.5732 0.6499 0.5797 1.0000 0.5936 0.2971
0.4686 0.4377 0.5382 0.5728 0.5068 0.5707 0.6428 0.5936 1.0000 0.3435
0.2556 0.2638 0.2985 0.3295 0.2948 0.2813 0.3079 0.2971 0.3435 1.0000
However, when I attempt to take the adjusted correlation matrix and make it a co-variance matrix the cov() is not producing the right matrix. I tried...
b = cov(rho_u);
Why is that? Is there another way to do that? Or is there a way to adjust what I did with
rho = inv(sqrt(diag(diag(sigma_a))))*sigma_a*inv(sqrt(diag(diag(sigma_a))));
so that it does the opposite (rho found the correlation matrix) to get the co-varience matrix instead?
Based on my understanding from the answer below, then the co-variance matrix for rho_u would be achieved by, doing...
sigma = sqrt(var(rho_u));
D = diag(sigma);
sigma_u = D*rho_u*D
Is this what was meant? I was little confused by which variables I should take the variance to. I thought that meant rho_u?
The MATLAB function cov is not defined to transform a correlation matrix to covariance matrix, as its documentation says
cov(X), if X is a vector, returns the variance. For matrices, where
each row is an observation, and each column a variable, cov(X) is the
covariance matrix.
So simply feeding the correlation matrix to cov() won't work. What you need to calculate the covariance matrix is the variance of your variables (which you can calculate from your data, but didn't post here)
So in your example using the 10x10 correlation matrix rho you posted and using some random numbers for the the standard deviations
sigma = rand(size(rho(:,1)));
D = diag(sigma); % Make the sigmas appear on the diagonal of an 10x10 matrix
(you have to insert the calculated values from your input data, of course). You can then calculate the covariance matrix by
S = D*rho*D

How to component wise multiply a vector and a matrix in MATLAB?

I wanted to compute the follow expression:
a_2 = c_k2 * (b - t_k2)
where t_k2 is a column vector of size K1 x K2, b is of size K1 x 1 and c_k2 is a constant (1 x 1). But I have K2 of those t vectors. I know that I could just do:
t % (K1 x K2)
b % (K1 x 1)
a_k2 % (K1 x K2)
c % (K2 x 1)
for k2=1:K2
t_k2 = t(:,k2); % K1 x 1
c_k2 = c(k2);
a_k2(:,k2) = c_k2 * (b - t_k2); % K1 x 1
end
but I was wondering if there was a cleaver way to write it as a single line in MATLAB (to avoid all the indexing and the looping and hopefully gain speed up). Is that possible?
My initial idea could be to replicate b into a matrix of size 'K1 x K2'. Assuming that can be done, denote that with B. Then we can compute B - t and we have each entry of (b - t_k2). Assuming we can even do this, the only idea I have is to replicate each constant c_k into a vector of that number as in c_k_vec = [c_k, ... c_k] and then do a element wise multiplication of those matrices. It's clear that B should:
B = repmat(b, [1,K2]);
and
B - t
accomplishes part of the task...but its not clear to me how to produce the matrix where the columns are c_k_vec = [c_k, ... c_k] in one line without looping. The idea is that a vector c matches with each column B - t and we want to multiply each column of B - t by the entries in the vector x.
Maybe this isn't possible...
You pretty much answered your question (again :)). You can certainly use repmat on b to duplicate the column vector K2 times horizontally to make the dimensions consistent. However, you have a slight problem with the c matrix as the dimensions are currently incompatible if you want to achieve the computation of the output matrix vectorized.
If I understand your problem correctly, each row of your output should be multiplied by the corresponding row of c. In that case, it's simply another case of running repmat on c, but duplicate this vector K1 times.
Concretely, you can do this:
a_k2 = repmat(c.', K1, 1) .* (repmat(b, 1, K2) - t);
Take note that I had to transpose c because you said it was a K2 x 1 vector. To make sure that there are matches in size, I transposed this so that it becomes 1 x K2, and repmat'ing will replicate this matrix to become K1 x K2 to match with the intermediate result.
However, this looks a bit inelegant. I encourage you to take advantage of bsxfun, which does the replication under the hood:
a_k2 = bsxfun(#times, c.', bsxfun(#minus, b, t));
What will be done first is b gets replicated for as many columns as there are t, and then we will multiply this intermediate result by the right c values by replicating the c vector to match up in shape with the intermediate result. The beauty with bsxfun is that you don't need to know how many times you need to repmat something. bsxfun figures that out for you.
To show that all three statements are equivalent, let's generate some sample data, and run through your for loop, then the two pieces of code I wrote above:
%// Data setup
rng(123);
K1 = 10;
K2 = 12;
t = rand(K1, K2);
b = rand(K1, 1);
c = rand(K2, 1);
%// Your code
for k2=1:K2
t_k2 = t(:,k2); % K1 x 1
c_k2 = c(k2); %// Note - typo here
a_k2(:,k2) = c_k2 * (b - t_k2); % K1 x 1
end
%// Using repmat
a_k2r = repmat(c.', K1, 1) .* (repmat(b, 1, K2) - t);
%// Using bsxfun
a_k2b = bsxfun(#times, c.', bsxfun(#minus, b, t));
a_2k is what is produced from your code and a_k2r, a_k2b are the outputs from the two pieces of code I suggested. If we display them all, we get:
>> a_k2
a_k2 =
Columns 1 through 7
0.1527 0.0905 0.1628 0.7042 0.2768 0.0623 0.1011
-0.0574 -0.0840 -0.3855 -0.1957 0.0905 -0.0491 -0.1620
0.0480 -0.0235 -0.2595 -0.1198 -0.0244 -0.0246 -0.1424
-0.0229 0.0741 -0.0547 0.0228 0.1035 -0.0020 -0.0663
0.1334 0.0812 0.1078 0.4122 0.0350 0.0444 0.0255
0.4098 0.0396 0.3969 0.5813 0.7211 0.0539 0.3857
-0.5287 0.0121 -0.0626 -0.1462 -0.2218 -0.0127 -0.2168
-0.0881 0.0626 0.2019 -0.2849 -0.4143 -0.0093 0.1374
0.2384 0.0444 0.3083 -0.1188 0.2827 -0.0054 0.2625
0.0016 -0.0221 -0.1421 -0.0931 -0.2149 -0.0092 -0.0763
Columns 8 through 12
0.1656 0.2643 0.1098 0.0366 0.1747
-0.1386 -0.2183 -0.4315 -0.0428 -0.0435
-0.0685 -0.1180 -0.0347 0.0174 0.0360
-0.0416 0.0591 -0.1329 0.0363 -0.0918
0.1812 -0.0105 0.1691 0.0541 0.1672
0.0796 0.0640 0.1599 0.0301 0.1280
-0.0612 -0.0450 0.0583 -0.0550 -0.0953
0.0829 0.2347 0.0906 0.0010 0.0127
0.1338 0.2263 0.3101 -0.0044 0.2388
-0.0616 -0.0017 0.0279 0.0009 -0.1763
>> a_k2b
a_k2b =
Columns 1 through 7
0.1527 0.0905 0.1628 0.7042 0.2768 0.0623 0.1011
-0.0574 -0.0840 -0.3855 -0.1957 0.0905 -0.0491 -0.1620
0.0480 -0.0235 -0.2595 -0.1198 -0.0244 -0.0246 -0.1424
-0.0229 0.0741 -0.0547 0.0228 0.1035 -0.0020 -0.0663
0.1334 0.0812 0.1078 0.4122 0.0350 0.0444 0.0255
0.4098 0.0396 0.3969 0.5813 0.7211 0.0539 0.3857
-0.5287 0.0121 -0.0626 -0.1462 -0.2218 -0.0127 -0.2168
-0.0881 0.0626 0.2019 -0.2849 -0.4143 -0.0093 0.1374
0.2384 0.0444 0.3083 -0.1188 0.2827 -0.0054 0.2625
0.0016 -0.0221 -0.1421 -0.0931 -0.2149 -0.0092 -0.0763
Columns 8 through 12
0.1656 0.2643 0.1098 0.0366 0.1747
-0.1386 -0.2183 -0.4315 -0.0428 -0.0435
-0.0685 -0.1180 -0.0347 0.0174 0.0360
-0.0416 0.0591 -0.1329 0.0363 -0.0918
0.1812 -0.0105 0.1691 0.0541 0.1672
0.0796 0.0640 0.1599 0.0301 0.1280
-0.0612 -0.0450 0.0583 -0.0550 -0.0953
0.0829 0.2347 0.0906 0.0010 0.0127
0.1338 0.2263 0.3101 -0.0044 0.2388
-0.0616 -0.0017 0.0279 0.0009 -0.1763
>> a_k2r
a_k2r =
Columns 1 through 7
0.1527 0.0905 0.1628 0.7042 0.2768 0.0623 0.1011
-0.0574 -0.0840 -0.3855 -0.1957 0.0905 -0.0491 -0.1620
0.0480 -0.0235 -0.2595 -0.1198 -0.0244 -0.0246 -0.1424
-0.0229 0.0741 -0.0547 0.0228 0.1035 -0.0020 -0.0663
0.1334 0.0812 0.1078 0.4122 0.0350 0.0444 0.0255
0.4098 0.0396 0.3969 0.5813 0.7211 0.0539 0.3857
-0.5287 0.0121 -0.0626 -0.1462 -0.2218 -0.0127 -0.2168
-0.0881 0.0626 0.2019 -0.2849 -0.4143 -0.0093 0.1374
0.2384 0.0444 0.3083 -0.1188 0.2827 -0.0054 0.2625
0.0016 -0.0221 -0.1421 -0.0931 -0.2149 -0.0092 -0.0763
Columns 8 through 12
0.1656 0.2643 0.1098 0.0366 0.1747
-0.1386 -0.2183 -0.4315 -0.0428 -0.0435
-0.0685 -0.1180 -0.0347 0.0174 0.0360
-0.0416 0.0591 -0.1329 0.0363 -0.0918
0.1812 -0.0105 0.1691 0.0541 0.1672
0.0796 0.0640 0.1599 0.0301 0.1280
-0.0612 -0.0450 0.0583 -0.0550 -0.0953
0.0829 0.2347 0.0906 0.0010 0.0127
0.1338 0.2263 0.3101 -0.0044 0.2388
-0.0616 -0.0017 0.0279 0.0009 -0.1763
... and for some bonus, let's compare the absolute difference between the original matrix (your code) and each one of these and find the maximum deviation:
>> format long g
>> max_diff1 = max(abs(a_k2(:) - a_k2r(:)))
max_diff1 =
0
>> max_diff2 = max(abs(a_k2(:) - a_k2b(:)))
max_diff2 =
0
As you can see, if we took an element wise subtraction between how you computed a_2k with what I produced with repmat and bsxfun, it says that the largest element in difference between the two matrices is 0.... so, we can see that there is no difference between the source and either of the alternative approaches.
I'm not sure where c_k_vec came from, but vector multiplication can very easily be done for each element through .* so if you have the (b-t_k2) part solved, multiplying the constant should be pretty simple with the .*

understand how reshape function forms matrix

let us consider following matrix for illustration
A=rand(6,3)
A =
0.3500 0.8308 0.7537
0.1966 0.5853 0.3804
0.2511 0.5497 0.5678
0.6160 0.9172 0.0759
0.4733 0.2858 0.0540
0.3517 0.7572 0.5308
to total we have 6*3=18 element,after apply reshape function
reshape(A,2,9)
ans =
0.3500 0.2511 0.4733 0.8308 0.5497 0.2858 0.7537 0.5678 0.0540
0.1966 0.6160 0.3517 0.5853 0.9172 0.7572 0.3804 0.0759 0.5308
clearly if we look on original array,then we can easily see that rows of these new matrix is same as
B=A(:)'
B =
Columns 1 through 9
0.3500 0.1966 0.2511 0.6160 0.4733 0.3517 0.8308 0.5853 0.5497
Columns 10 through 18
0.9172 0.2858 0.7572 0.7537 0.3804 0.5678 0.0759 0.0540 0.5308
>> B(1:2:18)
ans =
0.3500 0.2511 0.4733 0.8308 0.5497 0.2858 0.7537 0.5678 0.0540
so in reshape(A,m,n) where m*n must be total element,m represent starting form first element in first column,increment in columns until nth element?also when i have tried
reshape(A,3,4)
Error using reshape
To RESHAPE the number of elements must not change.
it gives me error,so whenever i choose n,m must be number of elements in array divided by n right?thanks in advance
Matlab stores its matrices column-wise. This means internally it basically is just one array where all the columns are concatenated. The shape of the matrix is stored seperately.
I don't quite understand your last question, because your matrix A has 18 entries, but you try to reshape it into a matrix with 3*4=12 entries
I hope this helped you
Reshape is for reordering elements as explained in #alex answer (and of course the number of elements must not change!). If you want to resize a matrix, use indexing:
Examples
A = rand(6,6) % Start matrix
A =
0.0113 0.5362 0.3510 0.7220 0.2084 0.8344
0.5013 0.9770 0.5221 0.5743 0.8442 0.8102
0.1214 0.0390 0.9594 0.1385 0.9038 0.6081
0.2480 0.9165 0.1986 0.3692 0.5135 0.6154
0.3631 0.9843 0.3697 0.5964 0.6437 0.6901
0.9978 0.8182 0.1990 0.8273 0.6811 0.2464
Use '[]' to remove lines or columns
A(2:3, :) = [] % This removes 2nd and 3rd lines
A(:, [2 5]) = [] % This further removes 2nd and 5th columns
A =
0.0113 0.3510 0.7220 0.8344
0.2480 0.1986 0.3692 0.6154
0.3631 0.3697 0.5964 0.6901
0.9978 0.1990 0.8273 0.2464
Use indexing for zero padding
AA = zeros(6, 6); % Build larger matrix the size you want ...
AA([1 2 4 6], [2 3 5 6]) = A % Place elements of `A` inside `AA` as you wish ...
AA =
0.0000 0.0113 0.3510 0.0000 0.7220 0.8344
0.0000 0.2480 0.1986 0.0000 0.3692 0.6154
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.3631 0.3697 0.0000 0.5964 0.6901
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.9978 0.1990 0.0000 0.8273 0.2464
With indexing you can also play around to create bigger/smaller matrices.
A([4 4 1 1 2 3], end:-1:1)
ans =
0.2464 0.8273 0.1990 0.9978
0.2464 0.8273 0.1990 0.9978
0.8344 0.7220 0.3510 0.0113
0.8344 0.7220 0.3510 0.0113
0.6154 0.3692 0.1986 0.2480
0.6901 0.5964 0.3697 0.3631

Extract data with conditions from matrix in Matlab

I have a matrix in Matlab where each row looks something like this:
1 3 0.112 5.31275 4.61924 -6.50652
And I want to extract to different matrices according to the value presented in the first column. I know how to do this with for loops but I have too many points to leave this running for whatever time it will take to analyze everything. Is there an easier way to do this?
Here is my code with for loops:
accelerometer = 1;
gyroscope = 0;
a = 1;
g = 1;
for i = 1:size(raw,1)
if raw(i,1) == accelerometer
accelData(a,:) = raw(i,2:6);
a = a+1;
else
if raw(i,1) == gyroscope
gyroData(g,:) = raw(i,2:6);
g = g+1;
end
end
end
Thanks!
I belive something like the code below could be used:
%# Create dummy matrix
raw = [rand(10,1)>=0.5 rand(10,5)];
accelerometer = 1;
gyroscope = 0;
accelData = raw(raw(:,1)==accelerometer,:)
gyroData = raw(raw(:,1)==gyroscope,:)
Example output:
accelData =
1.0000 0.3517 0.0759 0.1622 0.4505 0.1067
1.0000 0.5853 0.5308 0.3112 0.2290 0.0046
1.0000 0.9172 0.9340 0.1656 0.1524 0.8173
1.0000 0.3804 0.0119 0.6892 0.0782 0.2599
gyroData =
0 0.8308 0.0540 0.7943 0.0838 0.9619
0 0.5497 0.7792 0.5285 0.9133 0.7749
0 0.2858 0.1299 0.6020 0.8258 0.8687
0 0.7572 0.5688 0.2630 0.5383 0.0844
0 0.7537 0.4694 0.6541 0.9961 0.3998
0 0.5678 0.3371 0.7482 0.4427 0.8001

Is there a way to return many columns with linear indexing in MatLab?

Suppose a 3-D matrix :
>> a = rand(3,4,2)
a(:,:,1) =
0.1067 0.7749 0.0844 0.8001
0.9619 0.8173 0.3998 0.4314
0.0046 0.8687 0.2599 0.9106
a(:,:,2) =
0.1818 0.1361 0.5499 0.6221
0.2638 0.8693 0.1450 0.3510
0.1455 0.5797 0.8530 0.5132
I use linear indexing to have many element at a time:
>> index1 = [1 ; 2 ; 1 ; 3];
>> index2 = [1 ; 4 ; 2 ; 3];
>> index3 = [1 ; 1 ; 2 ; 1];
>> indices = sub2ind(size(a), index1, index2, index3)
>> a(indices)
ans =
0.1067
0.4314
0.1361
0.2599
I would like to do the same thing, put return all the values of the first dimensions. The size of this dimension may vary. The return should be, in that case:
>> indices = sub2ind(size(a), ??????, index2, index3);
>> a(indices)
ans =
0.1067 0.9619 0.0046 % a(:,1,1)
0.8001 0.4314 0.9106 % a(:,4,1)
0.1361 0.8693 0.5797 % a(:,2,2)
0.0844 0.3998 0.2599 % a(:,3,1)
Any way to do that in MatLab?
ind1 = repmat((1:size(a,1)),length(index2),1);
ind2 = repmat(index2,1,size(a,1));
ind3 = repmat(index3,1,size(a,1));
indices = sub2ind(size(a),ind1,ind2,ind3)
indices =
1 2 3
10 11 12
16 17 18
7 8 9
a(indices)
ans =
0.1067 0.9619 0.0046
0.8001 0.4314 0.9106
0.1361 0.8693 0.5797
0.0844 0.3998 0.2599
You can get the result you want by doing linear indexing on the last two dimensions separate from the first two dimensions. Even in the 3d data block where you expect to reference by a(:,:,:) you can reference by a(:) (as you know) or a(:,:). The following code finds the sub2ind for the last two dimensions then just repeats them using meshgrid. This ends up being very similar to the solution proposed by #tmpearce but explicitly shows the semi-linear indexing and uses meshgrid instead of repmat:
dim1 = 3;
dim2 = 4;
dim3 = 2;
rand('seed', 1982);
a = round(rand(dim1,dim2,dim3)*10)
% index1 = :
index2 = [1 ; 4 ; 2 ; 3];
index3 = [1 ; 1 ; 2 ; 1];
indices = sub2ind([dim2 dim3], index2, index3)
a(:, indices) % this is a valid answer
[X,Y] = meshgrid(1:dim1, indices)
indices2 = sub2ind([dim1, dim2*dim3], X,Y);
a(indices2) % this is also a valid answer, with full linear indexing