$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r51197 - in sandbox/numeric_bindings/libs/numeric/bindings/tools: . templates templates/computational templates/driver templates/test
From: rutger_at_[hidden]
Date: 2009-02-11 09:02:00
Author: rutger
Date: 2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
New Revision: 51197
URL: http://svn.boost.org/trac/boost/changeset/51197
Log:
Added the Python generator scripts for the BLAS and LAPACK bindings 
Added:
   sandbox/numeric_bindings/libs/numeric/bindings/tools/README.txt   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsdc.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsqr.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gebrd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gelqf.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hetr.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hgeqz.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/larz.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/opmtr.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/org.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/orm.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stedc.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/un.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/cgesv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gees.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geesx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gegv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gels.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelss.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsy.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesdd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gges.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggesx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggglm.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gglse.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevr.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/lalsd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevr.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syev.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevr.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvd.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysv.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysvx.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/lapack.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_lapack.hpp   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/CMakeLists.txt   (contents, props changed)
   sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/test_case.cpp   (contents, props changed)
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/README.txt
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/README.txt	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,25 @@
+
+Using the Python Generator
+----
+To test the python generator, you will need the lapack sources. Make sure the path to your lapack sources is also set in the lapack_parser.py file; look for the variable lapack_src_path.
+
+On a debian-based system, acquiring the sources of BLAS and LAPACK may be achieved by 
+
+$ cd tools
+$ apt-get source blas lapack
+
+this will give you a subdirectory called 'blas-X.X' and 'lapack-X.X.X'. Running the generator may be done by
+
+$ ./lapack_generator
+$ ./blas_generator
+
+from within the tools directory.
+
+To use the compile_test, you need cmake. Please do a 
+
+$ mkdir build
+$ cd build
+$ cmake ..
+$ make
+
+to try to compile all test files. ]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/bindings.py	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,121 @@
+#!/usr/bin/python
+#
+#  Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import re
+
+#
+# This routine actually does what it's named after :-).
+# Changes: 
+# * used regex matching on delimiter instead of .find
+#
+def proper_indent( input_string ):
+  max_chars = 80
+  all_results = []
+  find_delim = re.compile( "([\,\+/]|\|\||>=|std::log\(|work\()[ ]*" )
+  for input_line in input_string.splitlines():
+    result = ''
+    # extra indentation size is 8
+    indentation = len(input_line) - len(input_line.lstrip() ) + 8
+
+    #print "indentation: ", indentation
+
+    indentation_string = ''
+    for i in range(indentation ):
+      indentation_string += ' '
+    #cur_index = input_line.find( ",", 0, -1 ) + 1
+
+    match_delim = find_delim.search( input_line, 0, len(input_line) )
+    if match_delim != None:
+      #print match_delim.end( 0 )- match_delim.start( 0 )
+      cur_index = match_delim.end( 0 )
+    else:
+      cur_index = 0
+
+    prev_index = 0
+    prev_slice = 0
+    prev_indentation = 0
+    while cur_index != 0:
+      if ( (cur_index - prev_slice) > (79-prev_indentation) ):
+        result = result + input_line[ prev_slice : prev_index ].rstrip() + '\n' + indentation_string
+        prev_indentation = indentation
+        prev_slice = prev_index
+      prev_index = cur_index
+      if cur_index != len(input_line):
+        match_delim = find_delim.search( input_line, cur_index+1, len(input_line) )
+        if match_delim != None:
+          #print match_delim.end( 0 )- match_delim.start( 0 )
+          cur_index = match_delim.end( 0 )
+        else:
+          cur_index = 0
+        #cur_index = input_line.find( ",", cur_index+1, -1 ) + 1
+        if cur_index == 0:
+          cur_index = len(input_line)
+      else:
+        cur_index = 0
+    cur_index = len( input_line )
+    result = result + input_line[ prev_slice : cur_index ]
+    all_results += [ result ]
+
+  return "\n".join( all_results ) + "\n"
+
+
+
+#
+# Write the blas.h/lapack_names.h file.
+#
+def write_names_header( global_info_map, group, template_map, dest_file ):
+  parsermode = template_map[ 'PARSERMODE' ].lower()
+  group_keys = group.keys()
+  group_keys.sort()
+  content = ''
+  for g in group_keys:
+    content += '// Variants of ' + g.lower() + '\n'
+    for k in group[ g ]:
+      template = template_map[ parsermode + '_names.h_function' ]
+      template = template.replace( '$SUBROUTINE', k )
+      template = template.replace( '$subroutine', k.lower() )
+      content += template
+    content += '\n'
+
+  result = template_map[ parsermode + '_names.h' ]
+  result = result.replace( "$CONTENT", content )
+  #//result = result.replace( "$PARSERMODE", template_map[ "PARSERMODE" ] )
+
+  open( dest_file, 'wb' ).write( result )
+
+
+#
+# Write the blas.h/lapack.h file
+#
+def write_header( global_info_map, group, template_map, dest_file ):
+  parsermode = template_map[ 'PARSERMODE' ].lower()
+  group_keys = group.keys()
+  group_keys.sort()
+  content = ''
+  for g in group_keys:
+    content += '$INDENT// Variants of ' + g.lower() + '\n'
+    for k in group[ g ]:
+
+      template = template_map[ parsermode + '.h_function' ]
+      arg_list = []
+      for arg in global_info_map[ k ][ 'arguments' ]:
+        arg_list += [ global_info_map[ k ][ 'argument_map' ][ arg ][ 'code' ][ 'lapack_h' ] ]
+
+      template = template.replace( "$SUBROUTINE", k )
+      template = template.replace( "$ARGUMENTS", ", ".join( arg_list ) )
+      content += proper_indent( template )
+
+    content += '\n'
+
+  result = template_map[ parsermode + '.h' ]
+  result = result.replace( "$CONTENT", content )
+  result = result.replace( '$INDENT', '    ' )
+  #result = result.replace( "$PARSERMODE", template_map[ "PARSERMODE" ] )
+
+  open( dest_file, 'wb' ).write( result )
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/blas_generator.py	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,823 @@
+#!/usr/bin/python
+#
+#  Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import netlib
+import bindings
+
+import re, os.path, copy
+from types import StringType
+
+# for debugging purposes
+import pprint
+
+
+global_type_map = { 
+  'CHARACTER': 'char',
+  'LOGICAL': 'logical_t', 
+  'INTEGER': 'integer_t',
+  'REAL': 'float', 
+  'DOUBLE PRECISION': 'double' }
+  
+templates = {}
+
+
+  
+def c_type( name, properties ):
+  m_type_map = global_type_map
+  m_type_map[ 'COMPLEX' ] = 'fcomplex_t'
+  m_type_map[ 'COMPLEX*16' ] = 'dcomplex_t'
+
+  result = m_type_map[ properties[ 'value_type' ] ];
+  if properties[ 'io' ] == [ 'input' ]:
+    result += ' const'
+  result += '*'
+  result += ' ' + name.lower()  # is this really needed?
+  
+  return result
+  
+  
+def cpp_type( name, properties ):
+  m_type_map = global_type_map
+  m_type_map[ 'COMPLEX' ] = 'traits::complex_f'
+  m_type_map[ 'COMPLEX*16' ] = 'traits::complex_d'
+  
+  result = m_type_map[ properties[ 'value_type' ] ]
+  
+  if properties[ 'type' ] == 'scalar':
+    if properties[ 'io' ] == [ 'input' ]:
+      result += ' const'
+    elif properties[ 'io' ] == [ 'external procedure' ]:
+      result += '*'
+    else:
+      result += '&'
+    
+  if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+    result += '*'
+    
+  result += ' ' + name.lower()
+    
+  return result
+  
+def call_c_type( name, properties ):
+  result = ''
+  if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+      result = 'traits::complex_ptr(' + name.lower() + ')'
+    else:
+      result = name.lower()
+  elif properties[ 'type' ] == 'scalar':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+      result = 'traits::complex_ptr(&' + name.lower() + ')'
+    else:
+      result = '&' + name.lower()
+  
+  return result
+  
+
+def call_level0_type( name, properties, arg_map ):
+  result = ''
+  if properties[ 'type' ] == 'matrix':
+    result = "traits::matrix_storage(" + name.lower() + ")"
+  elif properties[ 'type' ] == 'vector':
+    my_name = name.lower()
+    if 'workspace' in properties[ 'io' ]:
+      my_name = 'work.select(' + workspace_type( name, properties ) + '())'
+    result = "traits::vector_storage(" + my_name + ")"
+  elif properties.has_key( 'trait_type' ):
+    if properties[ 'trait_type' ] == 'lda':
+      result = "traits::leading_dimension(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'num_columns':
+      result = "traits::matrix_size2(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'num_rows':
+      result = "traits::matrix_size1(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'size':
+      my_name = properties[ 'trait_of' ].lower()
+      referring_to_properties = arg_map[ properties[ 'trait_of' ] ]
+      if 'workspace' in referring_to_properties[ 'io' ]:
+        my_name = 'work.select(' + workspace_type( properties[ 'trait_of' ].lower(), referring_to_properties ) + \
+                  '())'
+      result = "traits::vector_size(" + my_name + ")"
+    if properties[ 'trait_type' ] == 'uplo':
+      result = "traits::matrix_uplo_tag(" + properties[ 'trait_of' ].lower() + ")"
+  else:
+    result = name.lower()
+  return result
+
+
+def level1_type( name, properties ):
+  result = None
+  if not properties.has_key( 'trait_of' ) and 'workspace' not in properties[ 'io' ]:
+    if properties[ 'type' ] == 'matrix':
+      result = "Matrix" + name + "& " + name.lower()
+    elif properties[ 'type' ] == 'vector':
+      result = "Vector" + name + "& " + name.lower()
+    else:
+      result = cpp_type( name, properties )
+      if properties[ 'value_type' ] == 'REAL':
+        result = result.replace( "float", "real_type" )
+      if properties[ 'value_type' ] == 'DOUBLE PRECISION':
+        result = result.replace( "double", "real_type" )
+  return result
+
+
+def level2_type( name, properties ):
+  result = level1_type( name, properties )
+  if name == 'INFO' and 'output' in properties[ 'io' ]:
+    result = None
+
+  if result != None:
+    if properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+      result = result.replace( "real_type", "typename traits::$TYPEOF_FIRST_TYPENAME" + \
+        "_traits< $FIRST_TYPENAME >::value_type" )
+
+  return result
+
+
+def level1_typename( name, properties ):
+  result = None
+  if 'workspace' not in properties[ 'io' ]:
+    if properties[ 'type' ] == 'matrix':
+      result = "typename Matrix" + name
+    if properties[ 'type' ] == 'vector':
+      result = "typename Vector" + name
+  return result
+
+
+
+def nested_list_args( arg ):
+  print "finding nested list arguments of", arg
+  if type( arg ) == StringType:
+    if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+      return [ None ]
+    else:
+      return [ arg.upper() ]
+  
+  # we are dealing with a list-type, e.g., 
+  # [ '*', [ 'A', 'B' ] ]
+  # [ 'A', 'B' ]
+  result = []
+  if re.compile( '^[A-Z]+$' ).match( arg[0] ) == None:
+    for a in arg[1]:
+      sub_result = nested_list_args( a )
+      if sub_result != [ None ]:
+        for r in sub_result:
+          if r not in result:
+            result.append( r )
+
+  else:
+    for a in arg:
+      result.append( a )
+
+  print "returning ",result
+  return result
+
+
+
+
+def expand_nested_list( arg, arg_map, use_arg_map = True ):
+
+  print "Expanding nested list: ", arg, len(arg)
+  if type( arg ) == StringType:
+    print "Type is string"
+    # .....
+    if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+      return arg
+    else:
+      if use_arg_map:
+        if not arg_map.has_key( arg ):
+          return '?' + arg.upper()
+        else:
+          return arg_map[ arg ][ 'code' ][ 'call_level_0' ]
+      else:
+        return arg.lower()
+    
+  if arg[0] == '()':
+    result = '(' + expand_nested_list( arg[1], arg_map, use_arg_map ) + ')'
+    return result
+    
+  if arg[0] == 'max' or arg[0] == 'min':
+    print "arg1: ", arg[1]
+    result = 'std::' + arg[0] + '('
+    i = 0
+    for a in arg[1]:
+      result += expand_nested_list( a, arg_map, use_arg_map )
+      i += 1
+      if i != len(arg[1]):
+        result += ","
+    result += ')'
+    return result
+  
+  if arg[0] == '*' or arg[0] == '/' or arg[0] == '+' or arg[0] == '-':
+    print "arg1: ", arg[1]
+    arg_list = []
+    for a in arg[1]:
+      arg_list += [ expand_nested_list( a, arg_map, use_arg_map ) ]
+    result = arg[0].join( arg_list )
+    return result
+  
+  print "ERROR: Don't know what to do!!"
+  return 'ERROR'
+
+def level1_assert( name, properties, arg_map ):
+  result = None
+  
+  if properties.has_key( 'assert_char' ):
+    result = "assert( "
+    result_array = []
+    for char in properties[ 'assert_char' ]:
+      result_array += [ call_level0_type( name, properties, arg_map ) + ' == \'' + char + '\'' ]
+    result += " || ".join( result_array )
+    result += " );"
+    
+  if properties.has_key( 'assert_ge' ) and not properties.has_key( 'workspace_query_for' ):
+    result = "assert( " + call_level0_type( name, properties, arg_map ) + " >= " + expand_nested_list( properties[ 'assert_ge' ], arg_map ) + ' );'
+      
+  if 'workspace' in properties[ 'io' ]:
+    min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+    if min_workspace_call == None:
+      min_workspace_call = '$CALL_MIN_SIZE'
+    result = 'assert( traits::vector_size(work.select(' + workspace_type( name, properties ) + '()) >= ' + \
+             'min_size_' + name.lower() + '( ' + min_workspace_call + ' )));'
+  
+  elif properties.has_key( 'assert_size' ):
+    result = "assert( traits::vector_size(" + call_level0_type( name, properties, arg_map ) + ") >= " + \
+      expand_nested_list( properties[ 'assert_size' ], arg_map ) + ' );'
+  
+  return result
+
+
+def call_level1_type( name, properties ):
+  result = None
+  if level1_type( name, properties ) != None:
+    result = name.lower()
+  return result
+
+
+def workspace_type( name, properties ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties[ 'value_type' ] == 'INTEGER':
+      result = 'integer_t'
+    elif properties[ 'value_type' ] == 'LOGICAL':
+      result = 'bool'
+    elif properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+      result = 'real_type'
+    else: 
+      result = 'value_type'
+  return result
+
+
+
+
+def opt_workspace_pre_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      result = workspace_type( name, properties ) + ' opt_size_' + name.lower() + ';'
+    else:
+      min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+      if min_workspace_call == None:
+        min_workspace_call = '$CALL_MIN_SIZE'
+      result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( min_size_' + name.lower() + '( ' + min_workspace_call + ' ) );'
+  return result
+
+
+def opt_workspace_post_type( name, properties ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      if properties['value_type'] == 'INTEGER':
+        result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( opt_size_' + name.lower() + ' );'
+      else:
+        result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( traits::detail::to_int( opt_size_' + name.lower() + ' ) );'
+  return result
+
+
+
+def opt_workspace_query_type( name, properties, arg_map ):
+  result = None
+  if properties.has_key( 'workspace_query_for' ):
+    result = '-1'
+  elif 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      result = '&opt_size_' + name.lower();
+    else:
+      result = 'traits::vector_storage(tmp_' + name.lower() + ')'
+  else:
+    result = call_level0_type( name, properties, arg_map )
+  return result
+
+
+def min_workspace_size_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size' ):
+    result = expand_nested_list( properties[ 'assert_size' ], arg_map, False );
+  return result
+
+
+def min_workspace_arg_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+    code_result = []
+    for arg in properties[ 'assert_size_args' ]:
+      if arg_map.has_key( arg ):
+        code_result += [ cpp_type( arg, arg_map[ arg ] ) ]
+      else:
+        code_result += [ '?' + arg.upper() ]
+    result = ", ".join( code_result )
+  return result
+
+
+def min_workspace_call_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+    code_result = []
+    for arg in properties[ 'assert_size_args' ]:
+      if arg_map.has_key( arg ):
+        code_result += [ call_level0_type( arg, arg_map[ arg ], arg_map ) ]
+      else:
+        code_result += [ '?' + arg.upper() ]
+      
+    result = ", ".join( code_result )
+  return result
+
+
+def user_defined_type( name, properties, arg_map ):
+  result = None
+  if properties.has_key( 'user_defined' ):
+    result = properties[ 'user_defined' ]
+  return result
+
+
+
+#
+#
+#
+#
+def match_formulae( text_field ):
+  find_start = re.compile( '([A-Z]+)\s?(>=|is\sat\sleast)\s?(.*)the\scode\swill', re.M | re.S ).findall( text_field )
+  for element in find_start:
+    print element
+
+
+
+#
+# Split string using a list of delimiters
+# Delimiters may be substrings of length 1 or 2 (may be increased if necessary)
+#
+def split_delim( s, delim = [','] ):
+  result = []
+  parentheses = 0
+  cur_pos = 0
+  prev_pos = 0
+  for index in range( 0, len(s) ):
+    if s[ index ] == '(': 
+      parentheses += 1
+    elif s[ index ] == ')':
+      parentheses -= 1
+    for length in range( 1, 3 ):
+      if index >= (length-1) and parentheses == 0:
+        c = s[ index-(length-1): index+1 ]
+        if c in delim:
+          result += [ s[ prev_pos:(index-(length-1)) ] ]
+          prev_pos = index+1
+          
+  result += [ s[ prev_pos:len(s) ] ]
+  return result
+
+
+
+#
+# Look for implicit products, like 5N, and replace with 5*N
+#
+def replace_implicit_products( text_field ):
+  result = re.sub( '([0-9])+([A-Z]+)', '\\1*\\2', text_field )
+  return result
+
+
+
+
+def decompose_formula( text_field ):
+  text_field = text_field.strip()
+  print "Decompose: ", text_field
+  
+  if text_field[0] == '(' and text_field[-1] == ')':
+    result = text_field[ 1:-1 ]
+    return [ '()', decompose_formula( result ) ]
+  
+  if len( split_delim( text_field, [ ',' ] ) ) > 1:
+    print "ERROR! (in BLAS?)"
+    return [ 'ERROR' ]
+  
+  #
+  # Detect leaf: if text_field equals a argument (like N), or a number
+  #  
+  if re.compile( '^([a-zA-Z]+|[0-9]+)$' ).match( text_field ):
+    print "decompose: at leaf: '" + text_field + "'"
+    return text_field.upper()
+  
+  
+  if len( split_delim( text_field, [ '**' ] ) ) > 1:
+    print 'decompose: inserting pow'
+    arguments = split_delim( text_field, [ '**' ] )
+    print arguments
+    result = []
+    for arg in arguments:
+      result.append( decompose_formula( arg ) )
+    return [ 'pow', result ]
+  
+  for operator in [ '*', '/', '+', '-' ]:
+    if len( split_delim( text_field, [ operator ] ) ) > 1:
+      print 'decompose: inserting ' + operator
+      arguments = split_delim( text_field, operator )
+      print arguments
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      return [ operator, result ]
+    
+  
+  if (text_field[ 0:4 ] == 'max(' or text_field[ 0:4 ] == 'MAX(') and \
+    text_field[ -1 ] == ')':
+    print "decompose: inserting max"
+    arguments = split_delim( text_field[ 4:-1 ] )
+    print arguments, len(arguments)
+    # keep max a binary function ... :-)
+    if len( arguments ) > 2:
+      return [ 'max', [ decompose_formula( arguments[0] ), decompose_formula( 'max(' + ",".join( arguments[1:] ) + ')' ) ] ]
+    else:  
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+      return [ 'max', result ]
+  
+
+  if (text_field[ 0:4 ] == 'min(' or text_field[ 0:4 ] == 'MIN(') and \
+    text_field[ -1 ] == ')':
+    print "decompose: inserting min"
+    arguments = split_delim( text_field[ 4:-1 ] )
+    print arguments, len(arguments)
+    # keep max a binary function ... :-)
+    if len( arguments ) > 2:
+      return [ 'min', [ decompose_formula( arguments[0] ), decompose_formula( 'min(' + ",".join( arguments[1:] ) + ')' ) ] ]
+    else:  
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+      return [ 'min', result ]
+  
+
+#
+#
+def match_assert_ge( argument_map, text_field ):
+  #print "Match assert GE..."
+  match_it = re.compile( ' +[A-Z]+[ ]{0,3}(>=|must be at least)[ ]{0,3}([0-9]|(min|max|MIN|MAX|[\(\)\,0-9A-Z\+\*\-])+)' ).findall( text_field )
+  if len( match_it ) == 1:
+    print "Match assert GE:", match_it
+    #print match_it
+    #if len( match_it[ 0 ][ 2 ] ) > 0:
+    return decompose_formula( match_it[ 0 ][ 1 ] )
+  else:
+    print "nr of matches: ", len( match_it )
+    return None
+  
+
+
+
+
+# try different keys, return the one that exists, if any
+
+def my_has_key( key_name, template_map ):
+  # try, e.g., gelsd.all.
+  m_all_key = key_name.replace( ".complex", ".all" ).replace( ".real", ".all" )
+  if template_map.has_key( key_name ):
+    print "using key ", key_name
+    return key_name
+  if template_map.has_key( m_all_key ):
+    print "using key ", m_all_key
+    return m_all_key
+  print "tried keys ", key_name, "and", m_all_key,", no results"
+  return None
+
+
+
+#
+# Default user-defined arg is of type scalar INTEGER
+#
+def add_user_defined_args( arg, argument_map, template_map, base_name ):
+  print "Trying to add user-defined argument definitions for", arg
+
+  argument_map[ arg ] = {}
+
+  base_key = base_name.lower() + '.' + arg
+  print "base_key",base_key
+
+  if my_has_key( base_key + '.value_type', template_map ) != None:
+    argument_map[ arg ][ 'value_type' ] = template_map[ my_has_key( base_key + '.value_type', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'value_type' ] = 'INTEGER'
+
+  if my_has_key( base_key + '.type', template_map ) != None:
+    argument_map[ arg ][ 'type' ] = template_map[ my_has_key( base_key + '.type', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'type' ] = 'scalar'
+
+  if my_has_key( base_key + '.init', template_map ) != None:
+    argument_map[ arg ][ 'user_defined' ] = template_map[ my_has_key( base_key + '.init', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'user_defined' ] = 'UNDEFINED'
+
+  argument_map[ arg ][ 'io' ] = [ 'input' ]
+
+  return
+
+
+
+#
+# Desired order of routines in C++ code: float, double, single complex, double complex
+#
+def routine_cmp( a, b ):
+  letter_a = a[0]
+  letter_b = b[0]
+  value_map = { 'S': 0, 'D': 1, 'C': 2, 'Z': 3 }
+  result = 0
+  if value_map[ a[0] ] < value_map[ b[ 0] ]:
+    result = -1
+  if value_map[ a[0] ] > value_map[ b[ 0] ]:
+    result = 1
+  return result
+    
+
+#
+# Group subroutines on their name, with the first character removed. This will 
+# group them in the same .hpp file as well. Sort these subroutines based on 
+# routine_cmp above.
+#
+def group_by_value_type( global_info_map ):
+  group_map = {}
+  for i in global_info_map.keys():
+    short_name = i[ 1: ]
+    if not group_map.has_key( short_name ):
+      group_map[ short_name ] = []
+    group_map[ short_name ] += [ i ]
+  for value in group_map.values():
+    value.sort( routine_cmp )
+  return group_map
+  
+
+
+ 
+#
+# Write the (many) driver routine file(s).
+#
+def write_functions( info_map, group, template_map, base_dir ):
+  #
+  # group.keys() is a vector of different grouped function names
+  # like gees, dgesv, etc.
+  #
+  for group_name, subroutines in group.iteritems():
+
+    filename = group_name.lower() + '.hpp'
+    includes = [ '#include <cassert>',
+      '#include <boost/numeric/bindings/traits/traits.hpp>',
+      '#include <boost/numeric/bindings/traits/type_traits.hpp>', 
+      '#include <boost/numeric/bindings/blas/blas.h>' ]
+      
+    if template_map.has_key( group_name.lower() + '.includes' ):
+      includes += template_map[ group_name.lower() + '.includes' ].splitlines()
+
+    #
+    # LEVEL 0 HANDLING
+    #  
+    overloads = ''
+    for subroutine in subroutines:
+      sub_template = template_map[ 'blas_overloads' ]
+      # add the argument list here
+      arg_list = []
+      lapack_arg_list = []
+      for arg in info_map[ subroutine ][ 'arguments' ]:
+        arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_0' ] ]
+        lapack_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_c_header' ] ]
+      sub_template = sub_template.replace( "$LEVEL0", ", ".join( arg_list ) )
+      sub_template = sub_template.replace( "$CALL_C_HEADER", ", ".join( lapack_arg_list ) )
+      sub_template = sub_template.replace( "$SUBROUTINE", subroutine )
+      sub_template = sub_template.replace( '$groupname', group_name.lower() )
+      
+      overloads += bindings.proper_indent( sub_template )
+  
+    cases = {}
+    # first, see what kind of functions we have
+    # needed for argument check etc.
+    for subroutine in subroutines:
+      if subroutine[0] == 'S' or subroutine[0] == 'D':
+        if not cases.has_key( 'real' ):
+          cases[ 'real' ] = {}
+          cases[ 'real' ][ 'subroutines' ] = []
+        cases[ 'real' ][ 'subroutines' ] += [ subroutine ]
+      if subroutine[0] == 'C' or subroutine[0] == 'Z':
+        if not cases.has_key( 'complex' ):
+          cases[ 'complex' ] = {}
+          cases[ 'complex' ][ 'subroutines' ] = []
+        cases[ 'complex' ][ 'subroutines' ] += [ subroutine ]
+
+    #
+    # LEVEL 1 and 2 HANDLING
+    #
+    level1_map = {}
+    level2_map = {}
+    for value_type, case_map in cases.iteritems():
+      level1_template = ''
+      level2_template = ''
+      level1_template = template_map[ 'blas_level1' ]
+
+      level0_arg_list = []
+      level1_arg_list = []
+      call_level1_arg_list = []
+      level1_type_arg_list = []
+      level1_assert_list = []
+      for arg in info_map[ subroutine ][ 'arguments' ]:
+        level0_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_0' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] != None:
+          level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_1' ] != None:
+          call_level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_1' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] != None and \
+          info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] not in level1_type_arg_list:
+          level1_type_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_assert' ] != None:
+          level1_assert_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_assert' ] ]
+
+      # Level 1 replacements
+      level1_template = level1_template.replace( "$CALL_LEVEL0", ", ".join( level0_arg_list ) )
+      level1_template = level1_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+      level1_template = level1_template.replace( "$LEVEL1", ", ".join( level1_arg_list ) )
+      level1_template = level1_template.replace( "$TYPES", ", ".join( level1_type_arg_list ) )
+      level1_template = level1_template.replace( "$ASSERTS", "\n        ".join( level1_assert_list ) )
+
+      level1_map[ value_type ] = bindings.proper_indent( level1_template )
+
+    #
+    # LEVEL 1 and 2 FINALIZATION
+    #
+    for mapping in [ level1_map, level2_map ]:
+      if len(mapping) > 1:
+        # compare real and complex cases
+        all_keys = mapping.keys()
+        if mapping[ all_keys[0] ] == mapping[ all_keys[1] ]:
+          print "literally everything is the same!!, falling back to 1 case"
+          del mapping[ all_keys[ 1 ] ]
+
+    level1 = ''
+    for value_type in level1_map.keys():
+      level1 += level1_map[ value_type ]
+
+    #
+    # handle addition of includes
+    #
+    includes_code = ''
+    unique_includes = []
+    for include in includes:
+      if include not in unique_includes:
+        unique_includes += [ include ]
+    sorted_includes = sorted( unique_includes, lambda x, y: cmp( x.lower(), y.lower() ) )
+    if len( sorted_includes ) > 0:
+      includes_code = "\n".join( sorted_includes )
+
+    result = template_map[ 'blas.hpp' ]
+    result = result.replace( '$INCLUDES', includes_code )
+    result = result.replace( '$OVERLOADS', overloads )
+    result = result.replace( '$LEVEL1', level1 )
+    result = result.replace( '$GROUPNAME', group_name )
+    result = result.replace( '$groupname', group_name.lower() )
+
+    # replace the global variables as last (this is convenient)
+    #result = result.replace( '$INDENT', '    ' )
+    #result = result.replace( '$groupname', group_name.lower() )
+    #result = result.replace( '$DESCRIPTION', info_map[ group[g][0] ][ 'description' ] )
+
+    open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+
+#
+# Write the (many) driver routine test cases to cpp files.
+#
+def write_test_case( info_map, group, template_map, base_dir, level_name ):
+
+  for group_name, subroutines in group.iteritems():
+
+    filename = group_name.lower() + '.cpp'
+    result = template_map[ 'test_case.cpp' ]
+    result = result.replace( '$groupname', group_name.lower() )
+    result = result.replace( '$levelname', level_name.lower() )
+
+    open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+def write_cmakefile( level_properties, template_map, base_dir ):
+  
+  entries = '' 
+  for problem_type, problem_properties in level_properties.iteritems():
+    if problem_properties.has_key( 'routines_by_value_type' ):
+      group = problem_properties[ 'routines_by_value_type' ]
+      for group_name, subroutines in group.iteritems():
+        sub_result = template_map[ 'CMakeLists.entry' ]
+        sub_result = sub_result.replace( '$groupname', group_name.lower() )
+        entries += sub_result
+
+  filename = 'CMakeLists.txt'
+  result = template_map[ 'CMakeLists.txt' ]
+  result = result.replace( '$ENTRIES', entries )
+  open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+
+def read_templates( template_file ):
+  file_contents = open( template_file ).read()
+  split_regex = re.compile( '^\$TEMPLATE\[([^\]]+)\]\s', re.M | re.S )
+  split_templates = split_regex.split( file_contents )[ 1:-1 ]
+  result = {}
+  for index in range(len(split_templates)/2):
+    print "Adding template", split_templates[ index*2 ]
+    result[ split_templates[ index*2 ] ] = split_templates[ index*2 + 1 ]
+  return result
+
+lapack_src_path = './blas-1.2/src'
+template_src_path = './templates'
+bindings_target_path = '../../../../boost/numeric/bindings/blas/'
+test_target_path = '../test/lapack/'
+
+templates = {}
+templates[ 'PARSERMODE' ] = 'BLAS'
+for root, dirs, files in os.walk( template_src_path ):
+  right_file = re.compile( '^.+\.(cpp|h|hpp|txt)$' )
+  for template_file in files:
+    if right_file.match( template_file ) != None:
+      path_to_template_file = os.path.join( root, template_file )
+      print "Reading template file", path_to_template_file
+      templates.update( read_templates( path_to_template_file ) )
+
+function_info_map = {}
+for lapack_file in os.listdir( lapack_src_path ):
+  right_file = re.compile( '^[cdsz].+\.f$' )
+  if right_file.match( lapack_file ) != None:
+    print "Parsing", lapack_file, "..."
+    key, value = netlib.parse_file( os.path.join( lapack_src_path, lapack_file ), templates )
+    if key != None and value != None:
+      print "Adding LAPACK subroutine", key
+      function_info_map[ key ] = value
+
+print "Grouping subroutines..."
+
+value_type_groups = {}
+value_type_groups = group_by_value_type( function_info_map )
+
+routines = {}
+routines[ 'level_1' ] = {}
+routines[ 'level_1' ][ 'endings' ] = [ 'ROTG', 'OTMG', 'ROT', 'ROTM', 'SWAP', 'SCAL', 'COPY', 'AXPY', 'DOT', 'DOTU', 'DOTC', 'NRM2', 'ASUM', 'AMAX' ]
+
+routines[ 'level_2' ] = {}
+routines[ 'level_2' ][ 'endings' ] = [ 'MV', 'SV', 'GER', 'GERU', 'GERC', 'HER', 'HPR', 'HER2', 'HPR2', 'SYR', 'SPR', 'SYR2' ]
+
+routines[ 'level_3' ] = {}
+routines[ 'level_3' ][ 'endings' ] = [ 'MM', 'RK', 'R2K', 'SM' ]
+
+for name in value_type_groups.keys():
+  found = False
+  for level, level_properties in routines.iteritems():
+      if name[ -2: ] in level_properties[ 'endings' ] or \
+         name[ -3: ] in level_properties[ 'endings' ] or \
+         name[ -4: ] in level_properties[ 'endings' ]:
+        print name, "is in " + level
+        if not level_properties.has_key( 'routines_by_value_type' ):
+          level_properties[ 'routines_by_value_type' ] = {}
+        level_properties[ 'routines_by_value_type' ][ name ] = value_type_groups[ name ]
+        found = True
+  if found == False:
+    print name, "is in {??}"
+
+print routines 
+
+
+bindings.write_names_header( function_info_map, value_type_groups, templates, bindings_target_path + 'blas_names.h' )
+bindings.write_header( function_info_map, value_type_groups, templates, bindings_target_path + 'blas.h' )
+
+for level, level_properties in routines.iteritems():
+  target_path = bindings_target_path + level
+  if not os.path.exists( target_path ):
+    print "Creating directory " + target_path
+    os.mkdir( target_path )
+
+  print level_properties
+
+  if level_properties.has_key( 'routines_by_value_type' ):
+    print "has key..." 
+    write_functions( function_info_map, level_properties[ 'routines_by_value_type' ], templates, target_path )
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/lapack_generator.py	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,1052 @@
+#!/usr/bin/python
+#
+#  Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import netlib
+import bindings
+
+import re, os.path, copy
+from types import StringType
+
+# for debugging purposes
+import pprint
+
+
+global_type_map = { 
+  'CHARACTER': 'char',
+  'LOGICAL': 'logical_t', 
+  'INTEGER': 'integer_t',
+  'REAL': 'float', 
+  'DOUBLE PRECISION': 'double' }
+  
+templates = {}
+
+
+  
+def c_type( name, properties ):
+  m_type_map = global_type_map
+  m_type_map[ 'COMPLEX' ] = 'fcomplex_t'
+  m_type_map[ 'COMPLEX*16' ] = 'dcomplex_t'
+
+  result = m_type_map[ properties[ 'value_type' ] ];
+  if properties[ 'io' ] == [ 'input' ]:
+    result += ' const'
+  result += '*'
+  result += ' ' + name.lower()  # is this really needed?
+  
+  return result
+  
+  
+def cpp_type( name, properties ):
+  m_type_map = global_type_map
+  m_type_map[ 'COMPLEX' ] = 'traits::complex_f'
+  m_type_map[ 'COMPLEX*16' ] = 'traits::complex_d'
+  
+  result = m_type_map[ properties[ 'value_type' ] ]
+  
+  if properties[ 'type' ] == 'scalar':
+    if properties[ 'io' ] == [ 'input' ]:
+      result += ' const'
+    elif properties[ 'io' ] == [ 'external procedure' ]:
+      result += '*'
+    else:
+      result += '&'
+    
+  if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+    result += '*'
+    
+  result += ' ' + name.lower()
+    
+  return result
+  
+def call_c_type( name, properties ):
+  result = ''
+  if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+      result = 'traits::complex_ptr(' + name.lower() + ')'
+    else:
+      result = name.lower()
+  elif properties[ 'type' ] == 'scalar':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+      result = 'traits::complex_ptr(&' + name.lower() + ')'
+    else:
+      result = '&' + name.lower()
+  
+  return result
+  
+
+def call_level0_type( name, properties, arg_map ):
+  result = ''
+  if properties[ 'type' ] == 'matrix':
+    result = "traits::matrix_storage(" + name.lower() + ")"
+  elif properties[ 'type' ] == 'vector':
+    my_name = name.lower()
+    if 'workspace' in properties[ 'io' ]:
+      my_name = 'work.select(' + workspace_type( name, properties ) + '())'
+    result = "traits::vector_storage(" + my_name + ")"
+  elif properties.has_key( 'trait_type' ):
+    if properties[ 'trait_type' ] == 'lda':
+      result = "traits::leading_dimension(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'num_columns':
+      result = "traits::matrix_size2(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'num_rows':
+      result = "traits::matrix_size1(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'size':
+      my_name = properties[ 'trait_of' ].lower()
+      referring_to_properties = arg_map[ properties[ 'trait_of' ] ]
+      if 'workspace' in referring_to_properties[ 'io' ]:
+        my_name = 'work.select(' + workspace_type( properties[ 'trait_of' ].lower(), referring_to_properties ) + \
+                  '())'
+      result = "traits::vector_size(" + my_name + ")"
+    if properties[ 'trait_type' ] == 'uplo':
+      result = "traits::matrix_uplo_tag(" + properties[ 'trait_of' ].lower() + ")"
+  else:
+    result = name.lower()
+  return result
+
+
+def level1_type( name, properties ):
+  result = None
+  if not properties.has_key( 'trait_of' ) and 'workspace' not in properties[ 'io' ]:
+    if properties[ 'type' ] == 'matrix':
+      result = "Matrix" + name + "& " + name.lower()
+    elif properties[ 'type' ] == 'vector':
+      result = "Vector" + name + "& " + name.lower()
+    else:
+      result = cpp_type( name, properties )
+      if properties[ 'value_type' ] == 'REAL':
+        result = result.replace( "float", "real_type" )
+      if properties[ 'value_type' ] == 'DOUBLE PRECISION':
+        result = result.replace( "double", "real_type" )
+  return result
+
+
+def level2_type( name, properties ):
+  result = level1_type( name, properties )
+  if name == 'INFO' and 'output' in properties[ 'io' ]:
+    result = None
+
+  if result != None:
+    if properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+      result = result.replace( "real_type", "typename traits::$TYPEOF_FIRST_TYPENAME" + \
+        "_traits< $FIRST_TYPENAME >::value_type" )
+
+  return result
+
+
+def level1_typename( name, properties ):
+  result = None
+  if 'workspace' not in properties[ 'io' ]:
+    if properties[ 'type' ] == 'matrix':
+      result = "typename Matrix" + name
+    if properties[ 'type' ] == 'vector':
+      result = "typename Vector" + name
+  return result
+
+
+
+def nested_list_args( arg ):
+  print "finding nested list arguments of", arg
+  if type( arg ) == StringType:
+    if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+      return [ None ]
+    else:
+      return [ arg.upper() ]
+  
+  # we are dealing with a list-type, e.g., 
+  # [ '*', [ 'A', 'B' ] ]
+  # [ 'A', 'B' ]
+  result = []
+  if re.compile( '^[A-Z]+$' ).match( arg[0] ) == None:
+    for a in arg[1]:
+      sub_result = nested_list_args( a )
+      if sub_result != [ None ]:
+        for r in sub_result:
+          if r not in result:
+            result.append( r )
+
+  else:
+    for a in arg:
+      result.append( a )
+
+  print "returning ",result
+  return result
+
+
+
+
+def expand_nested_list( arg, arg_map, use_arg_map = True ):
+
+  print "Expanding nested list: ", arg, len(arg)
+  if type( arg ) == StringType:
+    print "Type is string"
+    # .....
+    if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+      return arg
+    else:
+      if use_arg_map:
+        if not arg_map.has_key( arg ):
+          return '?' + arg.upper()
+        else:
+          return arg_map[ arg ][ 'code' ][ 'call_level_0' ]
+      else:
+        return arg.lower()
+    
+  if arg[0] == '()':
+    result = '(' + expand_nested_list( arg[1], arg_map, use_arg_map ) + ')'
+    return result
+    
+  if arg[0] == 'max' or arg[0] == 'min':
+    print "arg1: ", arg[1]
+    result = 'std::' + arg[0] + '('
+    i = 0
+    for a in arg[1]:
+      result += expand_nested_list( a, arg_map, use_arg_map )
+      i += 1
+      if i != len(arg[1]):
+        result += ","
+    result += ')'
+    return result
+  
+  if arg[0] == '*' or arg[0] == '/' or arg[0] == '+' or arg[0] == '-':
+    print "arg1: ", arg[1]
+    arg_list = []
+    for a in arg[1]:
+      arg_list += [ expand_nested_list( a, arg_map, use_arg_map ) ]
+    result = arg[0].join( arg_list )
+    return result
+  
+  print "ERROR: Don't know what to do!!"
+  return 'ERROR'
+
+def level1_assert( name, properties, arg_map ):
+  result = None
+  
+  if properties.has_key( 'assert_char' ):
+    result = "assert( "
+    result_array = []
+    for char in properties[ 'assert_char' ]:
+      result_array += [ call_level0_type( name, properties, arg_map ) + ' == \'' + char + '\'' ]
+    result += " || ".join( result_array )
+    result += " );"
+    
+  if properties.has_key( 'assert_ge' ) and not properties.has_key( 'workspace_query_for' ):
+    result = "assert( " + call_level0_type( name, properties, arg_map ) + " >= " + expand_nested_list( properties[ 'assert_ge' ], arg_map ) + ' );'
+      
+  if 'workspace' in properties[ 'io' ]:
+    min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+    if min_workspace_call == None:
+      min_workspace_call = '$CALL_MIN_SIZE'
+    result = 'assert( traits::vector_size(work.select(' + workspace_type( name, properties ) + '()) >= ' + \
+             'min_size_' + name.lower() + '( ' + min_workspace_call + ' )));'
+  
+  elif properties.has_key( 'assert_size' ):
+    result = "assert( traits::vector_size(" + call_level0_type( name, properties, arg_map ) + ") >= " + \
+      expand_nested_list( properties[ 'assert_size' ], arg_map ) + ' );'
+  
+  return result
+
+
+def call_level1_type( name, properties ):
+  result = None
+  if level1_type( name, properties ) != None:
+    result = name.lower()
+  return result
+
+
+def workspace_type( name, properties ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties[ 'value_type' ] == 'INTEGER':
+      result = 'integer_t'
+    elif properties[ 'value_type' ] == 'LOGICAL':
+      result = 'bool'
+    elif properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+      result = 'real_type'
+    else: 
+      result = 'value_type'
+  return result
+
+
+
+
+def opt_workspace_pre_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      result = workspace_type( name, properties ) + ' opt_size_' + name.lower() + ';'
+    else:
+      min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+      if min_workspace_call == None:
+        min_workspace_call = '$CALL_MIN_SIZE'
+      result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( min_size_' + name.lower() + '( ' + min_workspace_call + ' ) );'
+  return result
+
+
+def opt_workspace_post_type( name, properties ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      if properties['value_type'] == 'INTEGER':
+        result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( opt_size_' + name.lower() + ' );'
+      else:
+        result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( traits::detail::to_int( opt_size_' + name.lower() + ' ) );'
+  return result
+
+
+
+def opt_workspace_query_type( name, properties, arg_map ):
+  result = None
+  if properties.has_key( 'workspace_query_for' ):
+    result = '-1'
+  elif 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      result = '&opt_size_' + name.lower();
+    else:
+      result = 'traits::vector_storage(tmp_' + name.lower() + ')'
+  else:
+    result = call_level0_type( name, properties, arg_map )
+  return result
+
+
+def min_workspace_size_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size' ):
+    result = expand_nested_list( properties[ 'assert_size' ], arg_map, False );
+  return result
+
+
+def min_workspace_arg_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+    code_result = []
+    for arg in properties[ 'assert_size_args' ]:
+      if arg_map.has_key( arg ):
+        code_result += [ cpp_type( arg, arg_map[ arg ] ) ]
+      else:
+        code_result += [ '?' + arg.upper() ]
+    result = ", ".join( code_result )
+  return result
+
+
+def min_workspace_call_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+    code_result = []
+    for arg in properties[ 'assert_size_args' ]:
+      if arg_map.has_key( arg ):
+        code_result += [ call_level0_type( arg, arg_map[ arg ], arg_map ) ]
+      else:
+        code_result += [ '?' + arg.upper() ]
+      
+    result = ", ".join( code_result )
+  return result
+
+
+def user_defined_type( name, properties, arg_map ):
+  result = None
+  if properties.has_key( 'user_defined' ):
+    result = properties[ 'user_defined' ]
+  return result
+
+
+
+#
+#
+#
+#
+def match_formulae( text_field ):
+  find_start = re.compile( '([A-Z]+)\s?(>=|is\sat\sleast)\s?(.*)the\scode\swill', re.M | re.S ).findall( text_field )
+  for element in find_start:
+    print element
+
+
+
+#
+# Split string using a list of delimiters
+# Delimiters may be substrings of length 1 or 2 (may be increased if necessary)
+#
+def split_delim( s, delim = [','] ):
+  result = []
+  parentheses = 0
+  cur_pos = 0
+  prev_pos = 0
+  for index in range( 0, len(s) ):
+    if s[ index ] == '(': 
+      parentheses += 1
+    elif s[ index ] == ')':
+      parentheses -= 1
+    for length in range( 1, 3 ):
+      if index >= (length-1) and parentheses == 0:
+        c = s[ index-(length-1): index+1 ]
+        if c in delim:
+          result += [ s[ prev_pos:(index-(length-1)) ] ]
+          prev_pos = index+1
+          
+  result += [ s[ prev_pos:len(s) ] ]
+  return result
+
+
+
+#
+# Look for implicit products, like 5N, and replace with 5*N
+#
+def replace_implicit_products( text_field ):
+  result = re.sub( '([0-9])+([A-Z]+)', '\\1*\\2', text_field )
+  return result
+
+
+
+
+def decompose_formula( text_field ):
+  text_field = text_field.strip()
+  print "Decompose: ", text_field
+  
+  if text_field[0] == '(' and text_field[-1] == ')':
+    result = text_field[ 1:-1 ]
+    return [ '()', decompose_formula( result ) ]
+  
+  if len( split_delim( text_field, [ ',' ] ) ) > 1:
+    print "ERROR! (in LAPACK?)"
+    return [ 'ERROR' ]
+  
+  #
+  # Detect leaf: if text_field equals a argument (like N), or a number
+  #  
+  if re.compile( '^([a-zA-Z]+|[0-9]+)$' ).match( text_field ):
+    print "decompose: at leaf: '" + text_field + "'"
+    return text_field.upper()
+  
+  
+  if len( split_delim( text_field, [ '**' ] ) ) > 1:
+    print 'decompose: inserting pow'
+    arguments = split_delim( text_field, [ '**' ] )
+    print arguments
+    result = []
+    for arg in arguments:
+      result.append( decompose_formula( arg ) )
+    return [ 'pow', result ]
+  
+  for operator in [ '*', '/', '+', '-' ]:
+    if len( split_delim( text_field, [ operator ] ) ) > 1:
+      print 'decompose: inserting ' + operator
+      arguments = split_delim( text_field, operator )
+      print arguments
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      return [ operator, result ]
+    
+  
+  if (text_field[ 0:4 ] == 'max(' or text_field[ 0:4 ] == 'MAX(') and \
+    text_field[ -1 ] == ')':
+    print "decompose: inserting max"
+    arguments = split_delim( text_field[ 4:-1 ] )
+    print arguments, len(arguments)
+    # keep max a binary function ... :-)
+    if len( arguments ) > 2:
+      return [ 'max', [ decompose_formula( arguments[0] ), decompose_formula( 'max(' + ",".join( arguments[1:] ) + ')' ) ] ]
+    else:  
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+      return [ 'max', result ]
+  
+
+  if (text_field[ 0:4 ] == 'min(' or text_field[ 0:4 ] == 'MIN(') and \
+    text_field[ -1 ] == ')':
+    print "decompose: inserting min"
+    arguments = split_delim( text_field[ 4:-1 ] )
+    print arguments, len(arguments)
+    # keep max a binary function ... :-)
+    if len( arguments ) > 2:
+      return [ 'min', [ decompose_formula( arguments[0] ), decompose_formula( 'min(' + ",".join( arguments[1:] ) + ')' ) ] ]
+    else:  
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+      return [ 'min', result ]
+  
+
+#
+#
+def match_assert_ge( argument_map, text_field ):
+  #print "Match assert GE..."
+  match_it = re.compile( ' +[A-Z]+[ ]{0,3}(>=|must be at least)[ ]{0,3}([0-9]|(min|max|MIN|MAX|[\(\)\,0-9A-Z\+\*\-])+)' ).findall( text_field )
+  if len( match_it ) == 1:
+    print "Match assert GE:", match_it
+    #print match_it
+    #if len( match_it[ 0 ][ 2 ] ) > 0:
+    return decompose_formula( match_it[ 0 ][ 1 ] )
+  else:
+    print "nr of matches: ", len( match_it )
+    return None
+  
+
+
+
+
+# try different keys, return the one that exists, if any
+
+def my_has_key( key_name, template_map ):
+  # try, e.g., gelsd.all.
+  m_all_key = key_name.replace( ".complex", ".all" ).replace( ".real", ".all" )
+  if template_map.has_key( key_name ):
+    print "using key ", key_name
+    return key_name
+  if template_map.has_key( m_all_key ):
+    print "using key ", m_all_key
+    return m_all_key
+  print "tried keys ", key_name, "and", m_all_key,", no results"
+  return None
+
+
+
+#
+# Default user-defined arg is of type scalar INTEGER
+#
+def add_user_defined_args( arg, argument_map, template_map, base_name ):
+  print "Trying to add user-defined argument definitions for", arg
+
+  argument_map[ arg ] = {}
+
+  base_key = base_name.lower() + '.' + arg
+  print "base_key",base_key
+
+  if my_has_key( base_key + '.value_type', template_map ) != None:
+    argument_map[ arg ][ 'value_type' ] = template_map[ my_has_key( base_key + '.value_type', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'value_type' ] = 'INTEGER'
+
+  if my_has_key( base_key + '.type', template_map ) != None:
+    argument_map[ arg ][ 'type' ] = template_map[ my_has_key( base_key + '.type', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'type' ] = 'scalar'
+
+  if my_has_key( base_key + '.init', template_map ) != None:
+    argument_map[ arg ][ 'user_defined' ] = template_map[ my_has_key( base_key + '.init', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'user_defined' ] = 'UNDEFINED'
+
+  argument_map[ arg ][ 'io' ] = [ 'input' ]
+
+  return
+
+
+#
+# Desired order of routines in C++ code: float, double, single complex, double complex
+#
+def routine_cmp( a, b ):
+  letter_a = a[0]
+  letter_b = b[0]
+  value_map = { 'S': 0, 'D': 1, 'C': 2, 'Z': 3 }
+  result = 0
+  if value_map[ a[0] ] < value_map[ b[ 0] ]:
+    result = -1
+  if value_map[ a[0] ] > value_map[ b[ 0] ]:
+    result = 1
+  return result
+    
+
+#
+# Group subroutines on their name, with the first character removed. This will 
+# group them in the same .hpp file as well. Sort these subroutines based on 
+# routine_cmp above.
+#
+def group_by_value_type( global_info_map ):
+  group_map = {}
+  for i in global_info_map.keys():
+    short_name = i[ 1: ]
+    if not group_map.has_key( short_name ):
+      group_map[ short_name ] = []
+    group_map[ short_name ] += [ i ]
+  for value in group_map.values():
+    value.sort( routine_cmp )
+  return group_map
+  
+
+
+  
+def indent_lines( source_text, indent_size = 8 ):
+  indent_string = '\n'
+  for i in range(indent_size):
+    indent_string += ' '
+  return indent_string.join( source_text.splitlines() )
+  
+
+  
+#
+# Write the (many) driver routine file(s).
+#
+def write_functions( info_map, group, template_map, base_dir ):
+  #
+  # group.keys() is a vector of different grouped function names
+  # like gees, dgesv, etc.
+  #
+  for group_name, subroutines in group.iteritems():
+    
+    filename = group_name.lower() + '.hpp'
+    includes = [ '#include <cassert>',
+      '#include <boost/numeric/bindings/traits/traits.hpp>',
+      '#include <boost/numeric/bindings/traits/type_traits.hpp>', 
+      '#include <boost/numeric/bindings/lapack/lapack.h>' ]
+      
+    if template_map.has_key( group_name.lower() + '.includes' ):
+      includes += template_map[ group_name.lower() + '.includes' ].splitlines()
+
+    #
+    # LEVEL 0 HANDLING
+    #  
+    overloads = ''
+    for subroutine in subroutines:
+      sub_template = template_map[ 'lapack_overloads' ]
+      # add the argument list here
+      arg_list = []
+      lapack_arg_list = []
+      for arg in info_map[ subroutine ][ 'arguments' ]:
+        arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_0' ] ]
+        lapack_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_c_header' ] ]
+      sub_template = sub_template.replace( "$LEVEL0", ", ".join( arg_list ) )
+      sub_template = sub_template.replace( "$CALL_C_HEADER", ", ".join( lapack_arg_list ) )
+      sub_template = sub_template.replace( "$SUBROUTINE", subroutine )
+      sub_template = sub_template.replace( '$groupname', group_name.lower() )
+      
+      overloads += bindings.proper_indent( sub_template )
+  
+    cases = {}
+    # first, see what kind of functions we have
+    # needed for argument check etc.
+    for subroutine in subroutines:
+      if subroutine[0] == 'S' or subroutine[0] == 'D':
+        if not cases.has_key( 'real' ):
+          cases[ 'real' ] = {}
+          cases[ 'real' ][ 'subroutines' ] = []
+        cases[ 'real' ][ 'subroutines' ] += [ subroutine ]
+      if subroutine[0] == 'C' or subroutine[0] == 'Z':
+        if not cases.has_key( 'complex' ):
+          cases[ 'complex' ] = {}
+          cases[ 'complex' ][ 'subroutines' ] = []
+        cases[ 'complex' ][ 'subroutines' ] += [ subroutine ]
+    
+    #
+    # LEVEL 1 and 2 HANDLING
+    #
+    level1_map = {}
+    level2_map = {}
+    for value_type, case_map in cases.iteritems():
+      
+      level1_template = ''
+      level2_template = ''
+      if info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ].has_key( 'workspace' ):
+        level1_template = template_map[ 'level1_workspace' ]
+        level2_template = template_map[ 'level2_workspace' ]
+      else:
+        level1_template = template_map[ 'level1_noworkspace' ]
+        level2_template = template_map[ 'level2_noworkspace' ]
+      
+      level1_template = level1_template.replace( '$groupname', group_name.lower() )
+      level1_template = level1_template.replace( "$SPECIALIZATION", value_type )
+    
+      # take this subroutine for arguments etc.
+      subroutine = case_map[ 'subroutines' ][ 0 ]
+      print "taking",subroutine
+      
+      level0_arg_list = []
+      level1_arg_list = []
+      level2_arg_list = []
+      level1_type_arg_list = []
+      level1_assert_list = []
+      call_level1_arg_list = []
+      workspace_query_arg_list = []
+      user_defined_arg_list = []
+      user_defined_opt_arg_list = []
+      for arg in info_map[ subroutine ][ 'arguments' ]:
+        level0_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_0' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] != None:
+          level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_2' ] != None:
+          level2_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_2' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] != None and \
+          info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] not in level1_type_arg_list:
+          level1_type_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_type' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_assert' ] != None:
+          level1_assert_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'level_1_assert' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_1' ] != None:
+          call_level1_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'call_level_1' ] ]
+        if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'opt_workspace_query' ] != None:
+          workspace_query_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'opt_workspace_query' ] ]
+          
+      if info_map[ subroutine ][ 'user_defined_variables' ] != None:
+        for arg in info_map[ subroutine ][ 'user_defined_variables' ]:
+          print arg
+          if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] != None:
+            user_defined_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] ]
+      
+      if info_map[ subroutine ][ 'user_defined_opt_variables' ] != None:
+        for arg in info_map[ subroutine ][ 'user_defined_opt_variables' ]:
+          print arg
+          if info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] != None:
+            user_defined_opt_arg_list += [ info_map[ subroutine ][ 'argument_map' ][ arg ][ 'code' ][ 'user_defined_init' ] ]
+      
+      # Level 1 replacements
+      level1_template = level1_template.replace( "$CALL_LEVEL0", ", ".join( level0_arg_list ) )
+      level1_template = level1_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+      level1_template = level1_template.replace( "$LEVEL1", ", ".join( level1_arg_list ) )
+      level1_template = level1_template.replace( "$TYPES", ", ".join( level1_type_arg_list ) )
+      level1_template = level1_template.replace( "$ASSERTS", "\n        ".join( level1_assert_list ) )
+      
+      if len( user_defined_arg_list ) > 0:
+        level1_template = level1_template.replace( "$INIT_USER_DEFINED_VARIABLES", indent_lines( "\n".join(user_defined_arg_list), 8 ) )
+      else:
+        level1_template = level1_template.replace( "\n        $INIT_USER_DEFINED_VARIABLES", "" )
+
+      # Level 2 replacements
+      # some special stuff is done here, such as replacing real_type with a 
+      # type-traits deduction, etc..
+      level2_template = level2_template.replace( "$LEVEL2", ", ".join( level2_arg_list ) )
+      first_typename = level1_type_arg_list[0].split(" ")[-1]
+      first_typename_datatype = first_typename[0:6].lower() # 'matrix' or 'vector'
+      level2_template = level2_template.replace( "$FIRST_TYPENAME", first_typename )
+      level2_template = level2_template.replace( "$TYPEOF_FIRST_TYPENAME", first_typename_datatype )
+      level2_template = level2_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+      level2_template = level2_template.replace( "$TYPES", ", ".join( level1_type_arg_list ) )
+
+      #
+      # Workspace stuff
+      #
+      if info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ].has_key( 'workspace' ):
+        # Add an include for the workspace stuff
+        includes += [ '#include <boost/numeric/bindings/lapack/workspace.hpp>' ]
+        includes += [ '#include <boost/numeric/bindings/traits/detail/array.hpp>' ]
+
+        # Continue
+        workspace_size = len( info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ] )
+        workspace_args = info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]
+        level1_template = level1_template.replace( "$WORKSPACE_SIZE", str(workspace_size) )
+        level1_template = level1_template.replace( "$WORKSPACE_TYPENAMES", "typename " + ", typename ".join( workspace_args ) )
+        level1_template = level1_template.replace( "$WORKSPACE_TYPES", ", ".join( workspace_args ) )
+
+        # $TMP_WORKARRAYS is something like "tmp_work, tmp_rwork"
+        tmp_workspace_args = []
+        for name in info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]:
+          tmp_workspace_args += [ 'tmp_' + name.lower() ]
+        level1_template = level1_template.replace( "$TMP_WORKARRAYS", ", ".join( tmp_workspace_args ) )
+        
+        # $SETUP_WORKARRAYS looks like 
+        #    traits::detail::array< value_type > $TMP_NAME .... 
+        setup_min_workarrays = ''
+        setup_opt_workarrays_pre = []
+        setup_opt_workarrays_post = []
+        for name in info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]:
+          # minimal case
+          sub_min_template = template_map[ 'setup_min_workspace' ]
+          sub_min_template = sub_min_template.replace( '$NAME', name.lower() )
+          sub_min_template = sub_min_template.replace( '$WORKSPACE_TYPE', info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'workspace_type' ] )
+          if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_call' ] != None:
+            sub_min_template = sub_min_template.replace( "$CALL_MIN_SIZE", info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_call' ] )
+          
+          setup_min_workarrays += sub_min_template
+
+          # optimal case
+          if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_pre' ] != None:
+            setup_opt_workarrays_pre += [ info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_pre' ] ]
+          if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_post' ] != None:
+            setup_opt_workarrays_post += [ info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'opt_workspace_post' ] ]
+          
+          
+        # if the length of setup_opt_workarrays_post equals 0, it's equal to the minimal_case
+        opt_workspace_template = ''
+        if len( setup_opt_workarrays_post ) == 0:
+          print "EQUAL to MINIMAL CASE!"
+          opt_workspace_template = template_map[ 'level1_opt_workspace_is_min' ]
+        else:
+          includes += [ '#include <boost/numeric/bindings/traits/detail/utils.hpp>' ]
+          opt_workspace_template = template_map[ 'level1_opt_workspace' ]
+          
+        opt_workspace_template = opt_workspace_template.replace( "$WORKSPACE_QUERY", ", ".join( workspace_query_arg_list ) )
+        opt_workspace_template = opt_workspace_template.replace( "$SETUP_OPT_WORKARRAYS_POST", "\n        ".join( setup_opt_workarrays_post ) )
+        opt_workspace_template = opt_workspace_template.replace( "$SETUP_OPT_WORKARRAYS_PRE", "\n        ".join( setup_opt_workarrays_pre ) )
+        opt_workspace_template = opt_workspace_template.replace( "$CALL_LEVEL1", ", ".join( call_level1_arg_list ) )
+        opt_workspace_template = opt_workspace_template.replace( "$TMP_WORKARRAYS", ", ".join( tmp_workspace_args ) )
+        
+      
+        if len( user_defined_opt_arg_list ) > 0:
+          opt_workspace_template = opt_workspace_template.replace( "$INIT_USER_DEFINED_OPT_VARIABLES", indent_lines( "\n".join(user_defined_arg_list), 8 ) )
+        else:
+          print "removing $INIT_USER_DEFINED_OPT_VARIABLES"
+          opt_workspace_template = opt_workspace_template.replace( "        $INIT_USER_DEFINED_OPT_VARIABLES\n", "" )
+        
+        
+        level1_template = level1_template.replace( "$OPT_WORKSPACE_FUNC", opt_workspace_template.rstrip() )
+        level1_template = level1_template.replace( "$SETUP_MIN_WORKARRAYS_POST", setup_min_workarrays.rstrip() )
+        
+        
+        #
+        # INSERT THE MINIMAL WORKSPACE FUNCTIONS
+        #
+        min_size_funcs = ''
+        for name in info_map[ subroutine ][ 'grouped_arguments' ][ 'by_io' ][ 'workspace' ]:
+          sub_template = template_map[ 'min_size_func' ]
+          sub_template = sub_template.replace( "$NAME", name.lower() )
+          
+          # first: user-defined stuff (overrules any auto-detected stuff)
+          my_key = group_name.lower() + '.' + value_type + '.min_size_' + name.lower()
+          my_key_all = group_name.lower() + '.all.min_size_' + name.lower()
+          print my_key
+          if template_map.has_key( my_key ):
+            sub_template = sub_template.replace( "$MIN_SIZE", indent_lines( template_map[ my_key ].rstrip(), 8 ) )
+            
+          # if that fails, try the more generic key "all"
+          elif template_map.has_key( my_key_all ):
+            sub_template = sub_template.replace( "$MIN_SIZE", indent_lines( template_map[ my_key_all ].rstrip(), 8 ) )
+          
+          elif info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace' ] != None:
+            resulting_code = 'return ' + info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace' ] + ';'
+            sub_template = sub_template.replace( "$MIN_SIZE", resulting_code.rstrip() )
+            
+          # Do about the same for the argument stuff.  
+          if info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_args' ] != None:
+            sub_template = sub_template.replace( "$ARGUMENTS", info_map[ subroutine ][ 'argument_map' ][ name ][ 'code' ][ 'min_workspace_args' ] )
+
+            #sub_template += 'FOUND'
+          min_size_funcs += sub_template
+
+        min_size_funcs = min_size_funcs.rstrip()
+        level1_template = level1_template.replace( "$MIN_SIZE_FUNCS", min_size_funcs )
+
+      level1_map[ value_type ] = bindings.proper_indent( level1_template )
+      level2_map[ value_type ] = bindings.proper_indent( level2_template )
+
+    #
+    # LEVEL 1 and 2 FINALIZATION
+    #
+    for mapping in [ level1_map, level2_map ]:
+      if len(mapping) > 1:
+        # compare real and complex cases
+        all_keys = mapping.keys()
+        if mapping[ all_keys[0] ] == mapping[ all_keys[1] ]:
+          print "literally everything is the same!!, falling back to 1 case"
+          del mapping[ all_keys[ 1 ] ]
+
+    level1 = ''
+    if len( level1_map ) > 1:
+      level1 = template_map[ 'level1_pre_header' ]
+      includes += [ '#include <boost/utility/enable_if.hpp>' ]
+      includes += [ '#include <boost/numeric/bindings/traits/is_real.hpp>' ]
+      includes += [ '#include <boost/numeric/bindings/traits/is_complex.hpp>' ]
+
+    for value_type in level1_map.keys():
+      if len( level1_map ) == 1:
+        header = template_map[ 'level1_header1' ]
+      else:
+        header = template_map[ 'level1_header2' ]
+
+      level1 += header.replace( "$SPECIALIZATION", value_type )
+      level1 += level1_map[ value_type ]
+
+    level2 = ''
+    for value_type in level2_map.keys():
+      level2 += level2_map[ value_type ]
+
+    #
+    # handle addition of includes
+    #
+    includes_code = ''
+    unique_includes = []
+    for include in includes:
+      if include not in unique_includes:
+        unique_includes += [ include ]
+    sorted_includes = sorted( unique_includes, lambda x, y: cmp( x.lower(), y.lower() ) )
+    if len( sorted_includes ) > 0:
+      includes_code = "\n".join( sorted_includes )
+
+    result = template_map[ 'lapack.hpp' ]
+    result = result.replace( '$INCLUDES', includes_code )
+    result = result.replace( '$OVERLOADS', overloads )
+    result = result.replace( '$LEVEL1', level1 )
+    result = result.replace( '$LEVEL2', level2 )
+    result = result.replace( '$GROUPNAME', group_name )
+    result = result.replace( '$groupname', group_name.lower() )
+
+    # replace the global variables as last (this is convenient)
+    #result = result.replace( '$INDENT', '    ' )
+    #result = result.replace( '$groupname', group_name.lower() )
+    #result = result.replace( '$DESCRIPTION', info_map[ group[g][0] ][ 'description' ] )
+
+    open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+#
+# Write the (many) driver routine test cases to cpp files.
+#
+def write_test_case( info_map, group, template_map, base_dir, level_name ):
+
+  for group_name, subroutines in group.iteritems():
+
+    filename = group_name.lower() + '.cpp'
+    result = template_map[ 'test_case.cpp' ]
+    result = result.replace( '$groupname', group_name.lower() )
+    result = result.replace( '$levelname', level_name.lower() )
+
+    open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+def write_cmakefile( level_properties, template_map, base_dir ):
+  
+  entries = '' 
+  for problem_type, problem_properties in level_properties.iteritems():
+    if problem_properties.has_key( 'routines_by_value_type' ):
+      group = problem_properties[ 'routines_by_value_type' ]
+      for group_name, subroutines in group.iteritems():
+        sub_result = template_map[ 'CMakeLists.entry' ]
+        sub_result = sub_result.replace( '$groupname', group_name.lower() )
+        entries += sub_result
+
+  filename = 'CMakeLists.txt'
+  result = template_map[ 'CMakeLists.txt' ]
+  result = result.replace( '$ENTRIES', entries )
+  open( os.path.join( base_dir, filename ), 'wb' ).write( result )
+
+
+def read_templates( template_file ):
+  file_contents = open( template_file ).read()
+  split_regex = re.compile( '^\$TEMPLATE\[([^\]]+)\]\s', re.M | re.S )
+  split_templates = split_regex.split( file_contents )[ 1:-1 ]
+  result = {}
+  for index in range(len(split_templates)/2):
+    print "Adding template", split_templates[ index*2 ]
+    result[ split_templates[ index*2 ] ] = split_templates[ index*2 + 1 ]
+  return result
+
+lapack_src_path = './lapack-3.1.1/SRC'
+template_src_path = './templates'
+bindings_target_path = '../../../../boost/numeric/bindings/lapack/'
+test_target_path = '../test/lapack/'
+
+templates = {}
+templates[ 'PARSERMODE' ] = 'LAPACK'
+for root, dirs, files in os.walk( template_src_path ):
+  right_file = re.compile( '^.+\.(cpp|h|hpp|txt)$' )
+  for template_file in files:
+    if right_file.match( template_file ) != None:
+      path_to_template_file = os.path.join( root, template_file )
+      print "Reading template file", path_to_template_file
+      templates.update( read_templates( path_to_template_file ) )
+
+function_info_map = {}
+for lapack_file in os.listdir( lapack_src_path ):
+  right_file = re.compile( '^[cdsz].+\.f$' )
+  if right_file.match( lapack_file ) != None:
+    print "Parsing", lapack_file, "..."
+    key, value = netlib.parse_file( os.path.join( lapack_src_path, lapack_file ), templates )
+    if key != None and value != None:
+      print "Adding LAPACK subroutine", key
+      function_info_map[ key ] = value
+
+print "Grouping subroutines..."
+
+value_type_groups = {}
+value_type_groups = group_by_value_type( function_info_map )
+
+routines = {}
+routines[ 'driver' ] = {}
+routines[ 'driver' ][ 'linear_equations' ] = {}
+routines[ 'driver' ][ 'linear_equations' ][ 'endings' ] = [ 'SV', 'SVX' ]
+
+routines[ 'driver' ][ 'least_squares' ] = {}
+routines[ 'driver' ][ 'least_squares' ][ 'endings' ] = [ 'LS', 'LSY', 'LSS', 'LSD' ]
+
+routines[ 'driver' ][ 'general_least_squares' ] = {}
+routines[ 'driver' ][ 'general_least_squares' ][ 'endings' ] = [ 'LSE', 'GLM' ]
+
+# based on LAPACK Users' Guide, table 2.5
+routines[ 'driver' ][ 'eigen' ] = {}
+routines[ 'driver' ][ 'eigen' ][ 'endings' ] = [ 'YEV', 'EEV', 'YEVX', 'EEVX', 'YEVD', 'EEVD', 'YEVR', 'EEVR', 'EES', 'PEV', 'PEVD', 'PEVX', 'BEV', 'BEVD', 'BEVX', 'EESX', 'ESVD', 'ESDD', 'TEV', 'TEVD', 'TEVX', 'TEVR' ]
+
+# based on LAPACK Users' Guide, table 2.6
+routines[ 'driver' ][ 'general_eigen' ] = {}
+routines[ 'driver' ][ 'general_eigen' ][ 'endings' ] = [ 'GV', 'GVD', 'GVX', 'GES', 'GESX', 'GEV', 'GEVX', 'GSVD' ]
+
+
+routines[ 'computational' ] = {}
+
+# based on LAPACK Users' Guide, table 2.7
+routines[ 'computational' ][ 'linear_equations' ] = {}
+routines[ 'computational' ][ 'linear_equations' ][ 'endings' ] = [ 'TRF', 'TRS', 'CON', 'RFS', 'TRI', 'EQU' ]
+
+# based on LAPACK Users' Guide, table 2.9 
+routines[ 'computational' ][ 'least_squares' ] = {}
+routines[ 'computational' ][ 'least_squares' ][ 'endings' ] = [ 'QP3', 'EQRF', 'GQR', 'MQR', 'LQF', 'GLQ', 'MLQ', 'QLF', 'GQL', 'MQL', 'ERQF', 'GRQ', 'MRQ', 'RZF', 'RZ' ]
+
+routines[ 'computational' ][ 'general_least_squares' ] = {}
+routines[ 'computational' ][ 'general_least_squares' ][ 'endings' ] = [ 'GQRF', 'GRQF' ]
+
+# based on LAPACK Users' Guide, table 2.10
+routines[ 'computational' ][ 'symmetric_eigen' ] = {}
+routines[ 'computational' ][ 'symmetric_eigen' ][ 'endings' ] = [ 'TRD', 'MTR', 'GTR', 'TEQR', 'ERF', 'EDC', 'EGR', 'EBZ', 'TEIN' ]
+
+# based on LAPACK Users' Guide, table 2.11
+routines[ 'computational' ][ 'nonsymmetric_eigen' ] = {}
+routines[ 'computational' ][ 'nonsymmetric_eigen' ][ 'endings' ] = [ 'EHRD', 'EBAL', 'EBAK', 'GHR', 'MHR', 'SEQR', 'SEIN', 'REVC', 'REXC', 'RSYL', 'RSNA', 'RSEN' ]
+
+# based on LAPACK Users' Guide, table 2.12
+routines[ 'computational' ][ 'svd' ] = {}
+routines[ 'computational' ][ 'svd' ][ 'endings' ] = [ 'BRD', 'GBR', 'MBR', 'SQR', 'SDC' ]
+
+# based on LAPACK Users' Guide, table 2.14
+routines[ 'computational' ][ 'general_eigen' ] = {}
+routines[ 'computational' ][ 'general_eigen' ][ 'endings' ] = [ 'GST', 'STF' ]
+
+# based on LAPACK Users' Guide, table 2.15
+routines[ 'computational' ][ 'general_nonsymmetric_eigen' ] = {}
+routines[ 'computational' ][ 'general_nonsymmetric_eigen' ][ 'endings' ] = [ 'GHRD', 'GBAL', 'GBAK', 'EQZ', 'GEVC', 'GEXC', 'GSYL', 'GSNA', 'GSEN' ]
+
+# based on LAPACK Users' Guide, table 2.16
+routines[ 'computational' ][ 'general_nonsymmetric_svd' ] = {}
+routines[ 'computational' ][ 'general_nonsymmetric_svd' ][ 'endings' ] = [ 'SVP', 'SJA' ]
+
+for name in value_type_groups.keys():
+  found = False
+  for level, level_properties in routines.iteritems():
+    for problem_type, problem_properties in level_properties.iteritems():
+      if name[ -2: ] in problem_properties[ 'endings' ] or \
+         name[ -3: ] in problem_properties[ 'endings' ] or \
+         name[ -4: ] in problem_properties[ 'endings' ]:
+        print name, "is in {"+level+", "+  problem_type + "}"
+        if not problem_properties.has_key( 'routines_by_value_type' ):
+          problem_properties[ 'routines_by_value_type' ] = {}
+        problem_properties[ 'routines_by_value_type' ][ name ] = value_type_groups[ name ]
+        found = True
+  if found == False:
+    print name, "is in {??}"
+
+print routines 
+
+
+bindings.write_names_header( function_info_map, value_type_groups, templates, bindings_target_path + 'lapack_names.h' )
+bindings.write_header( function_info_map, value_type_groups, templates, bindings_target_path + 'lapack.h' )
+
+for level, level_properties in routines.iteritems():
+  target_path = bindings_target_path + level
+  if not os.path.exists( target_path ):
+    os.mkdir( target_path )
+  if not os.path.exists( test_target_path + level ):
+    os.mkdir( test_target_path + level )
+
+  for problem_type, problem_properties in level_properties.iteritems():
+    if problem_properties.has_key( 'routines_by_value_type' ):
+      write_functions( function_info_map, problem_properties[ 'routines_by_value_type' ], templates, target_path )
+
+      write_test_case( function_info_map, problem_properties[ 'routines_by_value_type' ], templates, test_target_path + level, level )
+
+  write_cmakefile( level_properties, templates, test_target_path + level )
+
+
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/netlib.py	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,1064 @@
+#!/usr/bin/python
+#
+#  Copyright (c) 2008 Thomas Klimpel and Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+
+import re, os.path, copy
+from types import StringType
+
+# for debugging purposes
+import pprint
+
+
+global_type_map = { 
+  'CHARACTER': 'char',
+  'LOGICAL': 'logical_t', 
+  'INTEGER': 'integer_t',
+  'REAL': 'float', 
+  'DOUBLE PRECISION': 'double' }
+  
+templates = {}
+
+
+  
+def c_type( name, properties ):
+  m_type_map = global_type_map
+  m_type_map[ 'COMPLEX' ] = 'fcomplex_t'
+  m_type_map[ 'COMPLEX*16' ] = 'dcomplex_t'
+  m_type_map[ 'DOUBLE COMPLEX' ] = 'dcomplex_t'
+
+  result = m_type_map[ properties[ 'value_type' ] ];
+  if properties[ 'io' ] == [ 'input' ]:
+    result += ' const'
+  result += '*'
+  result += ' ' + name.lower()  # is this really needed?
+  
+  return result
+  
+  
+def cpp_type( name, properties ):
+  m_type_map = global_type_map
+  m_type_map[ 'COMPLEX' ] = 'traits::complex_f'
+  m_type_map[ 'COMPLEX*16' ] = 'traits::complex_d'
+  
+  result = m_type_map[ properties[ 'value_type' ] ]
+  
+  if properties[ 'type' ] == 'scalar':
+    if properties[ 'io' ] == [ 'input' ]:
+      result += ' const'
+    elif properties[ 'io' ] == [ 'external procedure' ]:
+      result += '*'
+    else:
+      result += '&'
+    
+  if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+    result += '*'
+    
+  result += ' ' + name.lower()
+    
+  return result
+  
+def call_c_type( name, properties ):
+  result = ''
+  if properties[ 'type' ] == 'vector' or properties[ 'type' ] == 'matrix':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+      result = 'traits::complex_ptr(' + name.lower() + ')'
+    else:
+      result = name.lower()
+  elif properties[ 'type' ] == 'scalar':
+    if properties[ 'value_type' ][ 0:7] == 'COMPLEX':
+      result = 'traits::complex_ptr(&' + name.lower() + ')'
+    else:
+      result = '&' + name.lower()
+  
+  return result
+  
+
+def call_level0_type( name, properties, arg_map ):
+  result = ''
+  if properties[ 'type' ] == 'matrix':
+    result = "traits::matrix_storage(" + name.lower() + ")"
+  elif properties[ 'type' ] == 'vector':
+    my_name = name.lower()
+    if 'workspace' in properties[ 'io' ]:
+      my_name = 'work.select(' + workspace_type( name, properties ) + '())'
+    result = "traits::vector_storage(" + my_name + ")"
+  elif properties.has_key( 'trait_type' ):
+    if properties[ 'trait_type' ] == 'lda':
+      result = "traits::leading_dimension(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'num_columns':
+      result = "traits::matrix_size2(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'num_rows':
+      result = "traits::matrix_size1(" + properties[ 'trait_of' ].lower() + ")"
+    if properties[ 'trait_type' ] == 'size':
+      my_name = properties[ 'trait_of' ].lower()
+      referring_to_properties = arg_map[ properties[ 'trait_of' ] ]
+      if 'workspace' in referring_to_properties[ 'io' ]:
+        my_name = 'work.select(' + workspace_type( properties[ 'trait_of' ].lower(), referring_to_properties ) + \
+                  '())'
+      result = "traits::vector_size(" + my_name + ")"
+    if properties[ 'trait_type' ] == 'uplo':
+      result = "traits::matrix_uplo_tag(" + properties[ 'trait_of' ].lower() + ")"
+  else:
+    result = name.lower()
+  return result
+
+
+def level1_type( name, properties ):
+  result = None
+  if not properties.has_key( 'trait_of' ) and 'workspace' not in properties[ 'io' ]:
+    if properties[ 'type' ] == 'matrix':
+      result = "Matrix" + name + "& " + name.lower()
+    elif properties[ 'type' ] == 'vector':
+      result = "Vector" + name + "& " + name.lower()
+    else:
+      result = cpp_type( name, properties )
+      if properties[ 'value_type' ] == 'REAL':
+        result = result.replace( "float", "real_type" )
+      if properties[ 'value_type' ] == 'DOUBLE PRECISION':
+        result = result.replace( "double", "real_type" )
+  return result
+
+
+def level2_type( name, properties ):
+  result = level1_type( name, properties )
+  if name == 'INFO' and 'output' in properties[ 'io' ]:
+    result = None
+
+  if result != None:
+    if properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+      result = result.replace( "real_type", "typename traits::$TYPEOF_FIRST_TYPENAME" + \
+        "_traits< $FIRST_TYPENAME >::value_type" )
+
+  return result
+
+
+def level1_typename( name, properties ):
+  result = None
+  if 'workspace' not in properties[ 'io' ]:
+    if properties[ 'type' ] == 'matrix':
+      result = "typename Matrix" + name
+    if properties[ 'type' ] == 'vector':
+      result = "typename Vector" + name
+  return result
+
+
+
+def nested_list_args( arg ):
+  print "finding nested list arguments of", arg
+  if type( arg ) == StringType:
+    if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+      return [ None ]
+    else:
+      return [ arg.upper() ]
+  
+  # we are dealing with a list-type, e.g., 
+  # [ '*', [ 'A', 'B' ] ]
+  # [ 'A', 'B' ]
+  result = []
+  if re.compile( '^[A-Z]+$' ).match( arg[0] ) == None:
+    for a in arg[1]:
+      sub_result = nested_list_args( a )
+      if sub_result != [ None ]:
+        for r in sub_result:
+          if r not in result:
+            result.append( r )
+
+  else:
+    for a in arg:
+      result.append( a )
+
+  print "returning ",result
+  return result
+
+
+
+
+def expand_nested_list( arg, arg_map, use_arg_map = True ):
+
+  print "Expanding nested list: ", arg, len(arg)
+  if type( arg ) == StringType:
+    print "Type is string"
+    # .....
+    if re.compile( '^[A-Z]+$' ).match( arg ) == None:
+      return arg
+    else:
+      if use_arg_map:
+        if not arg_map.has_key( arg ):
+          return '?' + arg.upper()
+        else:
+          return arg_map[ arg ][ 'code' ][ 'call_level_0' ]
+      else:
+        return arg.lower()
+    
+  if arg[0] == '()':
+    result = '(' + expand_nested_list( arg[1], arg_map, use_arg_map ) + ')'
+    return result
+    
+  if arg[0] == 'max' or arg[0] == 'min':
+    print "arg1: ", arg[1]
+    result = 'std::' + arg[0] + '('
+    i = 0
+    for a in arg[1]:
+      result += expand_nested_list( a, arg_map, use_arg_map )
+      i += 1
+      if i != len(arg[1]):
+        result += ","
+    result += ')'
+    return result
+  
+  if arg[0] == '*' or arg[0] == '/' or arg[0] == '+' or arg[0] == '-':
+    print "arg1: ", arg[1]
+    arg_list = []
+    for a in arg[1]:
+      arg_list += [ expand_nested_list( a, arg_map, use_arg_map ) ]
+    result = arg[0].join( arg_list )
+    return result
+  
+  print "ERROR: Don't know what to do!!"
+  return 'ERROR'
+
+def level1_assert( name, properties, arg_map ):
+  result = None
+  
+  if properties.has_key( 'assert_char' ):
+    result = "assert( "
+    result_array = []
+    for char in properties[ 'assert_char' ]:
+      result_array += [ call_level0_type( name, properties, arg_map ) + ' == \'' + char + '\'' ]
+    result += " || ".join( result_array )
+    result += " );"
+    
+  if properties.has_key( 'assert_ge' ) and not properties.has_key( 'workspace_query_for' ):
+    result = "assert( " + call_level0_type( name, properties, arg_map ) + " >= " + expand_nested_list( properties[ 'assert_ge' ], arg_map ) + ' );'
+      
+  if 'workspace' in properties[ 'io' ]:
+    min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+    if min_workspace_call == None:
+      min_workspace_call = '$CALL_MIN_SIZE'
+    result = 'assert( traits::vector_size(work.select(' + workspace_type( name, properties ) + '()) >= ' + \
+             'min_size_' + name.lower() + '( ' + min_workspace_call + ' )));'
+  
+  elif properties.has_key( 'assert_size' ):
+    result = "assert( traits::vector_size(" + call_level0_type( name, properties, arg_map ) + ") >= " + \
+      expand_nested_list( properties[ 'assert_size' ], arg_map ) + ' );'
+  
+  return result
+
+
+def call_level1_type( name, properties ):
+  result = None
+  if level1_type( name, properties ) != None:
+    result = name.lower()
+  return result
+
+
+def workspace_type( name, properties ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties[ 'value_type' ] == 'INTEGER':
+      result = 'integer_t'
+    elif properties[ 'value_type' ] == 'LOGICAL':
+      result = 'bool'
+    elif properties[ 'value_type' ] == 'REAL' or properties[ 'value_type' ] == 'DOUBLE PRECISION':
+      result = 'real_type'
+    else: 
+      result = 'value_type'
+  return result
+
+
+
+
+def opt_workspace_pre_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      result = workspace_type( name, properties ) + ' opt_size_' + name.lower() + ';'
+    else:
+      min_workspace_call = min_workspace_call_type( name, properties, arg_map )
+      if min_workspace_call == None:
+        min_workspace_call = '$CALL_MIN_SIZE'
+      result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( min_size_' + name.lower() + '( ' + min_workspace_call + ' ) );'
+  return result
+
+
+def opt_workspace_post_type( name, properties ):
+  result = None
+  if 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      if properties['value_type'] == 'INTEGER':
+        result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( opt_size_' + name.lower() + ' );'
+      else:
+        result = 'traits::detail::array< ' + workspace_type( name, properties ) + ' >' + \
+               ' tmp_' + name.lower() + '( traits::detail::to_int( opt_size_' + name.lower() + ' ) );'
+  return result
+
+
+
+def opt_workspace_query_type( name, properties, arg_map ):
+  result = None
+  if properties.has_key( 'workspace_query_for' ):
+    result = '-1'
+  elif 'workspace' in properties[ 'io' ]:
+    if properties.has_key( 'workspace_query_by' ):
+      result = '&opt_size_' + name.lower();
+    else:
+      result = 'traits::vector_storage(tmp_' + name.lower() + ')'
+  else:
+    result = call_level0_type( name, properties, arg_map )
+  return result
+
+
+def min_workspace_size_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size' ):
+    result = expand_nested_list( properties[ 'assert_size' ], arg_map, False );
+  return result
+
+
+def min_workspace_arg_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+    code_result = []
+    for arg in properties[ 'assert_size_args' ]:
+      if arg_map.has_key( arg ):
+        code_result += [ cpp_type( arg, arg_map[ arg ] ) ]
+      else:
+        code_result += [ '?' + arg.upper() ]
+    result = ", ".join( code_result )
+  return result
+
+
+def min_workspace_call_type( name, properties, arg_map ):
+  result = None
+  if 'workspace' in properties[ 'io' ] and properties.has_key( 'assert_size_args' ):
+    code_result = []
+    for arg in properties[ 'assert_size_args' ]:
+      if arg_map.has_key( arg ):
+        code_result += [ call_level0_type( arg, arg_map[ arg ], arg_map ) ]
+      else:
+        code_result += [ '?' + arg.upper() ]
+      
+    result = ", ".join( code_result )
+  return result
+
+
+def user_defined_type( name, properties, arg_map ):
+  result = None
+  if properties.has_key( 'user_defined' ):
+    result = properties[ 'user_defined' ]
+  return result
+
+
+
+#
+#
+#
+#
+def match_formulae( text_field ):
+  find_start = re.compile( '([A-Z]+)\s?(>=|is\sat\sleast)\s?(.*)the\scode\swill', re.M | re.S ).findall( text_field )
+  for element in find_start:
+    print element
+
+
+
+#
+# Split string using a list of delimiters
+# Delimiters may be substrings of length 1 or 2 (may be increased if necessary)
+#
+def split_delim( s, delim = [','] ):
+  result = []
+  parentheses = 0
+  cur_pos = 0
+  prev_pos = 0
+  for index in range( 0, len(s) ):
+    if s[ index ] == '(': 
+      parentheses += 1
+    elif s[ index ] == ')':
+      parentheses -= 1
+    for length in range( 1, 3 ):
+      if index >= (length-1) and parentheses == 0:
+        c = s[ index-(length-1): index+1 ]
+        if c in delim:
+          result += [ s[ prev_pos:(index-(length-1)) ] ]
+          prev_pos = index+1
+          
+  result += [ s[ prev_pos:len(s) ] ]
+  return result
+
+
+
+#
+# Look for implicit products, like 5N, and replace with 5*N
+#
+def replace_implicit_products( text_field ):
+  result = re.sub( '([0-9])+([A-Z]+)', '\\1*\\2', text_field )
+  return result
+
+
+
+
+def decompose_formula( text_field ):
+  text_field = text_field.strip()
+  print "Decompose: ", text_field
+  
+  if text_field[0] == '(' and text_field[-1] == ')':
+    result = text_field[ 1:-1 ]
+    return [ '()', decompose_formula( result ) ]
+  
+  if len( split_delim( text_field, [ ',' ] ) ) > 1:
+    print "ERROR! (in LAPACK?)"
+    return [ 'ERROR' ]
+  
+  #
+  # Detect leaf: if text_field equals a argument (like N), or a number
+  #  
+  if re.compile( '^([a-zA-Z]+|[0-9]+)$' ).match( text_field ):
+    print "decompose: at leaf: '" + text_field + "'"
+    return text_field.upper()
+  
+  
+  if len( split_delim( text_field, [ '**' ] ) ) > 1:
+    print 'decompose: inserting pow'
+    arguments = split_delim( text_field, [ '**' ] )
+    print arguments
+    result = []
+    for arg in arguments:
+      result.append( decompose_formula( arg ) )
+    return [ 'pow', result ]
+  
+  for operator in [ '*', '/', '+', '-' ]:
+    if len( split_delim( text_field, [ operator ] ) ) > 1:
+      print 'decompose: inserting ' + operator
+      arguments = split_delim( text_field, operator )
+      print arguments
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      return [ operator, result ]
+    
+  
+  if (text_field[ 0:4 ] == 'max(' or text_field[ 0:4 ] == 'MAX(') and \
+    text_field[ -1 ] == ')':
+    print "decompose: inserting max"
+    arguments = split_delim( text_field[ 4:-1 ] )
+    print arguments, len(arguments)
+    # keep max a binary function ... :-)
+    if len( arguments ) > 2:
+      return [ 'max', [ decompose_formula( arguments[0] ), decompose_formula( 'max(' + ",".join( arguments[1:] ) + ')' ) ] ]
+    else:  
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+      return [ 'max', result ]
+  
+
+  if (text_field[ 0:4 ] == 'min(' or text_field[ 0:4 ] == 'MIN(') and \
+    text_field[ -1 ] == ')':
+    print "decompose: inserting min"
+    arguments = split_delim( text_field[ 4:-1 ] )
+    print arguments, len(arguments)
+    # keep max a binary function ... :-)
+    if len( arguments ) > 2:
+      return [ 'min', [ decompose_formula( arguments[0] ), decompose_formula( 'min(' + ",".join( arguments[1:] ) + ')' ) ] ]
+    else:  
+      result = []
+      for arg in arguments:
+        result.append( decompose_formula( arg ) )
+      #result = [ decompose_formula( arguments[0] ), decompose_formula( arguments[1] ) ]
+      return [ 'min', result ]
+  
+
+#
+#
+def match_assert_ge( argument_map, text_field ):
+  #print "Match assert GE..."
+  match_it = re.compile( ' +[A-Z]+[ ]{0,3}(>=|must be at least)[ ]{0,3}([0-9]|(min|max|MIN|MAX|[\(\)\,0-9A-Z\+\*\-])+)' ).findall( text_field )
+  if len( match_it ) == 1:
+    print "Match assert GE:", match_it
+    #print match_it
+    #if len( match_it[ 0 ][ 2 ] ) > 0:
+    return decompose_formula( match_it[ 0 ][ 1 ] )
+  else:
+    print "nr of matches: ", len( match_it )
+    return None
+  
+
+
+
+
+# try different keys, return the one that exists, if any
+
+def my_has_key( key_name, template_map ):
+  # try, e.g., gelsd.all.
+  m_all_key = key_name.replace( ".complex", ".all" ).replace( ".real", ".all" )
+  if template_map.has_key( key_name ):
+    print "using key ", key_name
+    return key_name
+  if template_map.has_key( m_all_key ):
+    print "using key ", m_all_key
+    return m_all_key
+  print "tried keys ", key_name, "and", m_all_key,", no results"
+  return None
+
+
+
+#
+# Default user-defined arg is of type scalar INTEGER
+#
+def add_user_defined_args( arg, argument_map, template_map, base_name ):
+  print "Trying to add user-defined argument definitions for", arg
+
+  argument_map[ arg ] = {}
+
+  base_key = base_name.lower() + '.' + arg
+  print "base_key",base_key
+
+  if my_has_key( base_key + '.value_type', template_map ) != None:
+    argument_map[ arg ][ 'value_type' ] = template_map[ my_has_key( base_key + '.value_type', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'value_type' ] = 'INTEGER'
+
+  if my_has_key( base_key + '.type', template_map ) != None:
+    argument_map[ arg ][ 'type' ] = template_map[ my_has_key( base_key + '.type', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'type' ] = 'scalar'
+
+  if my_has_key( base_key + '.init', template_map ) != None:
+    argument_map[ arg ][ 'user_defined' ] = template_map[ my_has_key( base_key + '.init', template_map ) ].strip()
+  else:
+    argument_map[ arg ][ 'user_defined' ] = 'UNDEFINED'
+
+  argument_map[ arg ][ 'io' ] = [ 'input' ]
+
+  return
+
+
+
+
+
+
+
+#
+# Parse a LAPACK file
+# input: filename
+# output: a pair of ( function name, map )
+#         the map contains: 
+#         'arguments': an array of arguments
+#         'argument_map': a map of ( argument_name, property ), 
+#                     in which property can be
+#            'type': Fortran type
+#            'cpptype': C++ type
+#            'io': the (input/output) part from the comment section
+#
+def parse_file( filename, template_map ):
+
+  # for nice printing
+  pp = pprint.PrettyPrinter( indent = 2 )
+
+  # read the entire fortran source file
+  source = open( filename ).read()
+
+  # parse and split the code 
+  # * merge multilines to one line (using the $ and + characters)
+  # * split comments-blocks and code blocks
+  # * remove '*' from comments
+  # input:  full source code
+  # output: an array of lines of code
+  #         an array of lines of comments
+  code = []
+  comments = []
+  for i in source.splitlines():
+
+    # Special case: in e.g. CHEEVR comments are lead by many stars instead of 1
+    # replace those (more than 1) with spaces so that it becomes a regular comment
+    # block.
+    leading_stars = re.compile( '^[ ]*\*(\*+)' ).match( i )
+    if leading_stars != None:
+      spaces = i[ leading_stars.start(1):leading_stars.end(1) ].replace( '*', ' ' )
+      i = i[0:leading_stars.start(1)] + spaces + \
+        i[leading_stars.end(1):len(i)]
+
+    # Continue for the regular case
+    match_comment = re.compile( '^[ ]*\*(.*)' ).search( i )
+    if match_comment == None:
+      match_multi = re.compile( '^[ ]*[\$\+][ ]*(.*)$' ).search( i )
+      if match_multi == None:
+        code += [ i ]
+      else:
+        code[-1 ] += match_multi.expand( "\\1" )
+    else:
+      comments += [ match_comment.expand( "\\1" ) ]
+
+  # Acquire important information
+  # * the subroutine name
+  # * the arguments of the subroutine
+  subroutine_found = False
+  subroutine_name = ''
+  subroutine_arguments = []
+  code_line_nr = 0
+  while code_line_nr < len(code) and not subroutine_found:
+    match_subroutine_name = re.compile( 'SUBROUTINE[ ]+([A-Z]+)\(([^\)]+)' ).search( code[ code_line_nr ] )
+    if match_subroutine_name != None:
+      subroutine_found = True
+      subroutine_name = match_subroutine_name.group( 1 )
+      subroutine_arguments = match_subroutine_name.group( 2 ).replace( ' ', '' ).split( "," )
+    code_line_nr += 1
+
+  # If we could not find a subroutine, we quit at our earliest convenience
+  if code_line_nr == len(code):
+    return None, None
+
+  #
+  # Do some further analysis as to what kind of routine this is
+  #
+  subroutine_group_name = subroutine_name[ 1: ]
+  subroutine_value_type = None
+  if subroutine_name[0] == 'C' or subroutine_name[0] == 'Z':
+    subroutine_value_type = 'complex'
+  if subroutine_name[0] == 'S' or subroutine_name[0] == 'D':
+    subroutine_value_type = 'real'
+
+  print "Subroutine: ", subroutine_name
+  print "Arguments:  ", len(subroutine_arguments),":",subroutine_arguments
+  print "Group name: ", subroutine_group_name
+  print "Variant:    ", subroutine_value_type
+
+  # Now we have the names of the arguments. The code following the subroutine statement are
+  # the argument declarations. Parse those right now, splitting these examples
+  #      INTEGER            INFO, LDA, LDVS, LWORK, N, SDIM
+  #      COMPLEX            A( LDA, * ), VS( LDVS, * ), W( * ), WORK( * )
+  # into a map containing
+  #      INFO: value_type=INTEGER, type=scalar
+  #      WORK: value_type=COMPLEX, type=vector
+  #         A: value_type=COMPLEX, type=matrix, leading_dimension=LDA
+  # etc.
+  arguments_found = False
+  argument_map = {}
+  while code_line_nr < len(code) and len( argument_map ) < len( subroutine_arguments ):
+    match_argument_declaration = re.compile( '^[ ]*(EXTERNAL|LOGICAL|CHARACTER|REAL|INTEGER' + \
+      '|DOUBLE PRECISION|DOUBLE COMPLEX|COMPLEX\*16|COMPLEX)[ ]+(.*)$' ).search( code[ code_line_nr] )
+    if match_argument_declaration != None:
+      for argument_match in re.findall( '([A-Z0-9]+(\([^\)]+\))?)[, ]?', match_argument_declaration.group( 2 ) ):
+        argument_description = argument_match[0].strip().split( "(" )
+        argument_name = argument_description[0]
+        argument_map[ argument_name ] = {}
+        argument_map[ argument_name ][ 'value_type' ] = match_argument_declaration.group( 1 )
+        if len(argument_description) == 1:
+          argument_map[ argument_name ][ 'type' ] = 'scalar'
+        else:
+          if argument_description[1].find( "," ) == -1:
+            argument_map[ argument_name ][ 'type' ] = 'vector'
+          else:
+            argument_map[ argument_name ][ 'type' ] = 'matrix'
+            # check if there is a leading dimension
+            argument_map[ argument_name ][ 'leading_dimension' ] = argument_description[1].split( "," )[0].strip()
+    code_line_nr += 1
+
+  # Create convenience lookups by value_type and types of arguments
+  # e.g., grouped_arguments[ 'by_value_type' ][ 'INTEGER' ] will give an array of all integer types
+  #       grouped_arguments[ 'by_type' ][ 'matrix' ] will give an array of all matrices
+  grouped_arguments = {}
+  key_array = [ 'type', 'value_type' ]
+  for s in key_array:
+    grouped_arguments[ 'by_' + s ] = {}
+  # make sure the order of argument names is the same as those in the subroutine argument order
+  for argument_name in subroutine_arguments:
+    argument_properties = argument_map[ argument_name ]
+    for s in key_array:
+      if not grouped_arguments[ 'by_' + s ].has_key( argument_properties[ s ] ):
+        grouped_arguments[ 'by_' + s ][ argument_properties[ s ] ] = []
+      grouped_arguments[ 'by_' + s ][ argument_properties[ s ] ] += [ argument_name ]
+
+  # The next bulk load of information can be acquired from the comment fields, 
+  # this is between "Purpose" and "Arguments". Locate those headers, and init with
+  # -1 so that we can check if they where found.
+  comment_line_nr = 0
+  purpose_line_nr = -1
+  arguments_line_nr = -1
+  while comment_line_nr < len(comments) and purpose_line_nr == -1:
+    if re.compile( '^[ ]+Purpose[ ]*$' ).search( comments[ comment_line_nr ] ) != None:
+      purpose_line_nr = comment_line_nr
+    comment_line_nr += 1
+
+  while comment_line_nr < len(comments) and arguments_line_nr == -1:
+    if re.compile( '^[ ]+Arguments[ ]*$' ).search( comments[ comment_line_nr ] ) != None:
+      arguments_line_nr = comment_line_nr
+    comment_line_nr += 1
+
+  # Gather the actual subroutine purpose. This is always following the Purpose title (obvious :-))
+  # and stopping before the "Arguments" block.
+  subroutine_purpose = ''
+  if purpose_line_nr > 0 and arguments_line_nr > 0:
+    subroutine_purpose = "//" + "\n//".join( comments[ purpose_line_nr+3:arguments_line_nr-1 ] )
+
+  # Break up the comments
+  # Now, for each argument, locate its associated comment field
+  #
+  # In this case, for M, we store the range [45, 48>
+  no_commented_arguments = 0
+  if arguments_line_nr > 0:
+    preceding_argument = ''
+    finished_the_last = False
+    detected_lapack_style = False
+    detected_blas_style = False
+    while comment_line_nr < len(comments) and not finished_the_last:
+
+      # Example for LAPACK-style matching. 
+      # 45 M       (input) INTEGER
+      # 46         The number of rows of the matrix A. M >= 0.
+      # 47
+      # 48 N       (input) INTEGER
+      match_lapack_style = re.compile( '^[\s]*([A-Z]+[2]?)[\s]+\(([a-z/ ]+)\)' ).search( comments[ comment_line_nr ] )
+      if not detected_blas_style and match_lapack_style != None:
+        detected_lapack_style = True
+        argument_name = match_lapack_style.group(1)
+        argument_map[ argument_name ][ 'comment_lines' ] = [ comment_line_nr ]
+        split_regex = re.compile( '\/| or ' )
+        argument_map[ argument_name ][ 'io' ] = split_regex.split( match_lapack_style.group(2) )
+        if preceding_argument != '':
+          argument_map[ preceding_argument ][ 'comment_lines' ] += [ comment_line_nr ]
+        preceding_argument = argument_name
+        no_commented_arguments += 1
+
+      # Example for BLAS, which doesn't mention input/output on the same line
+      # 37 N      - INTEGER.
+      # 38          On entry, N specifies the order of the matrix A.
+      # 39          N must be at least zero.
+      # 40          Unchanged on exit.
+      match_blas_style = re.compile( '^[\s]*([A-Z]+[2]?)[\s]+\- [A-Z]+' ).search( comments[comment_line_nr] )
+      if not detected_lapack_style and match_blas_style != None:
+        detected_blas_style = True
+        argument_name = match_blas_style.group(1)
+        argument_map[ argument_name ][ 'comment_lines' ] = [ comment_line_nr ]
+        # default input/output with blas to output, this will be overwritten if "unchanged on exit" is
+        # found
+        argument_map[ argument_name ][ 'io' ] = [ 'output' ]
+        if preceding_argument != '':
+          argument_map[ preceding_argument ][ 'comment_lines' ] += [ comment_line_nr ]
+        preceding_argument = argument_name
+        no_commented_arguments += 1
+
+      # Detection for BLAS' "input" statement
+      match_unchanged_on_exit = re.compile( '^[\s]*[uU]nchanged on exit' ).search( comments[comment_line_nr] )
+      if detected_blas_style and match_unchanged_on_exit != None:
+        argument_map[ preceding_argument ][ 'io' ] = [ 'input' ]
+
+      # INFO comes last, so detect an empty line for this case
+      if no_commented_arguments == len( subroutine_arguments ) and \
+         len( argument_map[ preceding_argument ][ 'comment_lines' ] ) < 2:
+        match_empty_line = re.compile( '^[ ]*$' ).search( comments[ comment_line_nr ] )
+        if match_empty_line != None:
+          argument_map[ preceding_argument ][ 'comment_lines' ] += [ comment_line_nr + 1 ]
+          finished_the_last = True
+
+      comment_line_nr += 1
+
+    # Inform the debug.log / user which comment style we employed
+    if ( detected_lapack_style ):
+      print "Argument comment style: LAPACK"
+    elif ( detected_blas_style ):
+      print "Argument comment style: BLAS"
+
+  #
+  # TODO
+  # TODO
+  # TODO
+  #
+  if no_commented_arguments != len( subroutine_arguments ):
+    print str(no_commented_arguments) + " out of " + str(len(subroutine_arguments)) + \
+      " arguments are commented, bailing out"
+    return subroutine_name, None
+
+  #
+  # Make a back-reference to those arguments that are defined as leading dimension in the code
+  #
+  for argument_name, argument_properties in argument_map.iteritems():
+    if argument_properties.has_key( 'leading_dimension' ):
+      referring_argument_name = argument_properties[ 'leading_dimension' ]
+      if argument_map.has_key( referring_argument_name ):
+        argument_map[ referring_argument_name ][ 'trait_type' ] = 'lda'
+        argument_map[ referring_argument_name ][ 'trait_of' ] = argument_name
+
+  # Extend convenience lookups by io, recently acquired when processing the comment
+  # fields. We have to be sure arguments are processed in the right order.
+  grouped_arguments[ 'by_io' ] = {}
+  for argument_name in subroutine_arguments:
+    argument_properties = argument_map[ argument_name ]
+    print argument_name, argument_properties
+    for io_type in argument_properties[ 'io' ]:
+      if not grouped_arguments[ 'by_io' ].has_key( io_type ):
+        grouped_arguments[ 'by_io' ][ io_type ] = []
+      grouped_arguments[ 'by_io' ][ io_type ] += [ argument_name ]
+
+  #
+  # Parse the comment fields
+  #
+  user_defined_arg_map = {}
+  for argument_name, argument_properties in argument_map.iteritems():
+
+    print "\n\n**********"
+    print argument_name
+    comment_block = "\n".join( comments[ argument_properties[ 'comment_lines' ][0] : argument_properties[ 'comment_lines' ][1] ] )
+    print comment_block
+    match_formulae( comment_block )
+
+    #
+    # Handle scalar INTEGER comment blocks. Look for type traits stuff.
+    #
+    if argument_properties[ 'type' ] == 'scalar' and \
+       argument_properties[ 'value_type' ] == 'INTEGER':
+      #
+      # Fetch matrix traits such as "the number of columns of A"
+      #
+      match_matrix_traits = re.compile( '(rows|columns|order)(in|of|the|input|\s)+(matrix|matrices|\s)+' + \
+        '([A-Z]+\s+and\s+[A-Z]+|[A-Z]+)', re.M | re.S ).findall( comment_block )
+      if len( match_matrix_traits ) == 1:
+        if match_matrix_traits[0][0] == 'order':
+          # PANIC: return none
+          # e.g., in tridiagonal case, there is no matrix, but a number of 
+          # vectors (the diagonals)
+          if not grouped_arguments[ 'by_type' ].has_key( 'matrix' ):
+            # TODO
+            # TODO
+            return subroutine_name, None
+            # TODO
+            # TODO
+          if match_matrix_traits[0][3] in grouped_arguments[ 'by_type' ][ 'matrix' ]:
+            # because it is both #rows and #columns, we have to choose one
+            argument_properties[ 'trait_type' ] = 'num_columns'
+            argument_properties[ 'trait_of' ] = match_matrix_traits[0][3].strip()
+
+          # see if the traits are overruled through the template system
+          traits_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.' + argument_name + '.trait_of'
+          if my_has_key( traits_key, template_map ):
+            argument_properties[ 'trait_type' ] = 'num_columns'
+            argument_properties[ 'trait_of' ] = template_map[ my_has_key( traits_key, template_map ) ].strip()
+
+        else:
+          references = match_matrix_traits[0][3].split( 'and' )
+          for matrix_name in references:
+            if matrix_name.strip() in grouped_arguments[ 'by_type' ][ 'matrix' ]:
+              argument_properties[ 'trait_type' ] = 'num_' + match_matrix_traits[0][0]
+              argument_properties[ 'trait_of' ] = matrix_name.strip()
+
+      #
+      # Fetch array traits, such as "the length of the array WORK"
+      #
+      match_array_traits = re.compile( '(The length|The dimension)(of|the|\s)+(array|\s)+([A-Z]+)', re.M | re.S ).findall( comment_block )
+      if len( match_array_traits ) > 0 and match_array_traits[ 0 ][ 3 ] in grouped_arguments[ 'by_type' ][ 'vector' ]:
+        argument_properties[ 'trait_type' ] = 'size'
+        argument_properties[ 'trait_of' ] = match_array_traits[ 0 ][ 3 ]
+
+      # Fetch greater-than-or-equal-to integer asserts, such as 
+      # M >= 0.
+      # N >= max(...)
+      match_greater_equal = match_assert_ge( argument_map, comment_block )
+      if match_greater_equal != None:
+        argument_properties[ 'assert_ge' ] = match_greater_equal
+
+      # Are we dealing with a workspace-length integer?
+      # If so, try to detect the workspace-query text.
+      # And, try to detect for which work arrays the query will run.
+      # Keep the same order of workspace names as used in the grouped arguments map
+      if 'WORK' in argument_name:
+        match_query = re.compile( 'If ' + argument_name + ' \= \-1(\,|then|a|workspace|\s)+query', re.M ).search( comment_block )
+        if match_query != None:
+          work_query_block = comment_block[ match_query.start(0): ]
+          any_workspace = "(" + "|".join( grouped_arguments[ 'by_io' ][ 'workspace' ] ) + ")"
+          match_workspace = re.compile( '[^A-Z]' + any_workspace, re.M | re.S ).findall( work_query_block )
+          if len( match_workspace ) > 0:
+            argument_properties[ 'workspace_query_for' ] = []
+          for name in grouped_arguments[ 'by_io' ][ 'workspace' ]:
+            if name in match_workspace:
+              argument_properties[ 'workspace_query_for' ] += [ name ]
+
+    #
+    # Handle CHARACTER comment blocks.
+    # Try to get which variables are valid, to put this in asserts.
+    #
+    elif argument_properties[ 'value_type' ] == 'CHARACTER':
+      match_statements = re.compile( '=(\s|or|\'[0-9A-Z]\')+[:,]', re.M ).finditer( comment_block )
+      for statement in match_statements:
+        print "Statement:",statement.group(0)
+        match_letters = re.compile( '\'([0-9A-Z])\'' ).findall( statement.group(0) )
+        for letter in match_letters:
+          print "Letter",letter
+          if not argument_properties.has_key( 'assert_char' ):
+            argument_properties[ 'assert_char' ] = []
+          if not letter in argument_properties[ 'assert_char' ]:
+            argument_properties[ 'assert_char' ] += [ letter ]
+
+      if argument_name == 'UPLO':
+        match_uplo = re.compile( '(Upper|Lower)(triangle|triangles|of|input|matrix|\s)+([A-Z]+)' ).findall( comment_block )
+        if len( match_uplo ) == 2 and len( argument_properties[ 'assert_char' ] ) == 2 and \
+          'U' in argument_properties[ 'assert_char' ] and 'L' in argument_properties[ 'assert_char' ]:
+          print "adding uplo trait"
+          argument_properties[ 'trait_type' ] = 'uplo'
+          argument_properties[ 'trait_of' ] = match_uplo[ 0 ][ 2 ]
+
+          # see if the traits are overruled through the template system
+          traits_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.' + argument_name + '.trait_of'
+          if my_has_key( traits_key, template_map ):
+            argument_properties[ 'trait_of' ] = template_map[ my_has_key( traits_key, template_map ) ].strip()
+
+    #
+    # Minimal workspace dimension recognition
+    #
+    elif argument_properties[ 'type' ] == 'vector':
+      # usually this text is
+      # 1) dimension (...)           without spaces in the formula
+      # 2) dimension at least ...    (e.g., RWORK IN CLALSA)
+      match_dim = re.compile( 'dimension \((.+)\)' ).findall( comment_block )
+      print "Matches on dimension(): ", len( match_dim )
+      for d in match_dim:
+        d = d.replace( ' ', '' )
+        #
+        # TODO
+        # make some sensible rules here
+        #
+        match_unwanted_text = re.compile( '\s([Ii]f|[Ww]hen)\s' ).findall( comment_block )
+        print match_unwanted_text
+        if len( match_unwanted_text ) == 0:
+          argument_properties[ 'assert_size' ] = decompose_formula( replace_implicit_products( d ) )
+          argument_properties[ 'assert_size_args' ] = nested_list_args( argument_properties[ 'assert_size' ] )
+
+      # assert_size_args determines the arguments of min_size function for this
+      # workspace array. But, this gets overruled by user-defined templates.
+      if 'workspace' in argument_properties[ 'io' ]:
+        args_string = None
+        template_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.min_size_' + argument_name.lower() + '.args'
+        if my_has_key( template_key, template_map ) != None:
+          args_string = template_map[ my_has_key( template_key, template_map ) ]
+          tmp_result = []
+          for arg in args_string.split( "," ):
+            tmp_result.append( arg.strip().upper() )
+          if tmp_result == ['']:
+            tmp_result = []
+
+          for arg in tmp_result:
+            if arg not in argument_map.keys():
+              # variable not found, try user-defined variable definitions
+              add_user_defined_args( arg, user_defined_arg_map, template_map, subroutine_group_name + '.' + subroutine_value_type )
+
+          argument_properties[ 'assert_size_args' ] = tmp_result
+          print "Using user-defined assert_size_args: ", tmp_result
+
+      #
+      # Try to detect packed strorage stuff. Typically these are vectors in Fortran, but 
+      # matrices in our bindings. E.g. as used in spsv. 
+      #
+      packed_keywords = re.compile( '(/s|packed|matrix)+', re.M ).findall( comment_block )
+      if 'matrix' in packed_keywords and 'packed' in packed_keywords:
+        #
+        # Overrule my type :-)
+        #
+        argument_properties[ 'type' ] = 'matrix'
+
+  #
+  # Add user-defined arguments to the argument_map
+  #
+  argument_map.update( user_defined_arg_map )
+
+
+  print "Argument map: "  
+  pp.pprint( argument_map )
+
+
+  #
+  # Make a back-reference for workspace queries
+  #
+  for argument_name, argument_properties in argument_map.iteritems():
+    if argument_properties.has_key( 'workspace_query_for' ):
+      for referring_argument_name in argument_properties[ 'workspace_query_for' ]:
+        if argument_map.has_key( referring_argument_name ):
+          if not argument_map[ referring_argument_name ].has_key( 'workspace_query_by' ):
+            argument_map[ referring_argument_name ][ 'workspace_query_by' ] = []
+          argument_map[ referring_argument_name ][ 'workspace_query_by' ] += [ argument_name ]
+
+
+  #
+  # Generate the actual C++ code statements, based on information acquired so far.
+  #
+  # pass 1
+  for argument_name, argument_properties in argument_map.iteritems():
+    argument_properties[ 'code' ] = {}
+    argument_properties[ 'code' ][ 'lapack_h' ] = c_type( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'call_c_header' ] = call_c_type( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'level_0' ] = cpp_type( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'call_level_0' ] = call_level0_type( argument_name, argument_properties, argument_map )
+    argument_properties[ 'code' ][ 'level_1' ] = level1_type( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'level_1_type' ] = level1_typename( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'call_level_1' ] = call_level1_type( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'level_2' ] = level2_type( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'workspace_type' ] = workspace_type( argument_name, argument_properties )
+    
+  # Pass 2
+  # A second pass is needed, because the asserts may cross-reference other 
+  # variables which have been assigned their code in pass 1.
+  for argument_name, argument_properties in argument_map.iteritems():
+    argument_properties[ 'code' ][ 'level_1_assert' ] = level1_assert( argument_name, argument_properties, argument_map )
+    argument_properties[ 'code' ][ 'opt_workspace_query' ] = opt_workspace_query_type( argument_name, argument_properties, argument_map )
+    argument_properties[ 'code' ][ 'opt_workspace_pre' ] = opt_workspace_pre_type( argument_name, argument_properties, argument_map )
+    argument_properties[ 'code' ][ 'opt_workspace_post' ] = opt_workspace_post_type( argument_name, argument_properties )
+    argument_properties[ 'code' ][ 'min_workspace' ] = min_workspace_size_type( argument_name, argument_properties, argument_map )
+    argument_properties[ 'code' ][ 'min_workspace_args' ] = min_workspace_arg_type( argument_name, argument_properties, argument_map )
+    argument_properties[ 'code' ][ 'min_workspace_call' ] = min_workspace_call_type( argument_name, argument_properties, argument_map )
+    argument_properties[ 'code' ][ 'user_defined_init' ] = user_defined_type( argument_name, argument_properties, argument_map )
+
+  print "Argument map: "  
+  pp.pprint( argument_map )
+
+  print "Grouped arguments: "
+  pp.pprint( grouped_arguments )
+
+  #
+  # create a dict object
+  #
+  info_map = {}
+  info_map[ 'arguments' ] = subroutine_arguments
+  info_map[ 'purpose' ] = subroutine_purpose
+  info_map[ 'argument_map' ] = argument_map
+  info_map[ 'grouped_arguments' ] = grouped_arguments
+  
+  #
+  # Pass / check user-defined stuff right here.
+  #
+  user_def_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.extra_variables'
+  if my_has_key( user_def_key, template_map ) != None:
+    user_vars = template_map[ my_has_key( user_def_key, template_map ) ].split( "," )
+    tmp_result = []
+    for v in user_vars:
+      tmp_result.append( v.strip().upper() )
+    info_map[ 'user_defined_variables' ] = tmp_result
+  else:
+    info_map[ 'user_defined_variables' ] = None
+    
+  #
+  # Pass / check user-defined stuff right here.
+  # OPTIMAL CASE (may contain fewer variables)
+  #
+  user_def_key = subroutine_group_name.lower() + '.' + subroutine_value_type + '.extra_opt_variables'
+  if my_has_key( user_def_key, template_map ) != None:
+    user_vars = template_map[ my_has_key( user_def_key, template_map ) ].split( "," )
+    tmp_result = []
+    for v in user_vars:
+      tmp_result.append( v.strip().upper() )
+    info_map[ 'user_defined_opt_variables' ] = tmp_result
+  else:
+    info_map[ 'user_defined_opt_variables' ] = None
+  
+  
+  #subroutine_description.replace( subroutine_name, subroutine_name[ 1: ] )
+  #info_map[ 'description' ] = subroutine_description
+  
+  return subroutine_name, info_map
+
+
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/blas.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,57 @@
+$TEMPLATE[blas.hpp]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_BLAS_$GROUPNAME_HPP
+#define BOOST_NUMERIC_BINDINGS_BLAS_$GROUPNAME_HPP
+
+$INCLUDES
+
+namespace boost {
+namespace numeric {
+namespace bindings {
+namespace blas {
+
+//$DESCRIPTION
+
+// overloaded functions to call blas
+namespace detail {
+$OVERLOADS}
+
+$LEVEL1
+
+}}}} // namespace boost::numeric::bindings::blas
+
+#endif
+$TEMPLATE[blas_overloads]
+    inline void $groupname( $LEVEL0 ) {
+        BLAS_$SUBROUTINE( $CALL_C_HEADER );
+    }
+$TEMPLATE[blas_level1]
+// value-type based template
+template< typename ValueType >
+struct $groupname_impl {
+
+    typedef ValueType value_type;
+    typedef typename traits::type_traits<ValueType>::real_type real_type;
+
+    // templated specialization
+    template< $TYPES >
+    static void compute( $LEVEL1 ) {
+#ifndef NDEBUG
+        $ASSERTS
+#endif
+        detail::$groupname( $CALL_LEVEL0 );
+    }
+};
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsdc.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsdc.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[bdsdc.real.min_size_work.args]
+COMPQ, N
+$TEMPLATE[bdsdc.real.min_size_work]
+switch ( compq ) {
+    case 'N': return 4*n;
+    case 'P': return 6*n;
+    case 'I': return 3*n*n + 4*n;
+}
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsqr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/bdsqr.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,15 @@
+$TEMPLATE[bdsqr.all.min_size_work.args]
+N,NCVT,NRU,NCC
+$TEMPLATE[bdsqr.real.min_size_work]
+if ( ncvt == 0 && nru == 0 && ncc == 0 )
+    return 2*n;
+else
+    return std::max(1, 4*n);
+$TEMPLATE[bdsqr.complex.min_size_rwork.args]
+N,NCVT,NRU,NCC
+$TEMPLATE[bdsqr.complex.min_size_rwork]
+if ( ncvt == 0 && nru == 0 && ncc == 0 )
+    return 2*n;
+else
+    return std::max(1, 4*n-4);
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gebrd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gebrd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[gebrd.all.min_size_work.args]
+M,N
+$TEMPLATE[gebrd.all.min_size_work]
+return std::max( 1, std::max( m, n ) );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gelqf.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/gelqf.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,13 @@
+$TEMPLATE[gelqf.all.min_size_work.args]
+M
+$TEMPLATE[gelqf.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[geqlf.all.min_size_work.args]
+N
+$TEMPLATE[geqlf.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[getri.all.min_size_work.args]
+N
+$TEMPLATE[getri.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hetr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hetr.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,7 @@
+$TEMPLATE[hetrd.all.min_size_work.args]
+$TEMPLATE[hetrd.all.min_size_work]
+return 1;
+$TEMPLATE[hetrf.all.min_size_work.args]
+$TEMPLATE[hetrf.all.min_size_work]
+return 1;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hgeqz.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/hgeqz.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hgeqz.all.min_size_work.args]
+N
+$TEMPLATE[hgeqz.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/larz.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/larz.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,8 @@
+$TEMPLATE[larz.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[larz.all.min_size_work]
+if ( side == 'L' )
+    return n;
+else
+    return m;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/opmtr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/opmtr.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,8 @@
+$TEMPLATE[opmtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[opmtr.all.min_size_work]
+if ( side == 'L' )
+    return n;
+else
+    return m;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/org.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/org.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,25 @@
+$TEMPLATE[orgbr.all.min_size_work.args]
+M,N
+$TEMPLATE[orgbr.all.min_size_work]
+return std::max( 1, std::min( m, n );
+$TEMPLATE[orglq.all.min_size_work.args]
+M
+$TEMPLATE[orglq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[orgrq.all.min_size_work.args]
+M
+$TEMPLATE[orgrq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[orgql.all.min_size_work.args]
+N
+$TEMPLATE[orgql.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[orgqr.all.min_size_work.args]
+N
+$TEMPLATE[orgqr.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[orgtr.all.min_size_work.args]
+N
+$TEMPLATE[orgtr.all.min_size_work]
+return std::max( 1, n-1 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/orm.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/orm.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,50 @@
+$TEMPLATE[ormbr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormbr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[ormlq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormlq.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[ormqr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormqr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[ormrq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormrq.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[ormtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormtr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[ormql.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormql.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[ormhr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ormhr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stedc.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/stedc.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[stedc.all.min_size_iwork.args]
+COMPZ,N
+$TEMPLATE[stedc.all.min_size_iwork]
+// some formula
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/un.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/computational/un.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,77 @@
+$TEMPLATE[ungbr.all.min_size_work.args]
+M,N
+$TEMPLATE[ungbr.all.min_size_work]
+return std::max( 1, std::min( m, n ) );
+$TEMPLATE[ungql.all.min_size_work.args]
+N
+$TEMPLATE[ungql.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[ungqr.all.min_size_work.args]
+N
+$TEMPLATE[ungqr.all.min_size_work]
+return std::max( 1, n );
+$TEMPLATE[unglq.all.min_size_work.args]
+M
+$TEMPLATE[unglq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[ungrq.all.min_size_work.args]
+M
+$TEMPLATE[ungrq.all.min_size_work]
+return std::max( 1, m );
+$TEMPLATE[ungtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[ungtr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[unmbr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmbr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[unmhr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmhr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[unmlq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmlq.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[unmqr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmqr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[unmrq.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmrq.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[unmql.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmql.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[unmtr.all.min_size_work.args]
+SIDE,M,N
+$TEMPLATE[unmtr.all.min_size_work]
+if ( side == 'L' )
+    return std::max( 1, n );
+else
+    return std::max( 1, m );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/cgesv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/cgesv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[cgesv.complex.min_size_work.args]
+N, NRHS
+$TEMPLATE[cgesv.complex.min_size_work]
+return n*nrhs;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[gbsv.all.N.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gbsvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,13 @@
+$TEMPLATE[gbsvx.real.min_size_iwork.args]
+N
+$TEMPLATE[gbsvx.real.min_size_iwork]
+return n;
+$TEMPLATE[gbsvx.real.min_size_work.args]
+N
+$TEMPLATE[gbsvx.real.min_size_work]
+return 3*n;
+$TEMPLATE[gbsvx.complex.min_size_rwork.args]
+N
+$TEMPLATE[gbsvx.complex.min_size_rwork]
+return n;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gees.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gees.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,16 @@
+$TEMPLATE[gees.real.min_size_work.args]
+N
+$TEMPLATE[gees.real.min_size_work]
+return std::max( 1, 3*n );
+$TEMPLATE[gees.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[gees.all.min_size_bwork]
+if ( sort == 'N' )
+    return 0;
+else
+    return n;
+$TEMPLATE[gees.complex.min_size_work.args]
+N
+$TEMPLATE[gees.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geesx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geesx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,27 @@
+$TEMPLATE[geesx.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[geesx.all.min_size_bwork]
+if ( sort == 'N' )
+    return 0;
+else
+    return n;
+$TEMPLATE[geesx.real.min_size_iwork.args]
+N, SENSE
+$TEMPLATE[geesx.real.min_size_iwork]
+if ( sense == 'N' || sense == 'E' )
+    return 1;
+else
+    return std::max( 1, n*n/4 );
+$TEMPLATE[geesx.all.min_size_work.args]
+N, SENSE
+$TEMPLATE[geesx.real.min_size_work]
+if ( sense == 'N' )
+    return std::max( 1, 3*n );
+else
+    return std::max( 1, n+n*n/2 );
+$TEMPLATE[geesx.complex.min_size_work]
+if ( sense == 'N' )
+    return std::max( 1, 2*n );
+else
+    return std::max( 1, n*n/2 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,12 @@
+$TEMPLATE[geev.real.min_size_work.args]
+JOBVL,JOBVR,N
+$TEMPLATE[geev.real.min_size_work]
+if ( jobvl == 'V' || jobvr == 'V' )
+    return std::max( 1, 4*n );
+else
+    return std::max( 1, 3*n );
+$TEMPLATE[geev.complex.min_size_work.args]
+N
+$TEMPLATE[geev.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/geevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,25 @@
+$TEMPLATE[geevx.real.min_size_iwork.args]
+SENSE,N
+$TEMPLATE[geevx.real.min_size_iwork]
+if ( sense == 'N' || sense == 'E' )
+    return 0;
+else
+    return 2*n-2;
+$TEMPLATE[geevx.real.min_size_work.args]
+SENSE,JOBVL,JOBVR,N
+$TEMPLATE[geevx.real.min_size_work]
+if ( sense == 'N' || sense == 'E' ) {
+    if ( jobvl =='V' || jobvr == 'V' )
+        return std::max( 1, 3*n );
+    else
+        return std::max( 1, 2*n );
+} else
+    return std::max( 1, n*(n+6) );
+$TEMPLATE[geevx.complex.min_size_work.args]
+SENSE,N
+$TEMPLATE[geevx.complex.min_size_work]
+if ( sense == 'N' || sense == 'E' )
+    return std::max( 1, 2*n );
+else
+    return std::max( 1, n*n + 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gegv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gegv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[gegv.real.min_size_work.args]
+N
+$TEMPLATE[gegv.real.min_size_work]
+return std::max( 1, 8*n );
+$TEMPLATE[gegv.complex.min_size_work.args]
+N
+$TEMPLATE[gegv.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gels.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gels.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,6 @@
+$TEMPLATE[gels.all.min_size_work.args]
+M,N,NRHS
+$TEMPLATE[gels.all.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, minmn + std::max( minmn, nrhs ) );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,29 @@
+$TEMPLATE[gelsd.includes]
+#include <boost/numeric/bindings/lapack/auxiliary/ilaenv.hpp>
+$TEMPLATE[gelsd.complex.min_size_rwork.args]
+MINMN,SMLSIZ,NLVL,NRHS
+$TEMPLATE[gelsd.all.extra_variables]
+MINMN,SMLSIZ,NLVL
+$TEMPLATE[gelsd.all.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gelsd.all.SMLSIZ.init]
+integer_t smlsiz = ilaenv(9, "GELSD", "");
+$TEMPLATE[gelsd.all.NLVL.init]
+integer_t nlvl = static_cast<integer_t>(((std::log(static_cast<real_type>(minmn)) / std::log(static_cast<real_type>(2.))) / (smlsiz+1)) + 1);
+$TEMPLATE[gelsd.complex.min_size_rwork]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return std::max( 1, 10*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + 3*smlsiz*nrhs + smlsiz_plus_one * smlsiz_plus_one );
+$TEMPLATE[gelsd.complex.min_size_work.args]
+MINMN, NRHS
+$TEMPLATE[gelsd.complex.min_size_work]
+return std::max( 1, 2*minmn + minmn*nrhs );
+$TEMPLATE[gelsd.all.min_size_iwork.args]
+MINMN,NLVL
+$TEMPLATE[gelsd.all.min_size_iwork]
+return std::max( 1, 3*minmn*nlvl + 11*minmn );
+$TEMPLATE[gelsd.real.min_size_work.args]
+MINMN,SMLSIZ, NLVL, NRHS
+$TEMPLATE[gelsd.real.min_size_work]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return std::max( 1, 12*minmn + 2*minmn*smlsiz + 8*minmn*nlvl + minmn*nrhs + smlsiz_plus_one * smlsiz_plus_one );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelss.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelss.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,20 @@
+$TEMPLATE[gelss.real.min_size_work.args]
+M,N,NRHS
+$TEMPLATE[gelss.real.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, 3*minmn + std::max( std::max( 2*minmn, std::max(m,n) ), nrhs ) );
+$TEMPLATE[gelss.complex.extra_variables]
+MINMN
+$TEMPLATE[gelss.complex.extra_opt_variables]
+MINMN
+$TEMPLATE[gelss.complex.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gelss.complex.min_size_work.args]
+M,N,NRHS,MINMN
+$TEMPLATE[gelss.complex.min_size_work]
+return std::max( 1, 2*minmn + std::max( std::max( m,n ), nrhs ) );
+$TEMPLATE[gelss.complex.min_size_rwork.args]
+MINMN
+$TEMPLATE[gelss.complex.min_size_rwork]
+return 5*minmn;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsy.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gelsy.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[gelsy.all.min_size_work.args]
+M,N,NRHS
+$TEMPLATE[gelsy.real.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, std::max( minmn+3*n+1, 2*minmn+nrhs ));
+$TEMPLATE[gelsy.complex.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, std::max( std::max( 2*minmn, n+1 ), minmn+nrhs ) );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesdd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesdd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,28 @@
+$TEMPLATE[gesdd.all.extra_variables]
+MINMN
+$TEMPLATE[gesdd.all.extra_opt_variables]
+MINMN
+$TEMPLATE[gesdd.all.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gesdd.all.min_size_work.args]
+M, N, JOBZ, MINMN
+$TEMPLATE[gesdd.real.min_size_work]
+if ( n == 0 ) return 1;
+if ( jobz == 'N' ) return 3*minmn + std::max( std::max(m,n), 7*minmn );
+if ( jobz == 'O' ) return 3*minmn*minmn + std::max( std::max( m,n ), 5*minmn*minmn + 4*minmn );
+return 3*minmn*minmn + std::max( std::max( m,n ), 4*minmn*minmn + 4*minmn );
+$TEMPLATE[gesdd.complex.min_size_work]
+if ( n == 0 ) return 1;
+if ( jobz == 'N' ) return 2*minmn + std::max( m,n );
+if ( jobz == 'O' ) return 2*(minmn*minmn + minmn) + std::max( m, n );
+return minmn*minmn + 2*minmn + std::max( m, n );
+$TEMPLATE[gesdd.all.min_size_iwork.args]
+MINMN
+$TEMPLATE[gesdd.all.min_size_iwork]
+    return 8*minmn;
+$TEMPLATE[gesdd.complex.min_size_rwork.args]
+MINMN, JOBZ
+$TEMPLATE[gesdd.complex.min_size_rwork]
+if ( jobz == 'N' ) return 5*minmn;
+return 5*minmn*minmn + 7*minmn;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,20 @@
+$TEMPLATE[gesvd.real.min_size_work.args]
+M,N
+$TEMPLATE[gesvd.real.min_size_work]
+integer_t minmn = std::min( m, n );
+return std::max( 1, std::max( 3*minmn+std::max(m,n), 5*minmn ) );
+$TEMPLATE[gesvd.complex.extra_variables]
+MINMN
+$TEMPLATE[gesvd.complex.extra_opt_variables]
+MINMN
+$TEMPLATE[gesvd.complex.MINMN.init]
+integer_t minmn = std::min( traits::matrix_size1(a), traits::matrix_size2(a) );
+$TEMPLATE[gesvd.complex.min_size_work.args]
+M,N,MINMN
+$TEMPLATE[gesvd.complex.min_size_work]
+return std::max( 1, 2*minmn+std::max(m,n) );
+$TEMPLATE[gesvd.complex.min_size_rwork.args]
+MINMN
+$TEMPLATE[gesvd.complex.min_size_rwork]
+return 5*minmn;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gesvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[gesvx.real.min_size_work.args]
+N
+$TEMPLATE[gesvx.real.min_size_work]
+return 4*n;
+$TEMPLATE[gesvx.complex.min_size_rwork.args]
+N
+$TEMPLATE[gesvx.complex.min_size_rwork]
+return 2*n;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gges.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gges.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,14 @@
+$TEMPLATE[gges.all.min_size_work.args]
+N
+$TEMPLATE[gges.real.min_size_work]
+return std::max( 1, 8*n + 16 );
+$TEMPLATE[gges.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[gges.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[gges.all.min_size_bwork]
+if ( sort == 'N' )
+    return 0;
+else
+    return n;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggesx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggesx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,34 @@
+$TEMPLATE[ggesx.all.min_size_iwork.args]
+N, SENSE
+$TEMPLATE[ggesx.real.min_size_iwork]
+if ( sense == 'N' )
+    return 1;
+else
+    return std::max( 1, n+6 );
+$TEMPLATE[ggesx.complex.min_size_iwork]
+if ( sense == 'N' )
+    return 1;
+else
+    return std::max( 1, n+2 );
+$TEMPLATE[ggesx.all.min_size_bwork.args]
+N, SORT
+$TEMPLATE[ggesx.all.min_size_bwork]
+if ( sort == 'N' )
+    return 0;
+else
+    return n;
+$TEMPLATE[ggesx.all.min_size_work.args]
+N, SENSE
+$TEMPLATE[ggesx.real.min_size_work]
+if ( n == 0 )
+    return 1;
+if ( sense == 'N' )
+    return std::max( 8*n, 6*n+16 );
+else
+    return std::max( 8*n, std::max( 6*n+16, n*n/2 ));
+$TEMPLATE[ggesx.complex.min_size_work]
+if ( sense == 'N' )
+    return std::max( 1, 2*n );
+else
+    return std::max( 1, std::max( 2*n, n*n/2 ) );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[ggev.real.min_size_work.args]
+N
+$TEMPLATE[ggev.real.min_size_work]
+return std::max( 1, 8*n );
+$TEMPLATE[ggev.complex.min_size_work.args]
+N
+$TEMPLATE[ggev.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,50 @@
+$TEMPLATE[ggevx.all.min_size_bwork.args]
+SENSE, N
+$TEMPLATE[ggevx.all.min_size_bwork]
+if ( sense == 'N' )
+  return 0;
+else
+  return n;
+$TEMPLATE[ggevx.real.min_size_iwork.args]
+SENSE, N
+$TEMPLATE[ggevx.real.min_size_iwork]
+if ( sense == 'E' )
+  return 0;
+else
+  return n+6;
+$TEMPLATE[ggevx.complex.min_size_iwork.args]
+SENSE, N
+$TEMPLATE[ggevx.complex.min_size_iwork]
+if ( sense == 'E' )
+  return 0;
+else
+  return n+2;
+$TEMPLATE[ggevx.complex.min_size_rwork.args]
+BALANC, N
+$TEMPLATE[ggevx.complex.min_size_rwork]
+if ( balanc == 'S' || balanc == 'B' )
+    return std::max( 1, 6*n );
+else
+    return std::max( 1, 2*n );
+$TEMPLATE[ggevx.real.min_size_work.args]
+BALANC,JOBVL,JOBVR,SENSE,N
+$TEMPLATE[ggevx.real.min_size_work]
+if ( balanc == 'S' || balanc == 'B' || jobvl == 'V' || jobvr == 'V' )
+    return std::max( 1, 6*n );
+if ( sense == 'E' )
+    return std::max( 1, 10*n );
+if ( sense == 'V' || sense == 'B' )
+    return 2*n*n + 8*n + 16;
+return std::max( 1, 2*n );
+$TEMPLATE[ggevx.complex.min_size_work.args]
+SENSE, N
+$TEMPLATE[ggevx.complex.min_size_work]
+if ( sense == 'N' )
+    return std::max( 1, 2*n );
+else {
+    if ( sense == 'E' )
+        return std::max( 1, 4*n );
+    else
+        return std::max( 1, 2*n*n+2*n );
+}
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggglm.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ggglm.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[ggglm.all.min_size_work.args]
+M,N,P
+$TEMPLATE[ggglm.all.min_size_work]
+return std::max( 1, n+m+p );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gglse.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/gglse.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[gglse.all.min_size_work.args]
+M,N,P
+$TEMPLATE[gglse.all.min_size_work]
+return std::max( 1, m+n+p );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbev.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hbevd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hbevd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[hbevd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hbevd.complex.min_size_rwork]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hbevd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hbevd.complex.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 2*n*n;
+}
+$TEMPLATE[hbevd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbevx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbgv.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hbgvd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hbgvd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[hbgvd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hbgvd.complex.min_size_rwork]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hbgvd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hbgvd.complex.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 2*n*n;
+}
+$TEMPLATE[hbgvd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hbgvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hbgvx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[heev.complex.min_size_rwork.args]
+N
+$TEMPLATE[heev.complex.min_size_rwork]
+return std::max( 1, 3*n-2 );
+$TEMPLATE[heev.complex.min_size_work.args]
+N
+$TEMPLATE[heev.complex.min_size_work]
+return std::max( 1, 2*n-1 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,30 @@
+$TEMPLATE[heevd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[heevd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[heevd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[heevd.complex.min_size_rwork]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[heevd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[heevd.complex.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n+1;
+    else
+        return 2*n + n*n;
+}
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevr.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,13 @@
+$TEMPLATE[heevr.complex.min_size_work.args]
+N
+$TEMPLATE[heevr.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[heevr.complex.min_size_rwork.args]
+N
+$TEMPLATE[heevr.complex.min_size_rwork]
+return std::max( 1, 24*n );
+$TEMPLATE[heevr.complex.min_size_iwork.args]
+N
+$TEMPLATE[heevr.complex.min_size_iwork]
+return std::max( 1, 10*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/heevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[heevx.complex.min_size_work.args]
+N
+$TEMPLATE[heevx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[hegv.complex.min_size_rwork.args]
+N
+$TEMPLATE[hegv.complex.min_size_rwork]
+return std::max( 1, 3*n-2 );
+$TEMPLATE[hegv.complex.min_size_work.args]
+N
+$TEMPLATE[hegv.complex.min_size_work]
+return std::max( 1, 2*n-1 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,30 @@
+$TEMPLATE[hegvd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hegvd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[hegvd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hegvd.complex.min_size_rwork]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hegvd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hegvd.complex.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n+1;
+    else
+        return 2*n + n*n;
+}
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hegvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hegvx.complex.min_size_work.args]
+N
+$TEMPLATE[hegvx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,4 @@
+$TEMPLATE[hesv.complex.min_size_work.args]
+$TEMPLATE[hesv.complex.min_size_work]
+return 1;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hesvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hesvx.complex.min_size_work.args]
+N
+$TEMPLATE[hesvx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpev.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hpevd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hpevd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[hpevd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hpevd.complex.min_size_rwork]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hpevd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hpevd.complex.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 2*n;
+}
+$TEMPLATE[hpevd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpevx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpgv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[hpgvd.complex.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[hpgvd.complex.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[hpgvd.complex.min_size_rwork.args]
+JOBZ,N
+$TEMPLATE[hpgvd.complex.min_size_rwork]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[hpgvd.complex.min_size_work.args]
+JOBZ,N
+$TEMPLATE[hpgvd.complex.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return n;
+    else
+        return 2*n;
+}
+$TEMPLATE[hpgvd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpgvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpgvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[hpsv.all.N.trait_of]
+AP
+$TEMPLATE[hpsv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/hpsvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[hpsvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/lalsd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/lalsd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,26 @@
+$TEMPLATE[lalsd.real.min_size_work.args]
+N,SMLSIZ, NLVL, NRHS
+$TEMPLATE[lalsd.real.min_size_work]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return 9*n + 2*n*smlsiz + 8*n*nlvl + n*nrhs + smlsiz_plus_one * smlsiz_plus_one;
+$TEMPLATE[lalsd.real.min_size_iwork.args]
+N,NLVL
+$TEMPLATE[lalsd.real.min_size_iwork]
+return 3*n*nlvl + 11*n;
+$TEMPLATE[lalsd.complex.min_size_rwork.args]
+N,SMLSIZ, NLVL, NRHS
+$TEMPLATE[lalsd.complex.min_size_rwork]
+integer_t smlsiz_plus_one = smlsiz + 1;
+return 9*n + 2*n*smlsiz + 8*n*nlvl + 3*smlsiz*nrhs + smlsiz_plus_one * smlsiz_plus_one;
+$TEMPLATE[lalsd.all.extra_variables]
+NLVL
+$TEMPLATE[lalsd.complex.NLVL.init]
+integer_t nlvl = std::max( 0, static_cast<integer_t>(
+    std::log(static_cast<real_type>(std::min(traits::matrix_size2(b),n))/
+    static_cast<real_type>(smlsiz+1)) /
+    std::log(static_cast<real_type>(2.))) + 1 );
+$TEMPLATE[lalsd.real.NLVL.init]
+integer_t nlvl = std::max( 0, static_cast<integer_t>(
+    std::log(static_cast<real_type>(n)/static_cast<real_type>(smlsiz+1)) /
+    std::log(static_cast<real_type>(2.)) ) + 1 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[pbsv.all.N.trait_of]
+AB
+$TEMPLATE[pbsv.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/pbsvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[pbsvx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[ppsv.all.N.trait_of]
+AP
+$TEMPLATE[ppsv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/ppsvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[ppsvx.all.N.trait_of]
+AP
+$TEMPLATE[ppsvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbev.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[sbevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[sbevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[sbevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[sbevd.real.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return 2*n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[sbevd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbevx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbgv.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[sbgvd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[sbgvd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[sbgvd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[sbgvd.real.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return 3*n;
+    else
+        return 1 + 5*n + 2*n*n;
+}
+$TEMPLATE[sbgvd.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sbgvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[sbgvx.all.UPLO.trait_of]
+AB
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spev.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[spevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[spevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[spevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[spevd.real.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return 2*n;
+    else
+        return 1 + 6*n + n*n;
+}
+$TEMPLATE[spevd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spevx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spgv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,21 @@
+$TEMPLATE[spgvd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[spgvd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[spgvd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[spgvd.real.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return 2*n;
+    else
+        return 1 + 6*n + n*n;
+}
+$TEMPLATE[spgvd.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spgvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,3 @@
+$TEMPLATE[spgvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[spsv.all.N.trait_of]
+AP
+$TEMPLATE[spsv.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/spsvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[spsvx.all.N.trait_of]
+AP
+$TEMPLATE[spsvx.all.UPLO.trait_of]
+AP
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[stev.real.min_size_work.args]
+N
+$TEMPLATE[stev.real.min_size_work]
+return std::max( 1, 2*n-2 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,15 @@
+$TEMPLATE[stevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[stevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[stevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[stevd.real.min_size_work]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 1 + 4*n + n*n;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/stevr.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[stevr.real.min_size_work.args]
+N
+$TEMPLATE[stevr.real.min_size_work]
+return std::max( 1, 20*n );
+$TEMPLATE[stevr.real.min_size_iwork.args]
+N
+$TEMPLATE[stevr.real.min_size_iwork]
+return std::max( 1, 10*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syev.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syev.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[syev.real.min_size_work.args]
+N
+$TEMPLATE[syev.real.min_size_work]
+return std::max( 1, 3*n-1 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,19 @@
+$TEMPLATE[syevd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[syevd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[syevd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[syevd.real.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return 2*n + 1;
+    else
+        return 1 + 6*n + 2*n*n;
+}
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevr.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevr.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[syevr.real.min_size_work.args]
+N
+$TEMPLATE[syevr.real.min_size_work]
+return std::max( 1, 26*n );
+$TEMPLATE[syevr.real.min_size_iwork.args]
+N
+$TEMPLATE[syevr.real.min_size_iwork]
+return std::max( 1, 10*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/syevx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,8 @@
+$TEMPLATE[syevx.real.min_size_work.args]
+N
+$TEMPLATE[syevx.real.min_size_work]
+if ( n < 2 )
+    return 1;
+else
+    return 8*n;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[sygv.real.min_size_work.args]
+N
+$TEMPLATE[sygv.real.min_size_work]
+return std::max( 1, 3*n-1 );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvd.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvd.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,19 @@
+$TEMPLATE[sygvd.real.min_size_iwork.args]
+JOBZ,N
+$TEMPLATE[sygvd.real.min_size_iwork]
+if ( jobz == 'N' || n < 2 )
+    return 1;
+else
+    return 3 + 5*n;
+$TEMPLATE[sygvd.real.min_size_work.args]
+JOBZ,N
+$TEMPLATE[sygvd.real.min_size_work]
+if ( n < 2 )
+    return 1;
+else {
+    if ( jobz == 'N' )
+        return 2*n + 1;
+    else
+        return 1 + 6*n + 2*n*n;
+}
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sygvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,5 @@
+$TEMPLATE[sygvx.real.min_size_work.args]
+N
+$TEMPLATE[sygvx.real.min_size_work]
+return std::max( 1, 8*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysv.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysv.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,4 @@
+$TEMPLATE[sysv.all.min_size_work.args]
+$TEMPLATE[sysv.all.min_size_work]
+return 1;
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysvx.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/driver/sysvx.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,9 @@
+$TEMPLATE[sysvx.real.min_size_work.args]
+N
+$TEMPLATE[sysvx.real.min_size_work]
+return std::max( 1, 3*n );
+$TEMPLATE[sysvx.complex.min_size_work.args]
+N
+$TEMPLATE[sysvx.complex.min_size_work]
+return std::max( 1, 2*n );
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/lapack.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/lapack.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,137 @@
+$TEMPLATE[lapack.hpp]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_$GROUPNAME_HPP
+#define BOOST_NUMERIC_BINDINGS_LAPACK_$GROUPNAME_HPP
+
+$INCLUDES
+
+namespace boost {
+namespace numeric {
+namespace bindings {
+namespace lapack {
+
+//$DESCRIPTION
+
+// overloaded functions to call lapack
+namespace detail {
+$OVERLOADS}
+
+$LEVEL1
+$LEVEL2
+}}}} // namespace boost::numeric::bindings::lapack
+
+#endif
+$TEMPLATE[lapack_overloads]
+    inline void $groupname( $LEVEL0 ) {
+        LAPACK_$SUBROUTINE( $CALL_C_HEADER );
+    }
+$TEMPLATE[level1_pre_header]
+// value-type based template
+template< typename ValueType, typename Enable = void >
+struct $groupname_impl{};
+
+$TEMPLATE[level1_header1]
+// value-type based template
+template< typename ValueType >
+struct $groupname_impl {
+
+$TEMPLATE[level1_header2]
+// $SPECIALIZATION specialization
+template< typename ValueType >
+struct $groupname_impl< ValueType, typename boost::enable_if< traits::is_$SPECIALIZATION<ValueType> >::type > {
+
+$TEMPLATE[level1_workspace]
+    typedef ValueType value_type;
+    typedef typename traits::type_traits<ValueType>::real_type real_type;
+
+    // user-defined workspace specialization
+    template< $TYPES, $WORKSPACE_TYPENAMES >
+    static void compute( $LEVEL1, detail::workspace$WORKSPACE_SIZE< $WORKSPACE_TYPES > work ) {
+#ifndef NDEBUG
+        $INIT_USER_DEFINED_VARIABLES
+        $ASSERTS
+#endif
+        detail::$groupname( $CALL_LEVEL0 );
+    }
+
+    // minimal workspace specialization
+    template< $TYPES >
+    static void compute( $LEVEL1, minimal_workspace work ) {
+        $INIT_USER_DEFINED_VARIABLES
+$SETUP_MIN_WORKARRAYS_POST
+        compute( $CALL_LEVEL1, workspace( $TMP_WORKARRAYS ) );
+    }
+
+    // optimal workspace specialization
+    template< $TYPES >
+    static void compute( $LEVEL1, optimal_workspace work ) {
+$OPT_WORKSPACE_FUNC
+    }
+
+$MIN_SIZE_FUNCS
+};
+
+$TEMPLATE[level1_opt_workspace]
+        $INIT_USER_DEFINED_OPT_VARIABLES
+        $SETUP_OPT_WORKARRAYS_PRE
+        detail::$groupname( $WORKSPACE_QUERY );
+        $SETUP_OPT_WORKARRAYS_POST
+        compute( $CALL_LEVEL1, workspace( $TMP_WORKARRAYS ) );
+$TEMPLATE[level1_opt_workspace_is_min]
+        compute( $CALL_LEVEL1, minimal_workspace() );
+$TEMPLATE[level2_workspace]
+// template function to call $groupname
+template< $TYPES, typename Workspace >
+inline integer_t $groupname( $LEVEL2, Workspace work = optimal_workspace() ) {
+    typedef typename traits::$TYPEOF_FIRST_TYPENAME_traits< $FIRST_TYPENAME >::value_type value_type;
+    integer_t info(0);
+    $groupname_impl< value_type >::compute( $CALL_LEVEL1, work );
+    return info;
+}
+
+$TEMPLATE[setup_min_workspace]
+        traits::detail::array< $WORKSPACE_TYPE > tmp_$NAME( min_size_$NAME( $CALL_MIN_SIZE ) );
+$TEMPLATE[setup_opt_workspace]
+        traits::detail::array< $WORKSPACE_TYPE > tmp_$NAME( $TMP_SIZE );
+$TEMPLATE[min_size_func]
+    static integer_t min_size_$NAME( $ARGUMENTS ) {
+        $MIN_SIZE
+    }
+
+$TEMPLATE[level1_noworkspace]
+    typedef ValueType value_type;
+    typedef typename traits::type_traits<ValueType>::real_type real_type;
+
+    // templated specialization
+    template< $TYPES >
+    static void compute( $LEVEL1 ) {
+#ifndef NDEBUG
+        $ASSERTS
+#endif
+        detail::$groupname( $CALL_LEVEL0 );
+    }
+};
+
+$TEMPLATE[level2_noworkspace]
+// template function to call $groupname
+template< $TYPES >
+inline integer_t $groupname( $LEVEL2 ) {
+    typedef typename traits::$TYPEOF_FIRST_TYPENAME_traits< $FIRST_TYPENAME >::value_type value_type;
+    integer_t info(0);
+    $groupname_impl< value_type >::compute( $CALL_LEVEL1 );
+    return info;
+}
+
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_blas.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,56 @@
+$TEMPLATE[blas.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS_H
+#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS_H
+
+#include <boost/numeric/bindings/traits/type.h>
+#include <boost/numeric/bindings/blas/blas_names.h>
+
+extern "C" {
+
+$CONTENT
+
+}
+
+#endif
+
+$TEMPLATE[blas.h_function]
+    void BLAS_$SUBROUTINE( $ARGUMENTS );
+$TEMPLATE[blas_names.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_BLAS_BLAS_NAMES_H
+#define BOOST_NUMERIC_BINDINGS_BLAS_BLAS_NAMES_H
+
+#include <boost/numeric/bindings/traits/fortran.h>
+
+$CONTENT
+
+#endif
+
+$TEMPLATE[blas_names.h_function]
+#define BLAS_$SUBROUTINE FORTRAN_ID( $subroutine )
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_lapack.hpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/singleton_lapack.hpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,66 @@
+$TEMPLATE[lapack.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_H
+#define BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_H
+
+#include <boost/numeric/bindings/traits/type.h>
+#include <boost/numeric/bindings/lapack/lapack_names.h>
+
+#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
+#  define BOOST_NUMERIC_BINDINGS_FORTRAN
+#endif 
+
+extern "C" {
+
+$CONTENT
+
+    int LAPACK_ILAENV(int const* ispec, const char* name, const char* opt,
+        int const* n1, int const* n2, int const* n3, int const* n4, int, int);
+}
+
+#endif
+
+$TEMPLATE[lapack.h_function]
+    void LAPACK_$SUBROUTINE( $ARGUMENTS );
+$TEMPLATE[lapack_names.h]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_NAMES_H
+#define BOOST_NUMERIC_BINDINGS_LAPACK_LAPACK_NAMES_H
+
+#ifndef BOOST_NUMERIC_BINDINGS_USE_CLAPACK
+#  include <boost/numeric/bindings/traits/fortran.h>
+#else
+#  define FORTRAN_ID( id ) id##_
+#endif
+
+$CONTENT
+
+#endif
+
+$TEMPLATE[lapack_names.h_function]
+#define LAPACK_$SUBROUTINE FORTRAN_ID( $subroutine )
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/CMakeLists.txt
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/CMakeLists.txt	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,23 @@
+$TEMPLATE[CMakeLists.txt]
+#
+# Copyright (c) 2009 by Rutger ter Borg
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+# THIS FILE IS AUTOMATICALLY GENERATED
+# PLEASE DO NOT EDIT!
+#
+
+enable_language( Fortran )
+find_package( LAPACK REQUIRED )
+
+#include_directories( . )
+
+$ENTRIES
+
+$TEMPLATE[CMakeLists.entry]
+add_executable( $groupname $groupname.cpp )
+target_link_libraries( $groupname ${LAPACK_LIBRARIES} )
+$TEMPLATE[end]
Added: sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/test_case.cpp
==============================================================================
--- (empty file)
+++ sandbox/numeric_bindings/libs/numeric/bindings/tools/templates/test/test_case.cpp	2009-02-11 09:01:46 EST (Wed, 11 Feb 2009)
@@ -0,0 +1,32 @@
+$TEMPLATE[test_case.cpp]
+//
+// Copyright (c) 2003--2009
+// Toon Knapen, Karl Meerbergen, Kresimir Fresl,
+// Thomas Klimpel and Rutger ter Borg
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// THIS FILE IS AUTOMATICALLY GENERATED
+// PLEASE DO NOT EDIT!
+//
+
+#include <cstdlib>
+#include <boost/numeric/bindings/lapack/$levelname/$groupname.hpp>
+
+int main(int argc, char *argv[]) {
+
+
+
+
+
+
+
+
+
+
+    return EXIT_SUCCESS;
+}
+
+$TEMPLATE[end]