bugGNU Octave - Bugs: bug #41674, [octave forge] (image) temporary...

 
 

bug #41674: [octave forge] (image) temporary arrays in imresize are doubles

Submitted by:  Ian Journeaux <ijourneaux>
Submitted on:  Sat 22 Feb 2014 11:30:23 PM UTC  
 
Category: Octave Forge PackageSeverity: 3 - Normal
Priority: 5 - NormalItem Group: Performance
Status: NoneAssigned to: None
Originator Name: Ian JourneauxOpen/Closed: Open
Release: otherOperating System: Any

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Sat 04 Mar 2017 02:56:09 AM UTC, comment #14:

Here is my result after trying some codes. See comment #5.

Xie Rui <xierui>
Thu 15 Dec 2016 12:08:58 PM UTC, comment #13:

This issue seems to be still present in Octave 4.2.0 with image 2.6.1.

(I could find none of the discussed improvements in the repos.)

Hartmut <hardy>
Thu 27 Feb 2014 11:43:02 PM UTC, comment #12:

for me:

>> class(linspace(single(1), 2))

ans = single

although

>> class(linspace(1, 2, single(10)))

ans = double

both as expected, I'd say.

XD and YD may contain fractional values, so we need to check if single precision is sufficient to store these values. their maximum value is not expected to be anywhere near the maximum integer used for indexing.

Felipe G. Nievinski <fgnievinski>
Thu 27 Feb 2014 10:49:58 PM UTC, comment #11:

Another thought...

If you pass single arguments to a function like meshgrid, you get single outputs. But there appears to be no way to tell linspace to generate single values instead of double. Maybe we should consider an extension to Matlab so that if the final argument of linspace may be a character string, either "single" or "double" to specify the type of result that should be produced.

Would that help here?

I'm not sure why you need to use the isequal test. Are you trying to check to see whether single precision is sufficient for the given operations, or whether double is needed because of the range of values?

John W. Eaton <jwe>
Project Administrator
Thu 27 Feb 2014 10:38:52 PM UTC, comment #10:

Thanks John/Filipe I am not sure of the process to submit a patch but will look into. I also use imremap which also uses meshgrid. A similar fix would help there as well.

Ian Journeaux <ijourneaux>
Thu 27 Feb 2014 09:40:54 PM UTC, comment #9:

I think the all() is unnecessary, as in Octave that is implicitly applied to the operands of the && operator.

I'm not a big fan of using clear inside functions as that operates on the symbol table. Simply assigning [] to those variables should release the memory, which I assume is what you want to do.

John W. Eaton <jwe>
Project Administrator
Thu 27 Feb 2014 09:12:38 PM UTC, comment #8:

Thank you for taking the time to report and test it. If you feel like, please consider submitting a patch, based on your experience. Maybe a reusable separate function would help. Thanks.

Felipe G. Nievinski <fgnievinski>
Thu 27 Feb 2014 08:29:41 PM UTC, comment #7:

Atleast in my test cases, I did not have to relax the tolerance so

if(all(isequalAbs(XD, XDs, eps(XDs))) ...
&& all(isequalAbs(YD, YDs, eps(YDs))))

worked. Thanks for the help. There are several other places where meshgrid is used in the image package. This could make it more useful in a memory constrained situation.

Ian Journeaux <ijourneaux>
Thu 27 Feb 2014 08:18:02 PM UTC, comment #6:

Using eps is a great way to accomplish this. IS there a way to set the k value without having to modify the function?

Ian Journeaux <ijourneaux>
Thu 27 Feb 2014 07:52:06 PM UTC, comment #5:

you're right, I was wrong.

although, hard coded tolerance (1e-6) is to be avoided, not least because Octave might be compiled in 64 bits.

I'd go for absolute comparison and take tol = eps(XDs):

if(all(isequalAbs(XD, XDs, k*eps(XDs))) ...
&& all(isequalAbs(YD, YDs, k*eps(YDs))))

if you need to relax the tolerance, then set k = 10.

here's a quick test showing it's viable:

Felipe G. Nievinski <fgnievinski>
Thu 27 Feb 2014 05:07:06 PM UTC, comment #4:

