Numeric Python, COM and Eigenvalues
Stefano
clubdelpelosuperfluo at yahoo.it
Tue Apr 23 03:29:14 EDT 2002
Fernando Pérez <fperez528 at yahoo.com> wrote in message news:<aa1ft2$mn7$2 at peabody.colorado.edu>...
> Stefano wrote:
>
> > I am working with Numpy and trying to create a COM server.
> > I managed to call this server by Excel and get results like Inverse
> > matrix or Cholesky decomposition but the server doesn't work as I ask
> > for Eigenvalues/vectors (Excel does not respond anymore).
> > Has anyone heard of a problem of this kind?
>
> Well, with zero example code and details provided that's going to be a hard
> one to get help on ;)
>
> Do you know for a fact you're feeding it a diagonalizable matrix? Does numpy
> compute the eigenvals/vects nicely if you test it with the same matrix on its
> own (not via excel)? Start testing with a symmetric 2x2 real matrix for which
> you can hand-compute the eigenvalues trivially, that might tell you where the
> problem is.
>
> Good luck,
>
> f.
I have already tried with a trivial matrix via Shell.
The same matrix makes Excel freeze.
I have walked two path to use numeric via com
1. making a client that talks with Mark Hammond's doubletalk (do you
know?)
2. making a server and a client by my own (actually with the help of
Poulsen)
I have problems only with eigenvalues (I can invert, i can decompose à
la Cholesky...) with both the codes!
1.
doubletalk server: http://starship.python.net/crew/mhammond/ppw32/ppw32_samples.zip
chapter 6
the client:
Const txtStartupScript = ""
Public BookServer As Object
' public methods
'double',
'interpretString', # tries exec, then eval
'execFile',
'importFile',
'beginTrappingOutput',
'endTrappingOutput',
'getStandardOutput',
'getViewData',
'count',
'createTransaction',
'getTransaction','getTransactionString',
'getOneLineDescription',
'load', 'loadFromText', 'loadFromString',
'save', 'saveAsText', 'asString',
'edit','add',
'getAccountDetails',
'getAccountList',
'drawAccountChart',
'doDelphiCallbackDemo'
Sub InitCOMServer()
Dim startupScript As String
'called when the program starts
On Error GoTo InitCOMServer_error
Set BookServer = CreateObject("Doubletalk.BookServer",
RemoteMachine)
On Error GoTo 0
'tell it to capture output for the console
BookServer.beginTrappingOutput
'if there is an init script, run it
If txtStartupScript <> "" Then
On Error GoTo InitCOMServer_StartupScriptError
BookServer.execFile txtStartupScript
On Error GoTo 0
End If
'grab any standard output for the console
Exit Sub
InitCOMServer_error:
Dim msg As String
msg = "There was an error trying to initialize the BookServer." +
_
"Please check that it is properly registered and try the
Python " + _
"test functions first. The program will now abort."
MsgBox msg
End
InitCOMServer_StartupScriptError:
MsgBox "An error occurred running your startup script '" + _
txtStartupScript + "'. " + _
"Please check it is present and correct."
End Sub
Sub CloseCOMServer()
Set BookServer = Nothing
End Sub
Sub TestCOMServer()
'just to check it is alive
Dim hopefully_four As Integer
hopefully_four = BookServer.Double(2)
MsgBox "2 x 2 = " & hopefully_four & ", so your server is alive"
End Sub
Sub ScriptRun(FileName)
BookServer.execFile FileName
On Error GoTo mnuScriptRun_Error:
Exit Sub
mnuScriptRun_Error:
MsgBox "Error running script:" + vbCrLf + vbCrLf + Err.Description
End Sub
Sub ScriptImport(FileName)
BookServer.importFile FileName
End Sub
Function ProcessPythonCode(expr As String) As String
'passes a chunk of text to the server's interpretString
'method, and returns the result. If an error occurs,
'returns the error message.
On Error GoTo mnuProcessPythonCode_Error
ProcessPythonCode = BookServer.interpretString(expr)
Exit Function
mnuProcessPythonCode_Error:
ProcessPythonCode = Err.Description
End Function
Sub ProcessCommand(txtInput As String)
'gets a one-line string from the input text box.
'if there is a result, appends it to the output box.
'Also copy the input command to output to keep a command history
Dim strInput As String
Dim strResult As String
Dim strStandardOutput As String
Dim strOutText As String 'for building the final textbox data
'VB puts CRLF pairs in the input for multi-line
'statements; Python just wants line feeds
strInput = Replace(txtInput, vbCrLf, vbLf)
'multi-line statements need a final line-feed; this is optional
'fopr one liners. WE'll add it anyway.
If Right(strInput, 1) <> vbLf Then strInput = strInput + vbLf
'process it
strResult = ProcessPythonCode(strInput)
Debug.Print strResult
'get output
strStandardOutput = BookServer.getStandardOutput()
strStandardOutput = Replace(strStandardOutput, vbLf, vbCrLf)
Debug.Print strStandardOutput
End Sub
Sub InitializeNumeric()
Dim s As String
s = "from LinearAlgebra import *"
ProcessPythonCode s
s = "from Numeric import *"
ProcessPythonCode s
End Sub
Sub testNumerical()
Call InitCOMServer
Call InitializeNumeric
Dim s As String
s = "a = array(([2,1],[1,2]))"
ProcessCommand s
s = "inverse(a)"
' s = "eigenvalues(a)" Excel freezes
ProcessCommand s
CloseCOMServer
End Sub
2.
Python server (assigning the _reg_clsid_ with pythoncom, imported and
then registered with win32com.server.register.UseCommandLine...)
# PythonNumeric.py
class PythonNumeric:
_reg_clsid_ = "{E34C200E-D95A-49C6-A0F9-F29FF8FF903A}"
_reg_desc_ = "Python Numeric COM Server"
_reg_progid_ = "PythonNumeric.Utilities" #for external calling
_reg_class_spec_ = "PythonNumeric.PythonNumeric"
_public_methods_ = [ 'InvertMatrix', 'Eigenvalues' ]
# Use "print pythoncom.CreateGuid()" to make a new one.
def InvertMatrix(self, val):
import Numeric
import LinearAlgebra
return (LinearAlgebra.inverse(Numeric.array(val))).tolist()
def Eigenvalues(self, val):
import Numeric
import LinearAlgebra
return (LinearAlgebra.eigenvalues(Numeric.array(val))).tolist()
VBA Client
Function NumpyMatInverse(mynum As Range)
Dim numpy As Object
Dim matrice As Variant
Range2Array2 matrice, mynum
Set numpy = CreateObject("PythonNumeric.Utilities")
NumpyMatInverse = numpy.InvertMatrix(matrice)
Set numpy = Nothing
End Function
Function NumpyMatEigen(mynum As Range)
Dim numpy As Object
Dim matrice As Variant
Range2Array2 matrice, mynum
Set numpy = CreateObject("PythonNumeric.Utilities")
NumpyMatEigen = numpy.Eigenvalues(matrice)
Set numpy = Nothing
End Function
Sub Range2Array2(arr As Variant, r As Range, Optional base As Integer)
Dim n(1 To 2) As Integer, i As Integer, j As Integer, k As Integer
n(1) = r.Rows.Count + (base - 1)
n(2) = r.Columns.Count + (base - 1)
Select Case n(2)
Case 0
ReDim arr(base To n(1))
For i = base To n(1)
arr(i) = r.Cells(i - base + 1, 1 - base + 1)
Next i
Case Else
ReDim arr(base To n(1), base To n(2))
For i = base To n(1)
For j = base To n(2)
arr(i, j) = r.Cells(i - base + 1, j - base + 1)
Next j
Next i
End Select
End Sub
More information about the Python-list
mailing list