From osklyar at ebi.ac.uk  Thu Mar 17 16:16:53 2005
From: osklyar at ebi.ac.uk (Oleg Sklyar)
Date: Thu Mar 17 16:17:08 2005
Subject: [Rd] .Call - applying setAttrib(x, R_DimSymbol, s) to a matrix
	being an element of a list
In-Reply-To: <Pine.LNX.4.61.0503170719060.14118@gannet.stats>
References: <42386FA6.7040800@ebi.ac.uk>
	<34C019CA-160A-4AFF-B622-CFB95201F5AD@r-project.org>
	<4238DEBD.1090805@ebi.ac.uk>
	<Pine.LNX.4.61.0503170719060.14118@gannet.stats>
Message-ID: <42399F65.6020801@ebi.ac.uk>

Thanks a lot for your comments. In fact I had an idea that maybe it is a 
pointer that is transferred after Simon's yesterday's commnent. So 
generally I should always allocVector for imgSize before passing it and 
just let the garbage collector to clean them afterwards if I understand 
right.

Best regards
Oleg

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



Prof Brian Ripley wrote:

> 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
>>
>>
>


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