MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Compiling SingularValueDecomposition

  • To: mathgroup at smc.vnet.net
  • Subject: [mg89855] Re: Compiling SingularValueDecomposition
  • From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
  • Date: Mon, 23 Jun 2008 02:45:32 -0400 (EDT)
  • Organization: The Open University, Milton Keynes, UK
  • References: <g3ihod$fc9$1@smc.vnet.net> <g3kunv$7e2$1@smc.vnet.net>

Jean-Marc Gulliet wrote:

> Frank Hu wrote:
>> Hi, group,
>>
>> I'm trying to speed up a piece of code that uses  
>> SingularValueDecomposition by compiling it.  But I couldn't get it to  
>> compile.  For a simple demonstration, try
>>
>> fx=Compile[{{x, _Real, 2}},  SingularValueDecomposition[x],  
>> {{SingularValueDecomposition, _Real, 3}}]
>>
>> and fx[[4]] is
>> {{1, 5}, {54, Function[{x}, SingularValueDecomposition[x]], 3, 2, 0,  
>> 3, 2, 1}, {2}}
>>
>> The "Function" there tells fx wasn't compiled successfully.  Calling  
>> fx[{{1., 2.}, {3., 4.}}] will generate the following warnings
>>
>> CompiledFunction::cfte: Compiled expression {<<1>>} should be a rank  
>> 2 tensor of machine-size real numbers. >>
>> CompiledFunction::cfex: Could not complete external evaluation at  
>> instruction 2; proceeding with uncompiled evaluation. >>
> 
> Hi Frank,
> 
> You must write the intermediate functions as full expressions, that is 
> SingularValueDecomposition[_] rather than just 
> SingularValueDecomposition. The following works as expected:
> 
> 
> In[1]:= fx = Compile[{{x, _Real, 2}}, SingularValueDecomposition[x],
>       {{SingularValueDecomposition[_], _Real, 3}}]
> fx[[4]]
> fx[{{1., 2.}, {3., 4.}}]
> 
> Out[1]= CompiledFunction[]
> 
> Out[2]= {{1, 5}, {54, Function[{x}, SingularValueDecomposition[x]], 3, 
> 2, 0, 3,
> 
>     3, 1}, {2}}
> 
> Out[3]= {{{-0.404554, 0.914514}, {-0.914514, -0.404554}},
> 
>    {{5.46499, 0.}, {0., 0.365966}},
> 
>    {{-0.576048, -0.817416}, {-0.817416, 0.576048}}}

Note that the code above will failed to compiled when the input is not a 
*square* matrix because Mathematica expects the returned value to be a 
*full* array. (In a full array all parts at a particular level must be 
lists of the same length.) When you feed the function fx with a 
rectangular (non square) matrix, the result returned by 
SingularValueDecomposition is a list of unequal-length elements.

In[1]:= fx = Compile[{{x, _Real, 2}},
   SingularValueDecomposition[x],
      {{SingularValueDecomposition[_], _Real, 3}}]
f1 = fx[{{1., 2.}, {3., 4.}}]
f2 = fx[{{1., 2.}, {3., 4.}, {5., 6.}}]
f3 = fx[{{1., 2., 3.}, {4., 5., 6.}}]
({ArrayDepth[#1], ArrayQ[#1]} & ) /@ {f1, f2, f3}

Out[1]= CompiledFunction[]

Out[2]= {{{-0.404554, 0.914514}, {-0.914514, -0.404554}},

   {{5.46499, 0.}, {0., 0.365966}},

   {{-0.576048, -0.817416}, {-0.817416, 0.576048}}}

During evaluation of In[1]:= CompiledFunction::cfte:Compiled expression 
{<<1>>} should be a rank 3 tensor \
of machine-size real numbers. >>

During evaluation of In[1]:= CompiledFunction::cfex:Could not complete 
external evaluation at instruction \
2; proceeding with uncompiled evaluation. >>

Out[3]= {{{-0.229848, 0.883461, 0.408248}, {-0.524745, 0.240782, 
-0.816497},

    {-0.819642, -0.401896, 0.408248}},

   {{9.52552, 0.}, {0., 0.514301}, {0., 0.}},

   {{-0.619629, -0.784894}, {-0.784894, 0.619629}}}

During evaluation of In[1]:= CompiledFunction::cfte:Compiled expression \
{{{-0.386318,-0.922366},{-0.922366,0.386318}},{{<<1>>},<<1>>},<<1>>} 
should \
be a rank 3 tensor of machine-size real numbers. >>

During evaluation of In[1]:= CompiledFunction::cfex:Could not complete 
external evaluation at instruction \
2; proceeding with uncompiled evaluation. >>

Out[4]= {{{-0.386318, -0.922366}, {-0.922366, 0.386318}},

   {{9.50803, 0., 0.}, {0., 0.77287, 0.}},

   {{-0.428667, 0.805964, 0.408248}, {-0.566307, 0.112382, -0.816497},

    {-0.703947, -0.581199, 0.408248}}}

Out[5]= {{3, True}, {1, False}, {1, False}}


On the other hand, if we use a function such as SingularValueList, which 
returns a one-dimensional vector, the compilation works with rectangular 
inputs.

In[6]:= gx = Compile[{{x, _Real, 2}},
   SingularValueList[x],
      {{SingularValueList[_], _Real, 1}}]
g1 = gx[{{1., 2.}, {3., 4.}}]
g2 = gx[{{1., 2.}, {3., 4.}, {5., 6.}}]
g3 = gx[{{1., 2., 3.}, {4., 5., 6.}}]
({ArrayDepth[#1], ArrayQ[#1]} & ) /@ {g1, g2, g3}

Out[6]= CompiledFunction[]

Out[7]= {5.46499, 0.365966}

Out[8]= {9.52552, 0.514301}

Out[9]= {9.50803, 0.77287}

Out[10]= {{1, True}, {1, True}, {1, True}}

HTH,
-- Jean-Marc


  • Prev by Date: Re: Mathematica performance improvements
  • Next by Date: FullGraphics[] does not work properly
  • Previous by thread: Re: Compiling SingularValueDecomposition
  • Next by thread: Re: WorldPlot and excel data