Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Indexing

Subject: Indexing

From: Iain

Date: 29 Oct, 2010 14:42:13

Message: 1 of 9

Hey guys,

I'm still trying to get my head round indexing and was wondering if somebody could help with something.

Taking this matrix as an example:

sampleMatrix = [NaN NaN 3; 12 9 NaN]

I want to set all NaNs from the 2nd and 3rd columns to 0.1, so I want something like this:

idx = isnan(sampleMatrix(:, 2:3))
sampleMatrix(idx) = 0.1

Except of course that doesn't work because the index that's created is on a small matrix than the sampleMatrix. So really I want something like:

idx = isnan(sampleMatrix(:, 2:3))
sampleMatrix(:, 2:3)(idx) = 0.1

Except obviously that syntax just doesn't work in Matlab, but hopefully you know what I mean.

I know in this trivial example there are several ways to do it, but I'm going to be dealing with absolutely enormous matrices with variable numbers of columns, and indeed the columns in which I'm looking for NaNs might be in the middle of the matrix and may not even be beside each other.

Is there an elegant way to what I'm describing.

I suspect that's not as clear as it might be. Hopefully you clever chaps will be able to work out what I mean.

Thanks
Iain

Subject: Indexing

From: Sean

Date: 29 Oct, 2010 14:53:03

Message: 2 of 9


> sampleMatrix = [NaN NaN 3; 12 9 NaN]
>
> I want to set all NaNs from the 2nd and 3rd columns to 0.1, so I want something like this:
>
> idx = isnan(sampleMatrix(:, 2:3))
> sampleMatrix(idx) = 0.1
>
> Except of course that doesn't work because the index that's created is on a small matrix than the sampleMatrix. So really I want something like:
>
> idx = isnan(sampleMatrix(:, 2:3))
> sampleMatrix(:, 2:3)(idx) = 0.1
>
> Except obviously that syntax just doesn't work in Matlab, but hopefully you know what I mean.
>
> I know in this trivial example there are several ways to do it, but I'm going to be dealing with absolutely enormous matrices with variable numbers of columns, and indeed the columns in which I'm looking for NaNs might be in the middle of the matrix and may not even be beside each other.
>
> Is there an elegant way to what I'm describing.
>
> I suspect that's not as clear as it might be. Hopefully you clever chaps will be able to work out what I mean.


partofsample = sampleMatrix(:,2:3);
partofsample(isnan(partofsample)) = 0.1;
sampleMatric(:,2:3) = partofsample;

%SCd

Subject: Indexing

From: Iain

Date: 29 Oct, 2010 15:57:08

Message: 3 of 9

Thanks Sean.

I'm guessing there's no way to do it without copying that of the matrix though?

These are going to be seriously massive matrices and we need to squeeze every ounce of efficiency out of this that we can.

I think I'm probably looking for efficiency that's just not there...

Thanks
Iain


"Sean " <sean.dewolski@nospamplease.umit.maine.edu> wrote in message <iaen4f$6kn$1@fred.mathworks.com>...
>
> > sampleMatrix = [NaN NaN 3; 12 9 NaN]
> >
> > I want to set all NaNs from the 2nd and 3rd columns to 0.1, so I want something like this:
> >
> > idx = isnan(sampleMatrix(:, 2:3))
> > sampleMatrix(idx) = 0.1
> >
> > Except of course that doesn't work because the index that's created is on a small matrix than the sampleMatrix. So really I want something like:
> >
> > idx = isnan(sampleMatrix(:, 2:3))
> > sampleMatrix(:, 2:3)(idx) = 0.1
> >
> > Except obviously that syntax just doesn't work in Matlab, but hopefully you know what I mean.
> >
> > I know in this trivial example there are several ways to do it, but I'm going to be dealing with absolutely enormous matrices with variable numbers of columns, and indeed the columns in which I'm looking for NaNs might be in the middle of the matrix and may not even be beside each other.
> >
> > Is there an elegant way to what I'm describing.
> >
> > I suspect that's not as clear as it might be. Hopefully you clever chaps will be able to work out what I mean.
>
>
> partofsample = sampleMatrix(:,2:3);
> partofsample(isnan(partofsample)) = 0.1;
> sampleMatric(:,2:3) = partofsample;
>
> %SCd

Subject: Indexing

From: Sean

Date: 29 Oct, 2010 16:21:04

Message: 4 of 9

"Iain " <itrotter@hometrack.co.uk> wrote in message <iaeqsk$grk$1@fred.mathworks.com>...
> Thanks Sean.
>
> I'm guessing there's no way to do it without copying that of the matrix though?
>
> These are going to be seriously massive matrices and we need to squeeze every ounce of efficiency out of this that we can.
>
> I think I'm probably looking for efficiency that's just not there...
>