I am not sure your proposal works since it is virtually guaranteed that

all(XD == double(single(XD)))

will not be true due to differences in precision.

I believe you have to factor in what would be an acceptable tolerance for the difference. You can do that with a relative tolerance or an absolute tolerance. My preference is an absolute tolerance but I have the definition for the relative tolerance comparison in case it is useful.

Also my choice of 1e-6 as a tolerance might not be appropriate.

Since you are creating grid coordinates for an interpolation, how many significant digits are required for an accurate interpolation?

If valid, it might be applicable to other places where meshgrid is used as a method of reducing the memory footprint.

I have tested this and it seems to work correctly and is more robust than my original proposal.

XD = linspace (1, inCols, outCols);
YD = linspace (1, inRows, outRows);
XDs = single(XD);
YDs = single(YD);
%# absolute tolerance equality
isequalAbs = @(x,y,tol) (abs(x-y) <= tol );
%# relative tolerance equality
isequalRel = @(x,y,tol) ( abs(x-y) <= ( tol*max(abs(x),abs(y)) + eps) );

if(all(isequalAbs(XD, XDs, 1e-6)) && all(isequalAbs(YD, YDs, 1e-6)))
XD = XDs;
YD = YDs;
endif
clear XDs YDs
[XI, YI] = meshgrid (XD, YD);
im = imremap (im, XI, YI, method);

Ian Journeaux <ijourneaux>
Thu 27 Feb 2014 03:48:36 PM UTC, comment #3:

the tolerance would have to be different for each value.

so yes, you could check for:

all( abs(XD - double(single(XD))) < double(eps(single(XD))) )

but I believe that's equivalent to:

all(XD == double(single(XD)))

Felipe G. Nievinski <fgnievinski>
Thu 27 Feb 2014 02:45:12 PM UTC, comment #2:

For the comparisons to be valid, would you need to specify a tolerance when doing the comparison?

Perhaps something like this?

XD = linspace (1, 10, 12);
YD = linspace (1, 20, 15);
XDs = single(XD);
YDs = single(YD);
%# absolute tolerance equality
isequalAbs = @(x,y,tol) (abs(x-y) <= tol );

if(all(isequalAbs(XD, XDs, 1e-6)) && all(isequalAbs(YD, YDs, 1e-6)))
%if all(XD == XDs) && all(YD == YDs)
XD = XDs;
YD = YDs;
endif
clear XDs YDs

Ian Journeaux <ijourneaux>
Thu 27 Feb 2014 02:58:20 AM UTC, comment #1:

this seems safe to do:

can you test if it works, please.

Felipe G. Nievinski <fgnievinski>
Sat 22 Feb 2014 11:30:23 PM UTC, original submission:

When using imresize on larger images, I end up running out of memory. In the process of troubleshooting this, I noticed that in
imresize there is a call to meshgrid

[XI, YI] = meshgrid (linspace (1, inCols, outCols), linspace (1, inRows, outRows));

im = imremap (im, XI, YI, method);

Since the default cast for XI and YI is double, the memory footprint is very large for large images.

If the arrays XI and YI are cast as single the out of memory condition is avoided.

This is probably not the ideal solution (or even a good solution) but it dramatically reduces the memory footprint of imresize.

Ian

Ian Journeaux <ijourneaux>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by xierui (Posted a comment)
  • -unavailable- added by hardy (Posted a comment)
  • -unavailable- added by jwe (Posted a comment)
  • -unavailable- added by fgnievinski (Posted a comment)
  • -unavailable- added by ijourneaux (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 4 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Sun 13 Aug 2017 01:30:28 PM UTCjweSummaryimage package: temporary arrays in imresize are doubles=>[octave forge] (image) temporary arrays in imresize are doubles
    Sun 23 Feb 2014 05:14:34 PM UTCcarandraugRelease3.8.0=>other
      Operating SystemMicrosoft Windows=>Any
      SummaryTemporary arrays in imresize are doubles=>image package: temporary arrays in imresize are doubles

    Back to the top


    Powered by Savane 3.1-cleanup1