From ripley at stats.ox.ac.uk  Thu Mar 17 09:46:50 2005
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Thu Mar 17 09:46:59 2005
Subject: [Rd] .Call - applying setAttrib(x, R_DimSymbol, s) to a matrix
	being an element of a list
In-Reply-To: <4238DEBD.1090805@ebi.ac.uk>
References: <42386FA6.7040800@ebi.ac.uk>
	<34C019CA-160A-4AFF-B622-CFB95201F5AD@r-project.org>
	<4238DEBD.1090805@ebi.ac.uk>
Message-ID: <Pine.LNX.4.61.0503170719060.14118@gannet.stats>

On Thu, 17 Mar 2005, Oleg Sklyar wrote:

> Dear Simon,
>
>> you gave us only a fragment of your code, so I can only guess what the 
> problem is:
>
>> What is imgSize? The behavior you describe seems as if you re-using the 
> imgSize SEXP in all elements.
>> AFAIR in your case setAttrib doesn't copy the value, so you need to do so 
> yourself (or alloc new dim array
>> for each element).
>
> Sorry, it is always a tradeoff - either to explain or put a relatively large 
> code, which also uses non-standard libraries making the code difficult to 
> read. imgSize values are reset in between: see the full code below. The SEXP 
> pointer imgSize stays in tact, that's true, but its values are changed (the 
> problem is, they are always the last in the row). I.e. if I have 3 images 
> 40x20, 200x100 and 150x75 I will get three matrices of 150x75, but if I omit 
> setAtrib and return vectors I get vectors of different length.

So, as Simon says, you need to create separate objects for the dimensions 
of each matrix, not share the object.  It is the object pointed to by 
imgSize you have attached as the dimensions, not the values.

BTW, setAttrib(element, R_DimSymbol, imgSize) just calls dimgets(element, 
imgSize), so I would have used the latter directly.

I believe you do not have three matrices of 150x75, rather a vector of 
length 40*20 with an inconsistent dim attribute of c(150, 75), etc.

>
> Oleg
>
> SEXP load2DImages(SEXP fileNames) {
>   int nFiles = LENGTH(fileNames);
>   std::cout << "Loading " << nFiles << " files..." << std::endl;
>   // SEXP result = allocList(nFiles);
>   SEXP result = allocVector(VECSXP, nFiles);
>   PROTECT(result);
>   SEXP imgSize = allocVector(INTSXP, 2);
>   PROTECT(imgSize);
>   TRGB2DImage::Pointer image;
>   TRGB2DReader::Pointer reader = TRGB2DReader::New();
>   TRGB2DImage::SizeType size;      TRGB2DImage::IndexType pixIndex;
>   for (int i = 0; i < nFiles; i++) {
>       try {
>           char *filename = CHAR(asChar(VECTOR_ELT(fileNames, i)));
>           std::cout << std::endl << "Loading image file " << filename << 
> "... ";
>           reader->SetFileName(filename);
>           reader->Update();
>           image = reader->GetOutput();
>       } catch(...) {
>           std::cout << "failed!";
>           continue;
>       }
>       std::cout << std::endl;
>       size = image->GetLargestPossibleRegion().GetSize();
>       INTEGER(imgSize)[0] = size[1];
>       INTEGER(imgSize)[1] = size[0];
>       std::cout << size[0] << " x " << size[1] << std::endl;
>       SET_VECTOR_ELT(result, i, allocVector(INTSXP, size[0] * size[1]));
>       SEXP element = VECTOR_ELT(result, i);
>       for (int ix = 0; ix < size[0]; ix++) {
>           pixIndex[0] = ix;
>           for (int iy = 0; iy < size[1]; iy++) {
>               pixIndex[1] = iy;
>               INTEGER(element)[size[1] * ix + iy] = 
> getIntRGBColour(image->GetPixel(pixIndex));
>           }
>       }
>       setAttrib(element, R_DimSymbol, imgSize);
>   }
>   UNPROTECT(2);
>   if (nFiles == 1)
>       return VECTOR_ELT(result, 0);
>   else
>       return result;
> }
>
> Dr Oleg Sklyar
> European Bioinformatics Institute
> Wellcome Trust Genome Campus
> Hinxton, Cambridge, CB10 1SD
> England
> phone/fax  +44(0)1223 49 4478/4468
> e-mail osklyar@ebi.ac.uk
>
>
>
> Simon Urbanek wrote:
>
>> Oleg,
>> 
>> you gave us only a fragment of your code, so I can only guess what the 
>> problem is:
>> 
>> On Mar 16, 2005, at 12:40 PM, Oleg Sklyar wrote:
>> 
>>> // converting element into a matrix
>>> setAttrib(element, R_DimSymbol, imgSize);
>> 
>> 
>> What is imgSize? The behavior you describe seems as if you re-using the 
>> imgSize SEXP in all elements. AFAIR in your case setAttrib doesn't copy the 
>> value, so you need to do so yourself (or alloc new dim array for each 
>> element).
>> 
>> Cheers,
>> Simon
>> 
>> 
>> 
>
> ______________________________________________
> R-devel@stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

-- 
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595


[Rd] .Call - applying setAttrib(x, R_DimSymbol, s) to a matrix being an element of a list
Prof Brian Ripley