You could loop over the column indexes you want to keep so it's not copying all of it at once:
%
for ii = [2 3]
   partofsample = A(:,ii);
   partofsample(isnan(partofsample)) = 0.1;
   A(:,ii) = partofsample;
end

Subject: Indexing

From: Matt Fig

Date: 29 Oct, 2010 16:58:04

Message: 5 of 9

Another approach:

% Data
S = [NaN NaN 3; 12 9 NaN]

% Engine
idx = [false(size(S(:,1))) isnan(S(:, 2:3))]
S(idx) = .1

Subject: Indexing

From: James Tursa

Date: 29 Oct, 2010 17:30:12

Message: 6 of 9

"Iain " <itrotter@hometrack.co.uk> wrote in message <iaemg5$osk$1@fred.mathworks.com>...
> Hey guys,
>
> I'm still trying to get my head round indexing and was wondering if somebody could help with something.
>
> Taking this matrix as an example:
>
> sampleMatrix = [NaN NaN 3; 12 9 NaN]
>
> I want to set all NaNs from the 2nd and 3rd columns to 0.1, so I want something like this:
>
> idx = isnan(sampleMatrix(:, 2:3))
> sampleMatrix(idx) = 0.1
>
> Except of course that doesn't work because the index that's created is on a small matrix than the sampleMatrix. So really I want something like:
>
> idx = isnan(sampleMatrix(:, 2:3))
> sampleMatrix(:, 2:3)(idx) = 0.1
>
> Except obviously that syntax just doesn't work in Matlab, but hopefully you know what I mean.
>
> I know in this trivial example there are several ways to do it, but I'm going to be dealing with absolutely enormous matrices with variable numbers of columns, and indeed the columns in which I'm looking for NaNs might be in the middle of the matrix and may not even be beside each other.
>
> Is there an elegant way to what I'm describing.
>
> I suspect that's not as clear as it might be. Hopefully you clever chaps will be able to work out what I mean.
>

One thing MATLAB is not very good at is large array slicing operations in loops because that necessitates data copying at each iteration. You can easily spend 90% or more of your time just doing the slicing and data copying and not much time doing the actual needed work. These are the cases that often can be better done in a mex routine since you can get at the array slice data directly without copying the data first. Your case seems to be a classic example of this. Here is a simple mex routine that does what you ask. It has *no* argument checking and it operates in-place on the input matrix, so mis-use can easily bomb MATLAB. If you need to make it robust for argument checking let me know. To mex it simply issue this command at the MATLAB prompt:

mex setnancol.c

James Tursa

------------------------------------------------------------------------------------------------

/* File: setnancol.c */
/* Programmer: James Tursa */
/* Calling sequence: setnancol(A,COLS,VALUE) */
/* A = a double 2D matrix */
/* COLS = a double vector of column indexes */
/* VALUE = a value to replace with */
/* setnancol sets all NaN values in the columns
 * specified by COLS to VALUE */
/* Works in-place on the matrix A */

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    mwSize m, n, i, j, k, c;
    double *pr, *d, *x;
    double value;
    
    pr = mxGetPr(prhs[0]);
    m = mxGetM(prhs[0]);
    n = mxGetN(prhs[0]);
    c = mxGetNumberOfElements(prhs[1]);
    x = mxGetPr(prhs[1]);
    value = mxGetScalar(prhs[2]);
    for( i=0; i<c; i++ ) {
        k = x[i];
        if( k >= 1 && k <= n ) {
            d = pr + (k-1) * m;
            for( j=0; j<m; j++ ) {
                if( mxIsNaN(d[j]) ) {
                    d[j] = value;
                }
            }
        }
    }
}

Subject: Indexing

From: Iain

Date: 2 Nov, 2010 09:31:03

Message: 7 of 9

Thanks for your help Sean, Matt and James.

I'll do some testing and see which way I think will work best. It's good to have a few different approaches.

I haven't looked at MEX files before. It's a long time since I did C, so this could be interesting :)

Thanks guys. I really appreciate it!

Subject: Indexing

From: Jos (10584)

Date: 2 Nov, 2010 15:52:04

Message: 8 of 9

"Iain " <itrotter@hometrack.co.uk> wrote in message <iaemg5$osk$1@fred.mathworks.com>...
* SNIP ... setting Nans another value, excluding a column

here is a simple and straightforward solution

M = [NaN NaN 3; 12 9 NaN]
q = isnan(M)
q(:,1) = false % exclude column 1
M(q) = rv

hth
Jos

Subject: Indexing

From: Iain

Date: 16 Nov, 2010 11:33:06

Message: 9 of 9

Thanks Jos. That is, as you say, extremely simple and straighforward!

Cheers
I

Tags for this Thread

No tags are associated with this thread.

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.

Contact us