Putting a java interface on your C, C , or fortran code
Abstract:. The purpose of this report is to document some of the technical aspects of creating Java interfaces for codes written in languages other than Java We outline a procedure where one separates the construction of the interface from the external codes with the introduction of an intermediate "wrapper" class. This intermediate class serves to isolate user interface details from the details of calling external routines. This intermediate class also facilitates the incorporation of external routines into Java based systems for distributed computing and / or visual programming.
Contents
Chris Anderson
Department of Mathematics
Ucla Los Angeles, CA 91555
7/15/97
These software components were developed in conjunction with the research supported by Air Force Office of Scientific Research Grant F49620-96-I-0327 and National Science Foundation / ARPA Grant NSF-DMS-961584
Introduction
While people are debating whether or not Java is good for computationally intensive tasks, the fact is that C, C and Fortran are the primary languages for those who do scientific / technical computing. It also seems unlikely that this situation will change in the near future . Unfortunately, C, C and Fortran do not contain (as Java does) standardized and platform independent constructs for creating user interfaces, managing threads, networking, and a variety of other tasks associated with creating "applications". Thus, there is interest in creating applications in which the user interface, or other "application packaging", is written in Java, but the core computational component is written in C, C , or Fortran (see Figure 1). The purpose of this document is to describe, principally By Means of An Extended Example, The Process of Creating A Java Interface for a Program Written In C, C or Fortran.
In order to create applications which have the form indicated in Figure 1, one needs to know how to write Java interfaces and how to call routines written in C, C and Fortran from Java. The process of writing a Java interface is well described in a variety of books [1] [2] [3] [4] and we will assume that the reader is capable of writing a modest Java interface which accepts input and displays output to a user. The task of calling routines written in C, C and Fortran from Java comes under the heading of implementing and using "native" methods. Here too, other documents [1] [7] describe the process of interfacing Java to other languages. While, for completeness, we will outline the steps required to create and implement Java classes with native methods, we assume that the reader has implemented a Java class that has at least one native method procedure in it (eg the "Hello World" example of [7]). in one aspect, this report is The Presentation of An Extended Example Demonstrating How T is knowledge of writing Java interfaces and implementing native methods can be combined to create a Java / "other language" application. In addition to providing samples of the mechanisms for data exchange, the example also reveals the choices we made (and choices you will have to make) concerning the dividing line between the Java interface and routines written in C, C or Fortran. Our example concerns the creation of a Java interface for a program which solves the heat equation in a two dimensional rectangular region. Examples in C and Fortran Are Given (As Is Readily Seen THE C Example Is Very Close To What Might Be Composed in C).
In the first section we outline the process that we follow for creating applications of the type described by Figure 1. In the second section we present the example which will form the basis of our discussion, and in the third and fourth sections we detail the construction Of The Java Classes Which Form The Primary Components of The Application.The Process of Creating A Java Interface To C, C And Fortran Routines
THE Process That We Use for Creating Java Interfaces Consists of the Three Stes Idicated in Figure 2.
A noticeable feature of the process is that we utilize three steps, rather than two One may wonder about the need for the intermediate step;. That of writing an intermediate class that `` wraps '' the C, C or Fortran code Originally we. Didn't Have Three Steps, But Adopted this Practice for Several Reasons:
IT Facilitated Having The External Code Run As a Separate Thread. IF One Is Running A Computationally Intensive Task, The This Allows The Task to Be Executed WITHOUT `` Freezing '' 'The interface.
By using this intermediate class we have isolated that component of the application which contains inter-language calls. Since the inter-language calling procedure for Java is evolving, this allows us to accommodate any changes in the inter-language procedures more easily. Additionally, BY NOT Embedding this code within a user interface, We Also Allow The User Interface To Change Independently (this INDEPENDENTLY (This Is Important Because The Java User Interface Classes Are Evolving As Well).
Lastly, and no less importantly, this class provides an encapsulation of the external routines which facilitates their incorporation in a visual programming system or a software infrastructure which supports distributed computing.The example program written in "another" language.
The starting point for the process of writing a Java interface is to have a program or a selected set of code components that one wishes to write interfaces for. Rather than discuss the process of writing interfaces in an abstract way, we discuss the process of writing . interfaces for a specific example The example program is one that computes the evolution of the temperature of a rectangular plate The main driver routine is given below (as well as in the file tempCalc.cpp);. the include file for the functions which the Main routine calls are given in tempcalcroutines.h and the source for these routines.cpp.
In the first part of the main routine, the problem and run parameters are set, memory is allocated and the temperature distribution is initialized. A time stepping loop is then executed. In this loop, the temperature of the plate is evolved in time increments of Size DT by calling the routine evolvetemperature (...) And at some predetermined number of time steps the temperature distribution is outprut. (in this case ..dat).
Even though the temperature values are associated with a two-dimensional set of nodes covering the plate, we allocate and pass one-dimensional arrays of values This was done because the standard method for exchanging data with other languages is through one-dimensional arrays.; Java is no exception. Using one-dimensional sets of data values does not preclude using a two-dimensional array structure to access the data. The routines create2dArrayStructure (...) and destroy2dArrayStructure (...) in tempCalcRoutines.cpp demonstrate how one CAN CREATE A TWO-DIMENSIONAL ARRAY STRUCTURE Which Access The Data Allocated As a One Dimensional Array. # include
#include
#include "tempcalcroutines.h"
void main ()
{
//
// set problem parameters
//
Double Diffusive = 0.1;
Double a = 0.0; double b = 1.0;
Double C = 0.0; Double D = 1.0;
//
// set Runtime Parameters
//
Long m = 10;
LONG N = 20;
Long nsteps = 100;
Long nout = 10;
Double DT = 0.01;
//
// Allocate Space for Solution and Work Arrays
//
Double * tarray = new double [m * n];
Double * WorkArray = new double [m * n];
//
// Open Output File
//
OFSTREAM Fout ("Tempout.dat");
InitializeTemperature (Tarray, M, N, A, B, C, D);
Double Time = 0.0;
INT I; int J;
For (i = 1; i <= nsteps; i )
{
Evolvetemperature (Tarray, M, N, A, B, C, D, DT, Diffusive, WorkArray);
Time = TIME DT;
IF ((i% Nout) == 0)
{
COUT << "step" << i << endl; //print out step to screen
Fout << m << "<< n << endl; // output to file tempout.dat ... fout << Time << endl;
For (j = 0; j } } DELETE [] TARRAY Delete [] WorkArray; } This program is typical of many computationally intensive applications; data is allocated, parameters and values are initialized, and then a time stepping loop is executed As the calculation proceeds data is output periodically.. The Fortran version of this program is given in tempCalc.f and the supporting routines are given in tempCalcRoutines.f. One may notice that the C program is nearly identical to the Fortran program and does not use any of the object oriented features of C ( ie it does not utilize classes). This was done intentionally so that the code would serve as an example of codes which are likely to be used (and / or written) by the majority of those involved in scientific / technical computation. The Java Class That Encapsules The C, C or Fortran Codes Components. The second step in the process of creating an interface is to create a Java wrapper class that encapsulates the C, C or Fortran code components. It is in this class that the connection between the external routines and the corresponding Java routines is made. This class IS also responsible for "loading" The external routines. Essentially, this class replaces the main () routine. In this regard the class allocates the required arrays, contains the parameters as data members and also contains the methods (declared native) which are invoked by the main () driver routine (the initializeTemperature and Evolvetemperature Routines). To facilitate the execution of the program as a separate thread, this class implements the Runnable interface (it implements a run () method). In this run () method, we have changed the output process to be one which displays a color contour plot of the data, rather than write the output to a file. The requisite Java classes are contained in the files ColorContourPlot.java, ColorContourCanvas.java and ContourResolutionDialog.java.Lastly this routine also includes a main routine of it's own for testing purposes. The COMPLETE CODE IS GIVEN IN TEMPCALCJAVA.JAVA. . Since this routine has native methods, one must create the dynamically linked library (DLL) or shared library that contains their implementations As outlined in the discussions on implementing native methods [1] [7], this is a multi-step process: ......................... The command javah is applied to TempCalcJava.class. This means executing "javah -jni TempCalcJava". The result of this command is the creation of the file TempCalcJava.h. Since we are using the native interface specification of Java 1.1, the javah command Must be the one distributed with the jdk 1.1. The functions contained in TempCalcJava.h are "implemented". In this regard our task consists of accessing the data contained within the Java arrays and passing it to the corresponding C (or Fortran routines). The implementation of these routines is given in TempCalcJava. CPP. (Note That One CAN SELECT The FORTRAN IMPLEMENTATION BY Defining __fortran_build__ in The Compilation Process.) The routines in TempCalcJava.cpp along with those in tempCalcRoutines.cpp are compiled and a dynamically linked library (or a shared library) is created. The name of this library must coincide with the name of the file (without the .dll or .so extension) which occurs in System.load or System.loadLibrary command within the static initializer for the class. (for some notes on the compilation process see Native Method Compilation Notes.) See "Native Method Implementation Process" for a diagram of these steps. At this point, if the native method implementation process is successful, one should be able to run a "command line" version of the program by executing the main routine of the class ie just execute "java TempCalcJava". Problems which occur at this point are often caused by incorrect, or non-specification, of the path which is searched for the library containing the native method implementation. On PC / Windows platforms the pATH variable must include the directory containing the native method implementation dll. On UNIX machines running solaris The LD_Library_Path Variable Must Include The Directory Containing The Native Method Implementation Shared Library. The Java Interface The third step in writing the interface is to write the Java class that implements the interface. Minimally this means creating a Java application that possesses program control buttons and fields for data input. The interface is displayed below, and the associated Java code is contained within TemperatureApp.java. This user interface was constructed using tools that generate Java 1.0.2. However, since our implementation of native methods is Java 1.1 based, after the initial construction, we compiled and worked with this code using the Java 1.1 compiler. In the Java 1.1 compilation step one must specify the flag "-deprication" and put up with all the warnings that are generated. Hopefully the interface construction tools will support Java 1.1 soon and these nuisances will disappear.In looking over the Java code, one should take note that the computationally intensive part of the application is done as a separate thread [6]. Specifically, within the code which gets executed when the Run button is hit (the code fragment is given below) we create threads for the separate components of the application-- - One Thread for the Calculation Component and One Thread for the Color Contour Plot. The Calculation Component Thread Is Given a Lower Priority, So That On Machines Whose Implementation of the Java Vi RTUAL Machine Doesn't Time-Slice Among Equal Priority Threads, The Computational INTENSIVE COMPONENT WILL NOT CAUSE The User Interface To "Freeze". Void Runbutton_Clicked (Event Event) { * * * // // set up and start the threads for the contact plot and the // Calculation // Thread current = thread.currentthread (); // Capture Current Thread Thread ContourRead = New Thread (Temperatureun.contourPlot); ContourThread.start (); Temprunthread = New Thread (TemperatureURun); Temprunthread.SetPriority (current.getpriority () -1); Temprunthread.start (); } The Color Contour Plot That Results from The Execution of The Program Is Given Below // Java / Fortran Interface This tutorial gives an example of how to interface Fortran and Java. It is intended to supplement the example given inJava / Fortran Interface tips and it's a good idea to read that site first. The example was developed on Sun Solaris using Sun Workshop 5.0 C and Fortran compilers and Sun JDK 1.2. Because the example is no longer fully portable, it may not work on your system and I do not know enough about other systems to really help you. So, if you do manage to get things running on other Systems the deplease send in your tips and makefiles for the benefit of other user. Why do it? Java provides object-oriented programming, easy visualisation and true portability. Fortran has none of these things but does offer highly optimised compilers (with the option of parallelisation), excellent numerical libraries, simplicity, maths support (eg complex numbers and multi-dimensional arrays ) and masses of legacy code all of which make it excellent for number crunching. Although one might like to move over to pure Java, the performance advantages of Fortran or the effort of converting legacy code often enforces a dual approach with an interface between the two LANGUAGES. Introduction This tutorial will work through an example which sets some variables in Java, changes them in Fortran and shows the effect in Java. The Java program must call the Fortran subroutine via a C wrapper (as explained in Java / Fortran Interface tips) because Java can only talk to C or C . The variables are integers, doubles, booleans and strings, one of each with the suffix "_A" and one with the suffix "_B". Each variable will be set in Java and reset in Fortran. However, only the changes in the "_A" variables are passed through to Java via the C wrapper. in addition two 2-D arrays (a double precision array and a complex double precision array) are passed to Fortran. The Fortran Subroutine. Because Java Does Not Support Multi-Dimensional Arrays, A 2-D Array Of Size (MX, My) IS Reference AS A 1-D Arrey Of Size (mx * my). In Addition, Java Does Not Support Complex NumBers SO A 2-D Complex Array Of Size (MX, MX, MX) IS Reference AS A 1-D Array Of Size (2 * mx * my) .The Java Program The Java Program Initialise The Variables and Echoes The Fortran Subroutine THROUGH ITS C Wrapper And Echoes The Updated Variable Values. In the line public native void cppsub (int int_A, int int_B, double double_A, double double_B, boolean bool_A, boolean bool_B, int mx, int my, double [] doubleArray, double [] complexArray, String string_A, String string_B); We declare a native routine "CPPSUB" (OUR C Wrapper). in the line Static {system.loadLibrary ("jnidemo"); We Load in The Dynamic Library "libjnidemo.so". The Java Code is Compiled by "javac jnidemo.java" and is found here: JNideMo.java. NOTEMO.JAVA. NOTICE How The 1-D Java Arrays Are Unpacked To Access The 2-D Fortran Arrays. Java Include File We can automatically generate a Java include file for the native routine "cppsub" from JniDemo.class by typing "javah -jni JniDemo" The include file is found here:.. JniDemo.h and gives us the declaration of the subroutine "Java_JniDemo_cppsub" For the c wrapper. All The Java Integers, Doubles etc. Have Been Passed AS C Types Jint, JDOUBLE ETC. Specified in "jni.h". THE C Wrapper The C wrapper is the heart of the interface and must do more than simply pass its parameters to Fortran The link between Fortran and C is unfortunately not standardised Information on the Solaris interface is found here..: Fortran / C Interface. The Line extern "C" void f90sub_ (int * int_A, int * int_B, double * double_A, double * double_B, unsigned char * bool_A, unsigned char * bool_B, int * mx, int * my, double * doubleArray, double * complexArray, const Char * STR_A, Const Char * STR_B, INT * STR_A_LEN, INT * STR_B_LEN; Declares The External Compiled Fortran Subroutine "F90Sub" Which Gets An Undine IS Called with: F90SUB _ (& INT_A, & INT_B, & DOUBLE_A, & DOUBLE_B, & BOOL_A, & BOOL_B, & MX, & MY, DAPTR, CAPTR, STR_A, STR_B, & STR_A_LEN, & STR_B_LEN; All The Variables Are Passed by Reference. Note That The Jbooleans Must Be Passed to Fortran As Type Unsigned CHAR. .. Let us first look at the scalar variables (jint, jdouble, jboolean) These can simply be passed by reference to Fortran On return from the Fortran subroutine, the corresponding Java variables ending in "_A" are updated by: JCLASS CLS = Env-> getObjectClass (OBJ); JFIELDID FID; .... FID = ENV-> GetFieldID (CLS, "INT_A", "I"); if (FID == 0) {Return;} ENV-> Setintfield (Obj, FID, INT_A); FID = ENV-> GetFieldID (CLS, "Double_A", "D"); if (FID == 0) {Return;} ENV-> SetDoublefield (Obj, FID, Double_A); FID = Env-> getfieldID (CLS, "BOOL_A", "Z"); if (FID == 0) {Return;} ENV-> SetintField (Obj, FID, BOOL_A); WHERE WE DIRECTLY OVERWRITE THE VARIABLES "INT_A" "Double_a" and "bool_a" in the calling object "obj". For the arrays, we create pointers to those arrays by calling a JNI routine "GetDoubleArrayElements" and pass those to the Fortran subroutine. Before leaving the C wrapper we must call "ReleaseDoubleArrayElements" in case Java had to make a copy of the array (see Java Native Interface Tutorial. jdouble * caPtr = env-> GetDoubleArrayElements (complexArray, 0); jdouble * daPtr = env-> GetDoubleArrayElements (doubleArray, 0); ... env-> ReleaseDoubleArrayElements (complexArray, caPtr, 0); env-> ReleaseDoubleArrayElements (doubleArray, DAPTR, 0); Passing strings is slightly more completed. We first define pointers "str_a" and "str_b" and get the lengths of the strings Using "getStringutfchars" and pass those to fortran: jstring jstr; int str_A_len, str_B_len; const char * str_A = env-> GetStringUTFChars (string_A, 0); str_A_len = env-> GetStringLength (string_A); const char * str_B = env-> GetStringUTFChars (string_B, 0); str_B_len = ENV-> getStringLength; String_B); Next We make a copy of the string "str_a" to ensure it is online: char buf [128] = ""; strncat (buf, str_a, str_a_len); Now We create the jstring "jstr" Using the jni method "newstringutf" and use what to overwrite the java string "string_a" in the calling program: FID = ENV-> GetfieldID (CLS, "String_a", "Ljava / Lang / String;"); if (FID == 0) {Return;} jstr = env-> Newstringutf (buf); env-> setObjectfield (Obj , FID, JSTR); Finally, WE Must Release The String Elements: ENV-> ReleaseStringutfchars (String_a, Str_a); Env-> ReleaseStringutfchars (String_B, STR_B); Here Is The C Wrapper Code: Jnidemo.cpp in Solaris, The C Wrapper is Compiled to create the Dynamic Library "jnidemo.so" Something Like: Cc -g -i / usr / java / include -i / usr / java / include / solaris -o jnidemo.so jnidemo.cpp The fortran subroutine The Fortran subroutine first prints out all the variables passed to it, then overwrites them all and finally prints out the variables again Note that booleans (Fortran logicals) must be converted from the unsigned chars that were passed from the C wrapper with the lines.: BOOL_A = (CBOOL_A.EQ.CHAR (1)) BOOL_B = (CBool_B.EQ.CHAR (1)) At the end, The Fortran Logicals Must Be Converted Back to Unsigned Characters with the lines: CBOOL_A = char (0) CBOOL_B = char (0) IF (BOOL_A) CBOOL_A = Char (1) IF (BOOL_B) CBOOL_B = char (1) The passings of character strings between C and Fortran is not standardised so we have used character arrays and passed a separate integer with the string length The arrays are indexed in the normal Fortran fashion The fortran subroutine is found here:.. JniDemo_fortran.f In Solaris , WE Compile The Fortran Subroutine and Link In The C Wrapper Like this: F90 -LF77_MT -LM77 -LFSU -LF77COMPAT -G -L / USR / Java / JRE / LIB / SPARC -LJAVA -I / USR / Java / include -i / us / uslnidemo.so jnidemo. So jnidemo_fortran.f The makefile Here is the makefile for sun solaris: makefile. It is hopefully easy to adapt to your system. Note that files with the suffix ".so" are dynamic libraries (equivalent to ".DLL" files in Windows). The "-G" compiler flag signals creation of a dynamic library . The "-o" flag names the output file. The "-I" flag signals include files. The "-L" flag signals the directory where libraries to be linked to are kept and the "-l" flag names individual libraries ( the names are expanded eg -ljava indicates file libjava.so). Here, dynamic libraries are used throughout rather than object files. The final linking step must be done with the Fortran f90 compiler so the dynamic library "libJniDemo.so" is created by Linking the libraries "jnidemo.so" and jnidemo_fortran.so "together. Output of the program Compile The program Using "Make" and run it using "java jnidemo". You Should get the output shown here: Output of "java JniDemo". Note that the print statements may be jumbled as you should not really mix Java and native input / output. I hope you got it to work. Now try adapting it to suit your needs. If there's anything that Hasn't Been Covered Then Let Me Know At The Address Below. Good Luck! Notes There Seems To Be a Problem (Using Sun / Solaris / Workshop) WHEN USING EG Real (8) And Complex (16) in Fortran 90 INSTEAL * 8 AND Complex * 16. I get the message: Fatal Error In Native Method: Try to unpin an Object this is not pinnedi don't know why this is and the workaround is to just use the real * 8 notation. Please email me if you know what's going on ... // Why Not Stick TO JAVA OR C / C ? Features of Perl and Python Compared with Java, C / C and Fortran: SHORTER Programs Much Faster development NO Variable Declarations, But Lots of Consitency Checks At Run Time Lots of gluing Tools Lots of Text Processing Tools Guis Are Simpler / Shorter Lots of Web Programming Tools The popularity of scripting is growing fast! Scripting is on the rise 70S / 80S: UNIX Shell, Job Control Languages (Primitive, Cryptic Programming) 90s: Development of Perl, Python, Ruby, TCL Y2K: Scripting Languages Are Stable and Powerful on All Major Platforms Next decade: Explosure Interest??? Scripting supports Software Reuse Scripting Simplifies GUI Programming Scripts are fast enough on Today's Computers Python Supports Both Short Scripts and Java / C - Like Systems GUI: Python VS C Case: make a window on the screen with the text 'Hello World' C X11: 176 LINES OF UGLY CODE Python TK: 6 LINES OF Readable Code #! / usr / bin / env python From tkinter import * root = tk () Label (root, text = 'hello, world!', Foreground = "white", Background = "black"). Pack () root.mainloop () Java and C Codes Are Longer Than Python TK The Relation to OOP · Object-Oriented Programming Can Also Be Used to Parameterize Types · Introduce Base Class A and A Range of Subclasses, All with a (Virtual) Print Function · Let Debug Work with var as an a reason · Now Debug Works for All Subclasses of A · Advantage: Complete Control of the Legal Variable Types That Debug Are MAYED To Print (May Be Important in Big Systems TOSURE THAT A Function Can Allow Make Transactions with Certain Objects) · Disadvantage: Much More Work, Much More Code, Less Reuse of debug in new Occasions When to Use C, C , Java, Fortran Does The Application Implement Complicated Algorithms and Data Structures? Does The Application Manipulate Large DataSets So That Execution Speed Is Critical? Are The Application's Functions Well-Defined and Changing Slowly? Will Strong Typing Be An Advantage, E.G., in LARGE DEVELOPMENT TEAMS? Personal Applications of scripting Automate Manual Intertion with the computer Customize Your OWN WORKING Environment and Become More Efficient Have More fun Increase The Reliability of Your Work (What You Did IS Document " Scripts (USUALLY) RUN UNIX, Windows, Mac and MANY HAND-HELD Devices (i.e. scripts are cross-platform) You Get The Power of Unix Also in Non-UNIX Environments Python's Advantages over Perl Python IS Easier to Learn Because of ITS Clean Syntax and Simple / Clear Concepts Python Supports OO in a Much Easier Way Than Perlgui Programming In Python IS Easier (Because of the Oo Features) Documenting Python IS Easier Because of Doc Strings and More Readable Code Complicated Data Structures Are Easier To Work with in Python Python IS Simpler to Integrate with C and Fortran Python Can Be Seamless INTEGRATED WITH JAVA Perl's Advantages Over Python Perl is more widespread Perl Has More Additional Modules Perl is Faster Perl Enables Many Different Solutions To The Same Problem Perl programming is more fun (?) And more intellectually challening (?) Python is the Very High-Level Java, Perl Is Very The High-Level C? Numeric Python (NUMPY) Numpy Enables Efficient Numeric Computing in Python Numpy Is a Python / C Package Which Offers Efficient Arrays (Contiuous Storage) And Mathematical Operations IN C Old Numeric Module: From numeric import * NUMARRAY MODULE: From NumArray Import * Numpy Contains Other Modules As Well Python and numerical computing Fill A 2D Numpy Array with Function VALUES: N = 2000 A = Zeros ((N, N), FLOAT) Xcoor = arange (0, 1, 1 / float (n)) Ycoor = arange (0, 1, 1 / float (n)) For i in range (n): For J in Range (N): a [i, j] = f (Xcoor [i], ycoor [j]) Fortran / C / C Version: (Normalized) TIME 1.0 Python Version: Time 75 Numpy Vectorized Evaluation of F: Time 3 Conclusions Python Loops over Arrays Aremely Slow Numpy May Be Sufficient HOWEVER, NUMPY Vectorization May Be inconvenient- plain loops in fortran / C / C Are Much Easier! Write Administering Code in Python Identify bottlenecks (via profile) Migrate Slow Python Code To Fortran, C, OR C The Nature of Python vs. C A Python Variable Can Hold Different Objects: D = 3.2 # D Holds A Float D = 'txt' # D Holds a string D = button (frame, text = 'push') # instance of class button IN C, C And Fortran, A Variable is Declared of a Specific Type: Double D; D = 4.2; D = "some string"; / * Illegal, Compiler Error * / This Difference Makes It Quite Complicated to Call C, C or Fortran from Python Calling c from python Suppose We Have a c Function Extern Double HW1 (Double R1, Double R2); WE Want to Call this from Python AS From HW Import HW1 R1 = 1.2; R2 = -1.2 s = HW1 (R1, R2) THE PYTHON VARIABLES R1 And R2 Hold Numbers, We need to extract these in the c code, convert to double variables, and then call hw1 This is done in wrapper code Wrapper Code Between Python and Hw1 We need wrapper code: Static PyObject * _Wrap_hw1 (PyObject * Self, PyObject * args) { PyObject * resultobj; Double arg1; Double arg2; Double Result; IF (! pyarg_parsetuple (args, (char *) "DD: HW1", & arg1, & arg2) { Return null; / * WRONG ARGUMENTS Provided * / } Result = (Double) HW1 (Arg1, Arg2); Resultobj = pyfloat_fromdouble (result); Return Resultobj; Python Matlab = TRUE A Python Module, Pymat, Enables Communication with Matlab: From numeric import * Import Pymat x = arrayrange (0,4 * math.pi, 0.1) m = pymat.open () # can send numpy arrays to match: Pymat.put (m, 'x', x); Pymat.eval (m, 'y = sin (x)') Pymat.eval (M, 'Plot (x, y)') # get a new number array back: Y = pymat.get (m, 'y') Comparison with matlab The Demonstrated Functionality Can Be Coded in Matlab As Well Why Python F77? We can Define Our OWN Interface in a Much More Powerful Language (Python) Than Matlabwe Can Much More Easily Transfer Data To And from Or OWN F77 OR C OR C Libraries We can Use any appropriate Visualization Tool And, of course, We can call up matlab if we want Python F77 Gives Tailored Interfaces and Maximum Flexibility Disadvantages Of Fortran 77 The Basic Variables Types Are Primitive NO STRUCT or CLASS CONSTRUCT IN F77 No Dynamic Memory Allocation Very Primitive Language for Text Processing, Lists and More Complicated Data Structures F77 Codes Are Difficult to Extend, Maintain and Re-USE F90 / F95: Extension of F77 with classes (But Not Virtual Functions, Templates ETC.) The efficience of f90 / f95 is still problematic, and f77 programmers Move Very Slowly to F90 / F95 Advantages Of Fortran 77 F77 is a Very Simple Language F77 is easy to Learn F77 WAS Made for Computing Mathematical Formulas and Operating Efficiently on Plain Arrays F77 Is STILL (AND WILL Forever BE?) The Dominating Language for Numeric Computing Lots of Well Tested and Efficient F77 Libraries EXIST Compilers Have 50 Years of Experience with Optimizing F77 Loops over Arrays Result: f77 is hard to beat des comes to array operations My Opinion Use f77 for time-critical loops (array operations) Make the rest of the program in Python, C , Java OR F95 Python and F77 is an Easy-to-use pair! NOTE: Integration of F77 with C or Java Is Not ALWAYS StraightForward // About this Page A programmer can be significantly more productive in Python than in Java. How much more productive? The most widely accepted estimate is 5-10 times. On the basis of my own personal experience with the two languages, I agree with this estimate.Managers who are considering adding Python to their organization's list of approved development tools, however, can not afford to accept such reports uncritically. They need evidence, and some understanding of why programmers are making such claims. This page is for those managers. On this page, I present a list of side-by-side comparisons of features of Java and Python. If you look at these comparisons, you can see why Python can be written much more quickly, and maintained much more easily, than Java. The list is not long - IT is Meant To Be Repensentative, Not Exhaustive. This page looks only at programmer productivity, and does not attempt to compare Java and Python on any other basis. There is, however, one related topic that is virtually impossible to avoid. Python is a dynamically-typed language, and this feature is an important reason why programmers can be more productive with Python;. they do not have to deal with the overhead of Java's static typing So the debates about Java / Python productivity inevitably turn into debates about the comparative advantages and drawbacks of static typing versus dynamic typing a € "or strong typing versus weak typing a €" in programming languages. I will not discuss that issue here, other than to note that in the last five years a number of influential voices in the programming community have been expressing serious doubts about the Supposed Advantages Of Static Typing. For Those Who wish to Pursue the Matter, Strong Versus Weak Typing: a Conversation with Guido Van Rossum, Part V Is A Good Place To Start. See Also BR uce Eckel's weblog discussion Strong Typing vs. Strong Testing and Robert C. Martin's weblog discussion Are Dynamic Languages Going to Replace Static Languages ?. For background, see one of the papers that started it all in 1998 - Scripting: Higher Level Programming for the 21st Century by John Ousterhout.Several of these discussions contain valuable comparisons of Java and Python. for other language comparisons, see the Python language comparisons page at www.python.org, and the PythonComparedToJava page at Python for Java Programmers. Finally, it is important to note that asserting that a programmer can be more productive in Python than in Java, is not the same as asserting that one ought always to use Python and never to use Java. Programming languages are tools, and different tools are appropriate for different jobs. It is a poor workman whose toolbox contains only a hammer (no matter how big it is!), and it is a poor programmer (or software development organization) whose development toolkit contains only one programming language. Our toolboxes should . contain both Python and Java, so that in any given situation we have the option of choosing the best tool for the job So our claim is not that Python is the only programming language that you'll ever need - only that the number of jobs For Which Python Is The Best Tool Is Much Larger Than Is Generally Recognized.java vs. Python Productivity - An Overview There Are Three Main Language Characteristics That Make Program More Productive with Python Than with Java. Java Python STATICally Typed In Java, all variable names (along with their types) must be explicitly declared. Attempting to assign an object of the wrong type to a variable name triggers a type exception. That's what it means to say that Java is a statically typed language. Java container objects (eg Vector and ArrayList) hold objects of the generic type Object, but can not hold primitives such as int. To store an int in a Vector, you must first convert the int to an Integer. When you retrieve an object from a Container, IT Doesn't Remember ITS TYPE, AND MUST BE EXPLICIY CAST To The Desired Type. Dynamically Typed In Python, you never declare anything. An assignment statement binds a name to an object, and the object can be of any type. If a name is assigned to an object of one type, it may later be assigned to an object of a different type. that's what it means to say that Python is a dynamically typed language.Python container objects (eg lists and dictionaries) can hold objects of any type, including numbers and lists. When you retrieve an object from a container, it remembers its type SO no casting is required. For more information on static vs. Dynamic Typing, See the appendix. Verbose "Abounding in Words; Using Or Containing More Words Than Are Necessary" Concise (Aka Terse) "Expressing Much in A Few Words. Implies Clean-Cut Brevity, Attained by Excision of The Superfluous" Not Compact Compact In The New Hacker's Dictionary, Eric S. Raymond Gives The Following Definition for "Compact": Compact adj. Of a design, describes the valuable property that it can all be apprehended at once in one's head. This generally means the thing created from the design can be used with greater facility and fewer errors than an equivalent tool that is not compact. The reason for this is that Java, virtually alone among object-oriented programming languages, uses checked exceptions -. Exceptions that must be caught or thrown by every method in which they might appear, or the code will fail to compile Recently (as of June 2003) there seems to be an increasing amount of unhappiness with Java's use of checked exceptions. See Bruce Eckel's "Does Java need Checked Exceptions?" and Ron Waldhoff's "Java's checked exceptions were a mistake". As chromatic, the Technical Editor of the O'Reilly Network, put it: I like the idea of checked exceptions in some situations, but forcing every method to deal with (catching or throwing) all exceptions that its child calls or may call can be TEDIOS. I'D Rather Be Able To Ignore An Exception and Let Ignogate Upwards. Sometimes, I'D Rather Not Worry About Exceptions At ALL. EXAMPLE In why python? Eric S. Raymond Notes That: Python ... Is Compact - You Can Hold Its Entire Feature Set (AND At Least A Concept Index of Its Libraries) in Your Head. IN why i love python bra is not compact. I can remember many Python idioms because they're simpler. That's one more reason I program faster [in Python]. I still have to look up how to open a file every time I do it in Java. In fact, most things in Java Require me to look Something Up. EXAMPLE Java's String-Handling Capabilities Are Surprisingly Weak (But The Have Improved Considerably with the addition of the split method to the string class in java 1.4.) EXAMPLE . In Java, a new Integer object must be created and initialized from the int before it can be added to the Vector. In order to retrieve the value, the member of the Vector must be cast back to an Integer, and then converted back to an Int. In Python, None of these Conversions is Necessary. Java Python Public Vector Alist = New Vector; PUBLIC INUMBER = 5; Public int anothernumber; Alist.addelement (new integer (anumber); AnotherNumber = (Integer) alist.getlement (0)). INTVALUE (); Alist = [] Anumber = 5 Alist.Append (Anumber) AnotherNumber = alist [0] In Particular, this Example Illustrates The Clumsiness of Container Objects in Java, Which Require Casting An Object WHENEVER IT IS Extracted from a container. It is a common practice among Java programmers to overcome this clumsiness by writing application-specific container objects to wrap Java's generic containers. You might, for example, have an Employees class to wrap a vector of Employee objects. The get () method of the Employees object would retrieve the appropriate member of the Vector, and cast it back to an Employee object before returning it This is actually a good practice in Java But it has the effect of increasing the number of classes in the application -.. classes that The Programmer Must Write - And (Because Each Java Class Must EXISTIST ITS OWN FILE) It increases The number of java files That The Program Must Manage. None of this, of course, IS Necessary in Python. The Burden on Java Program Will Be EASED SOMEWHAT IN JAVA 1.5 with the Introduction of Generals and Boxing Conversions, Also Know as Autoboxing. EXAMPLE Verbosity is not just a matter of increasing the number of characters that must be typed - it is also a matter of increasing the number of places where mistakes can be made The Java code on the left has 5 control characters:. () {} WHERE The Corresponding Python Code Has Only One Control Character, The Colon. (or Two, if You Count Indentation. See Below.) Java Python IF (a> b) { A = B; B = C; } IF a> B: A = B B = C Omitting or duplicating such characters is easy to do accidentally, and constitutes a severe error in the code In my personal estimate, I spend 5 times as much time fixing such errors in Java as I do in Python It really cuts into your productivity.. - - and your creative energy - when you spend that much of your time just trying to satisfy the compiler.Technically, Python has another control character that Java does not a € "indentation But the requirement for correct indentation is the same in Java as. it is in Python, because in both languages correct indentation is a practical requirement for human-readable code. The Python interpreter automatically enforces correct indentation, whereas the Java compiler does not. With Java, you need an add-on product such as the Jalopy Code formatter to provide Automated Enforcement Of Indentation Standards. Appendix: About static vs. Dynamic Typing, and Strong vs. weak type, of programing languages. There is widespread confusion or disagreement about the meanings of the words static, dynamic, strong and weak when used to describe the type systems of programming languages. What follows is a description of the way (or at least one of the ways) these terms are Most Commonly Used. In a statically type name is bots (1) to a type (at Compile Time) and (at compile time, by means of a data declaration) and (2) to an Object. The binding to an Object is optional - if a name is not bound to an object, the name is said to be null Once a variable name has been bound to a type (that is, declared) it can be bound (via an assignment statement) only to objects of that type;. it can not ever be bound to an object of a different type. An attempt to bind the name to an object of the wrong type will raise a type exception.In a dynamically typed language, every variable name is (unless it is null) bound only to an object .............................. ...CRIPLITRATE. Here is an example. In a statically-typed language, the following sequence of statements (which binds an integer object, then a string object, to the name employeeName) is illegal. If employeeName had been declared to be an int, then the second Statement Would Be Illegal; if IT Had Been Declared to Be A String, The First Statement Would Be Illegal. But in a Dynamical-Typed Language This Sequence of Statements IS Perfectly Fine. EMPLOYEENAME = 9 Employeename = "steve ferg" Python is a dynamically-type is a staticly-type language. In a weakly typed language, variables can be implicitly coerced to unrelated types, whereas in a strongly typed language they can not, and an explicit conversion is required. (Note that I said unrelated types. Most languages will allow implicit coercions between related types a € "for example, the addition of an integer and a float. By unrelated types I mean things like numbers and strings.) In a typical weakly typed language, the number 9 and the string" 9 "are interchangeable, and the following sequence of statements Is legal.a = 9 B = "9" C = Concatenate (a, b) // Produces "99" D = add (a, b) // Produces 18 In A Strongly Typed Language, The Last Two Statements Would Raise Type Exceptions. To Avoid The Exceptions, Some Kind of Explicit Type Conversion Would Be Necessary, Like this. A = 9 B = "9" C = Concatenate (STR (a), b) D = add (a, int (b)) Both Java and Python Are Strongly Typed Languages. Examples of Weakly Typed Languages Are Perl and Rexx. A third distinction may be made between manifestly typed languages in which variable names must have explicit type declarations, and implictly typed languages in which this is not required. Most static languages are also manifestly typed (Java certainly is), but Frank Mitchell notes that some Are Not: "Haskell and the Dialects of ML, for Example, CAN Infer the Type of any variable based on the Operations Performed on it, with" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" Java Python Used to be "jpython", name recently change to "jython". An Implementation of The PythonLanguage That Generates Bytecodes for the Java Virtual Machine. http://www.jython.org/from the site ... (some from an older site) Jython is an implementation of the high-level, dynamic, object-oriented PythonLanguage written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform. Jython is freely available for both commercial And Non-Commercial Use and is distributed with source code. Jython is Complementary To Java and is especially suited for the folload tasks: Embedded scripting -. Java programmers can add the JPython libraries to their system to allow end users to write simple or complicated scripts that add functionality to the application Since JPython is certified 100% Pure Java, it can be added to an application without fear of compromising ITS Ability to Run on All Java Platforms. Interactive experimentation - Jython provides an interactive interpreter that can be used to interact with Java packages or with running Java applications This allows programmers to experiment and debug any Java system using Jython.. Rapid application development - PythonLanguage programs are typically 2-10X shorter than the equivalent Java program This translates directly to increased programmer productivity The seamless interaction between PythonLanguage and Java allows developers to freely mix the two languages both during development and in shipping products... Stregths: Ability to use a scripting language from thein java. This Alone Makes It Worthwhile! Excellent ability to invoke Java objects from Python code. This means that you have easy access to all those java libraries. In fact, it's often EASIER to call java objects from the Python side than from the java side! The only time it gets annoying is WHEN There multiple methods with the Same name But Multiple Signatures.Pretty Darn Easy to Invoke Python Objects from Java Code. This Less Used, But Vitally Important for Complete Integration. All the "obvious" conversions are performed for you. Strings, numbers, arrays, and things like that are typically converted for you with little effort. A java.lang.String just becomes a Python string (and vice-versa) with no need To "convert". with fancier objects you'll nesed to make some effort. Python interpreter can easily be embedded in Java. The existance of "exec" (or it's equivalent) in PerlLanguage, PythonLanguage, LispLanguage, etc makes it quite easy to make things user-scriptable (at runtime). Now you can do it for JavaLanguage TOO, ONLY The User Scripts Get Written in Python. Weakness: Class loading is weak. For example, if you change a script, you either need to run it with a new class loader or restart the application that will exec the script. Furthermore, reload is shallow, so if any imported scripts change, they also NEED to BE Recompiled and Run Under A New Class Loader. Jython Program Run Much More Slowly Than Cpython Ones. Jython Is About One Tenth of a Version OR SO BEHIND CPYTHON, PLUS It Doesn't Have All The Same Libraries and FunctionAlity As CPYTHON. Java Arrays Are A Problem. Use the Jarray Module for Java Array Support. WHATLAB Octave? Jan 24th, 2001 08:25 Marcel Oliver, Louis Luang [Note: This is a complicated question I am currently trying make this determination for myself, too This is what I came up with after a bit of searching and trying Hopefully more knowlegeable people will add some meat....] Mathematical Features: - currently matlab sets the standard. Octave is trailing matlab by several version. The main gist behind octave is to provide a free usage of matlab. - Numpy has a set of basic features that cover most of what is required for a standard undergraduate numerical analysis curriculum, (standard numerical linear algebra, FFT) but not much more Fancy stuff like domain triangulations is not supported and does not seem currently available. [DON 'THINOW Octave's Status on this particular issu.] - There Are Some Bindings to Standard Numeric Libraries, E.G. Multipack [link http://oliphant.netpedia.net is currently broken] Graphical Capabilities: - Again, Matlab is State of the Art. - a Frequent criticism About Octave is this ITS Graphical Capabilities Are Substandard, in Particular With Regards to publication Quality 3D graphics. [Current Status?] - There Are Graphical Add-ons for Numpy [no experience with any.] Interfaces to External Code: - All Three Are Sufficiently Able To Interface with External C Or Fortran Code. Programming language: - Numpy Builds Upon Attractive General-Purpose Object-Oriented Programming Langage. - Octave and matlab Share Mostly The Same Special Purpose Language. Maybe Second Weakest Point of Matlab AfTER licencing. - Some Clumsyness in Numpy with Matrix Multiplication. May Disappear At Some Point, See http://python.sourceforge.net/perth/pe-0211.html http://python.sourceforge.net/peps/pe-0225.html - EXISTING PHYTHON MODULES SHOULD MAKE IT Easy to Interface With Internet or Low-Level I / O IF So Desired. Documentation: - MATLAB: LOTS OF Books and Internet Resources Available. - Octave: Some MathLab Info May Work, Somewhat Complete User Manual, But Somewhat Outdated. - Numpy: Many Good Books on Python in General, A Rather Short But up-to-Date Introduction To Numpy. Portability: - NUMPY AND OCTAVE; Generally Good [KNown Problems?] - MATLAB: ANY Platforms That MathWorks Sees Fit To Support. This Currently Excludes All Non-Intel Linux Ports. LINCENSE: - MATLAB: ProPrietary. - OCTAVE: GPL - Numpy: phython lincense, is considered free. Conclusion: I currently plan to give Numpy a try as both a teaching platform and for doing small toy-case research codes. I am not yet sure how this will work out, but I decided for the probably least-established option for the following reasons. - After Falling Into The Proprietary Trap with a Wire-Know Program for Symbolic Math, i do not want to repeat this experience. - Python as a language as an Aestetic Appeal That Matlab / Ocatve SIMPLY DO NOTLAB / OCATVE SIMPLY DO NOTHEFUL FURTHER, The Language IS Useful Far Beyond Numeric Math, Which IS A BIG BONUS WHEN USING IT AS A TEACHING LANGUAGE. Pymat - an interface Between Python and Matlab Introduction NumPy is a set of numerical extensions for Python that introduces a multidimensional array type and a rich set of matrix operations and mathematical functions. Users who have MATLAB 5 installed, however, may wish to take advantage of some of MATLAB's additional functions, including the plotting interface. The PyMat module acts as an interface between NumPy arrays in Python and a MATLAB engine session, allowing arrays to be passed back and forth and arbitrary commands to be executed in the MATLAB workspace.PyMat is usable on both UNIX and Win32 platforms, although There Area Somet Differences Between The Two (Mainly Due To Matlab's Limitations). You Can Download The Latest version of pymat from: http://claymore.engineer.gvsu.edu/~steriana/python Functions Open ([STARTCMD]) ................ .. On the Win32 platform, the optional parameter startcmd is always ignored On UNIX platforms, it indicates the method of starting MATLAB Quoting from the documentation for the engOpen function from the MATLAB API reference manual..: On UNIX systems, if startcmd is NULL or the empty string, engOpen starts MATLAB on the current host using the command matlab. If startcmd is a hostname, engOpen starts MATLAB on the designated host by embedding the specified hostname string into the larger string : "RSH Hostname /" / BIN / CSH-C 'Stenv Display Hostname: 0; Matlab' / "" IF StarTCMD is any other string (HAS White Space In It, or NonalPhanumeric Characters), The String is Executed Litrally to Start Matlab. On Unix Systems, Engopen Performs The Following Steps: Creates Two Pipes. 2. Forks a new process and sets up the pipes to pass stdin and stdout from matlab (parent) To Two File Descriptors in the Engine Program (Child). 3. Executes a command to run matlab (RSH for remote execution). Under Windows on a PC, engOpen opens an ActiveX channel to MATLAB This starts the MATLAB that was registered during installation If you did not register during installation, on the command line you can enter the command..: Matlab / regserver Close (Handle) This function closes the matlab session represented by handle. evAl (Handle, String) ................ .. Note that this function always succeeds without any exceptions unless the handle is invalid, even if the evaluation failed in the MATLAB workspace !. You are responsible for verifying successful execution of your code. Get (Handle, Name) .................................................... Currently, only one-dimensional and two-dimensional floating-point arrays (real or complex) are supported. Structures, cell arrays, multi-dimensional arrays, etc. are not yet supported. On UNIX systems, this function can also be used to Retrieve Character strings, in which case a python string Object is returned. This functionality is not supported on Win32 (Due to Matlab Restrictions). PUT (Handle, Name, DATA) THIS FUNCTION Places A Python Object Into Matlab's Workspace Under The Given Name. The Data Parameter Can Be One of Things: A NumPy array -. In this case, an array of the same shape and contents will be placed into the MATLAB workspace The MATLAB array will be in double-precision format (real or complex), converting from the NumPy array type as necessary. Only one-dimensional or two-dimensional NumPy arrays are supported.A Python list or tuple containing numeric values. In this case, a NumPy object is created from the list or tuple (as if you were using NumPy's array () function) and that Object is instantiated in Matlab's Workspace. A Python String Object. In this case, a matlab character array will be instantiated with the contents of the string. Limitations The Following Limitations Apply to The Current Version of Pymat: Only 1-D and 2-D Double-Precision (REAL OR Complex) Matlays Aresu Supported (AND Single Character strings). Matrices of Higher Dimension, Structure Arrays, Cell Arrays, etc. Are Not Yet Supported. The Win32 Platform Does Not Support Retrieving Character Strings from The Matlab Workspace. Examples Here Is A Simple Example That Computes The Discrete Cosine Transform Of A Short Numpy Array Using Matlab's DCT Function: >>> IMPORT PYMAT >>> from numeric import * >>> x = array ([1, 2, 3, 4, 5, 6]) >>> h = pymat.open () >>> Pymat.Put (h, 'x', x) >>> Pymat.eval (h, 'y = DCT (x)') >>> Print Pymat.get (h, 'y') [8.57321410E 00 -4.16256180E 00 -1.55403172E-15 -1.88808530E-15 -8.00788912E-02] >>> pymat.close (h) Installation Win32 Simply place the pymat.pyd file somewhere on your Python search path. Also ensure that MATLAB's BIN directory is somewhere on your DOS path, or else that you have copied MATLAB's LIBENG.DLL and LIBMX.DLL files somewhere on this path./// A Lightweight Language Has ONE Data Structure and Uses It Well. Perl, TCL - String Python, Scheme - List Matlab - Matrix All of these (Well, i don't actually know) Offer Other Data Types, But if you use the predominant data type Things Go Much More SMOOTHLY. THINGY IS THEN IRE IS One Form of I / O, you CAN hook lots of things together easily. as Pointed Out at the Conference, this trades short term estainability.