Thread Subject: Reshape?

Subject: Reshape?

From: Vanesa

Date: 29 Sep, 2009 23:35:19

Message: 1 of 10

Hi

let's say i have an upper triagular matrix and i want to repeat each column in such a way that...let me show you an example

I have this column
[1;2;3;4;5]

From that column i wan to get thefollowing result:
[1;2;3;4;5;2;3;4;5;3;4;5;4;5;5]

And I want to do this for every column in the matrix

is there any way to do this without a loop?Reshape, maybe?

I've come up with a way but it involves cell arrays and it is pretty time consuming

I'd appreciate your help

Subject: Reshape?

From: Matt Fig

Date: 30 Sep, 2009 00:05:05

Message: 2 of 10

% Data
V = [1;2;3;4;5];

% Engine
[I,JUNK] = find(tril(ones(length(V)))); % I is what you want.

% OR if you have 2009b, you can (apparently) do this:
[I,~] = find(tril(ones(length(V))));

Subject: Reshape?

From: James Tursa

Date: 30 Sep, 2009 00:25:05

Message: 3 of 10

"Vanesa " <vanesa2455@HOTMAIL.com> wrote in message <h9u5jn$ar7$1@fred.mathworks.com>...
> Hi
>
> let's say i have an upper triagular matrix and i want to repeat each column in such a way that...let me show you an example
>
> I have this column
> [1;2;3;4;5]
>
> From that column i wan to get thefollowing result:
> [1;2;3;4;5;2;3;4;5;3;4;5;4;5;5]
>
> And I want to do this for every column in the matrix
>
> is there any way to do this without a loop?Reshape, maybe?
>
> I've come up with a way but it involves cell arrays and it is pretty time consuming
>
> I'd appreciate your help

I'm not exactly sure from your description if I got it how you want it, but here is a mex routine to do it. Call the file trianglecolumns.c and mex it with this command:

>> mex trianglecolumns.c

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    mwSize i, j, k, m, n;
    double *Col, *col, *tri;
    
    m = mxGetM(prhs[0]);
    n = mxGetN(prhs[0]);
    Col = mxGetPr(prhs[0]);
    plhs[0] = mxCreateDoubleMatrix(m, n*m, mxREAL);
    tri = mxGetPr(plhs[0]);
    for( j=0; j<n; j++ ) {
        for( i=0; i<m; i++ ) {
            col = Col++;
            for( k=i; k<m; k++ ) {
                *tri++ = *col++;
            }
            tri += i;
        }
    }
}


James Tursa

Subject: Reshape?

From: James Tursa

Date: 30 Sep, 2009 00:36:02

Message: 4 of 10

Oops. Looking at Matt's response it looks like I misread the question. You can use this instead:

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    mwSize i, j, k, m, n;
    double *Col, *col, *tri;
    
    m = mxGetM(prhs[0]);
    n = mxGetN(prhs[0]);
    Col = mxGetPr(prhs[0]);
    plhs[0] = mxCreateDoubleMatrix(n * (m * (m+1))/2, 1, mxREAL);
    tri = mxGetPr(plhs[0]);
    for( j=0; j<n; j++ ) {
        for( i=0; i<m; i++ ) {
            col = Col++;
            for( k=i; k<m; k++ ) {
                *tri++ = *col++;
            }
        }
    }
}

James Tursa

Subject: Reshape?

From: Matt Fig

Date: 30 Sep, 2009 00:53:01

Message: 5 of 10

Here is a faster (than my first post) MATLAB solution that doesn't leave a useless variable in the workspace:

% If V = 1:N, then:
T = ones((N+1)*N/2,1);
T(cumsum(N:-1:2)+1) = -(N-2:-1:0);
T = cumsum(T)


James, when I call your mex routine with a vector (including 1x1), the vector is just returned.
 
>> creat_tril_c(1:5) % Call JT MEX routine
ans =
     1
     2
     3
     4
     5

Subject: Reshape?

From: Matt Fig

Date: 30 Sep, 2009 01:02:02

Message: 6 of 10

"Matt Fig" <spamanon@yahoo.com> wrote in message
> James, when I call your mex routine with a vector (including 1x1), the vector is just returned.
>
> >> creat_tril_c(1:5) % Call JT MEX routine
> ans =
> 1
> 2
> 3
> 4
> 5

Nevermind, I see:

creat_tril_c((1:5).')

works.

Subject: Reshape?

From: Bruno Luong

Date: 30 Sep, 2009 05:24:01

Message: 7 of 10

c=nchoosek(0:5,2) % 0:5 is [0; v].'
c=c(:,2)

% Bruno

Subject: Reshape?

From: Jos

Date: 30 Sep, 2009 08:29:02

Message: 8 of 10

"Vanesa " <vanesa2455@HOTMAIL.com> wrote in message <h9u5jn$ar7$1@fred.mathworks.com>...
> Hi
>
> let's say i have an upper triagular matrix and i want to repeat each column in such a way that...let me show you an example
>
> I have this column
> [1;2;3;4;5]
>
> From that column i wan to get thefollowing result:
> [1;2;3;4;5;2;3;4;5;3;4;5;4;5;5]
>
> And I want to do this for every column in the matrix
>
> is there any way to do this without a loop?Reshape, maybe?
>
> I've come up with a way but it involves cell arrays and it is pretty time consuming
>
> I'd appreciate your help


Here is a solution:

M = (1:4).' * [1:5] % a matrix
% M = 1 2 3 4 5
% 2 4 6 8 10
% 3 6 9 12 15
% 4 8 12 16 20

idx = nchoose2(0:size(M,1)) ;
R = M(idx(:,2),:)

% as described above
% R = 1 2 3 4 5
% 2 4 6 8 10
% 3 6 9 12 15
% 4 8 12 16 20
% 2 4 6 8 10
% 3 6 9 12 15
% 4 8 12 16 20
% 3 6 9 12 15
% 4 8 12 16 20
% 4 8 12 16 20

NCHOOSE2 (X) is a fast implementation of NCHOOSEK(X,2) and can be found on the File Exchange:
http://www.mathworks.com/matlabcentral/fileexchange/20144

hth
Jos

Subject: Reshape?

From: Sebastiaan

Date: 30 Sep, 2009 09:41:01

Message: 9 of 10

Much of the methods presented here do not work if the column is e.g. [5;4;3;2;1]. This one will:
V=[5;4;3;2;1];
N = length(V);
T = reshape(tril(kron(ones(1,N), V)), N*N, 1);
T(T==0)=[]

However, a simple loop like this:
U = zeros((N+1)*N/2,1);
idx = 1;
for j=1:N
  U(idx:(idx+N-j)) = V(j:N);
  idx = idx + N-j+1
end
is actually faster.

For 100000 runs, the first option takes 11.23 seconds, while the loop is 2.494161 seconds.

It does not seem that there is a trick to do this faster, so there is nothing against a loop, as long as you preallocate the required memory.

If your matrices are large and speed becomes an issue, consider using or writing a mex file.

Sebastiaan


"Vanesa " <vanesa2455@HOTMAIL.com> wrote in message <h9u5jn$ar7$1@fred.mathworks.com>...
> Hi
>
> let's say i have an upper triagular matrix and i want to repeat each column in such a way that...let me show you an example
>
> I have this column
> [1;2;3;4;5]
>
> From that column i wan to get thefollowing result:
> [1;2;3;4;5;2;3;4;5;3;4;5;4;5;5]
>
> And I want to do this for every column in the matrix
>
> is there any way to do this without a loop?Reshape, maybe?
>
> I've come up with a way but it involves cell arrays and it is pretty time consuming
>
> I'd appreciate your help

Subject: Reshape?

From: Vanesa

Date: 30 Sep, 2009 12:01:03

Message: 10 of 10

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <h9uq1h$btq$1@fred.mathworks.com>...
> c=nchoosek(0:5,2) % 0:5 is [0; v].'
> c=c(:,2)
>
> % Bruno

WOW

That was all pretty useful, thank you all for your help!

Tags for this Thread

Everyone's Tags:

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Tag Activity for This Thread
Tag Applied By Date/Time
forloopking Matt Fig 30 Sep, 2009 11:28:18
reshape Sprinceana 30 Sep, 2009 07:34:09
cell array Sprinceana 30 Sep, 2009 07:34:09
reshape cell arays Vanesa 29 Sep, 2009 19:39:04
rssFeed for this Thread

Contact us at files@mathworks.com