Implementation of javaoctave


To the original author of this software, Kim Rydhof Thor Hansen.

Table of Contents

1. Introduction
2. Setting and Getting Variables
Logical and numerical types
Octave's struct type
Octave Types which can/shall not be treated
How to extend on further octave types

This documentation is intended to describe the implementation of javaoctave, and is thus complementary to the user documentation. Unlike the latter, this document has no overall structure but spotlights aspects of the implementation. The individual chapters arise through rework on according topic.

Currently, there is a single chapter only,

Setting and getting variables is done via octave functions load and save which define a textual description of the content of the space of variables. For instance, save('-') outputs on standardout ('-') the list of all variables. The first line is something like (dont ask me where the email address comes from):

# Created by Octave 4.3.0+, Thu May 31 14:32:19 2018 CEST <ernst@linux-9rd9.suse>

The following lines describe the individual variables defined, usually with a lot of blank lines in between the description of variables but sometimes also without. This is an example:



# name: XFPNumber
# type: global octave_java
warning: save: unable to save java objects, skipping

# name: ans
# type: scalar
0

# name: dd
# type: scalar
1

# name: ff
# type: float scalar
1.2999999523162842

Some observations:
  • Description of each variable starts with line # name: <variablename> followed by second line # type: <typename>. The typename is as returned by typeinfo, optionally preceeded by declaration global (with separating blank).
  • Also variable name ans is described if defined already.
  • From the 3rd line on, the description depends on the type. The modifier global has no influence.
  • There are types which cannot be saved, as octave_java. For these in the 3rd line a warning is saved of the form warning: save: unable to save ....
The types are listed by typeinfo(). According to personal communication with octave developers, this list is open, i.e. there are ways to add types to the builtin ones. We do not take this into account for now.
Let us focus first on the java primitive types which are all logical or numerical with the according octave types and then on octaves complex types for which there is no generic counterpart in java.
  • Floating point types are in java double and float corresponding with octave types scalar and float, respectively.
  • Integer types are in java long, int, short and byte corresponding with octave types int64, int32, int16 and int8, respectively. In addition, octave has unsigned integer types uint64, uint32, uint16 and uint8, for which there are no corresponding java types until java 1.8. Nevertheless, these are considered primitive octave types.
  • Java's logical type bool fully corresponds with the according octave type bool.
  • The java type char only roughly corresponds with the octave types string and sq_string. They more resemble the non-primitive java type String and so in this document are not considered primitive types. They are discussed later.
There is a fundamental difference between the java primitive types and the corresponding octave primitive types: whereas in java, these are all scalar, octave allowes matrices. Thus in octave each primitive types comes in two variants, scalar and matrix which is appended to the proper type name. For example int8 in itself does not exist, but instead int8 scalar and int8 matrix. The following types are named differently:
  • Whereas bool matrix is named regularly, bool scalar is just called bool. This may be due to the fact, that booleans normally occur as scalars.
  • Since the double type is the prevalent type, it is dropped from naming, i.e. double matrix is just called matrix and double scalar is just called scalar.

There is a special case, complex types ocurring in octave for which there is no correspondence in java: complex types. For each of the two floating point types there is an according complex type and this as the primitive types comes as scalar and as matrix. The according types are thus called complex scalar, complex matrix, float complex scalar and float complex matrix. Note the place where the word complex is inserted.

Each scalar value is directly stored. The integer types as one would expect. This is illustrated for the value 42:



# name: i64
# type: int64 scalar
42

# name: i32
# type: int32 scalar
42

# name: i16
# type: int16 scalar
42

# name: i8
# type: int8 scalar
42

For the boolean type, 1 represents true and 0 represents false.



# name: bb
# type: bool
1

For the floating point types an interesting effect comes into the game: we stored the value 3.3 but the result is as follows.



# name: dd
# type: scalar
3.2999999999999998


# name: ff
# type: scalar
3.2999999999999998

The reason for this is just that 3.3 is rounded towards the next value which can be represented by the according type. **** disuss also on precision ****

The complex types as tuple with real component and complex one.



# name: cc
# type: complex scalar
(3.2999999999999998,4.4000000000000004)

# name: ffc
# type: float complex scalar
(3.2999999523162842,6.5999999046325684)

Now let us consider the matrix types. As an example let us define ii=int32([1 3; 2 4]);: Saving, it is transformed into:



# name: ii
# type: int32 matrix
# ndims: 2
 2 2 
1
2
3
4

The general principle is clear: After the 2nd line specifying the type comes the following sequence of lines:

  • The 3rd line specifies the number of dimensions as # ndims: <numdims> followed in the 4th line by numdims times a blank plus length of array in this direction.
  • Starting with the 5th line for each entry the according number on a separate line.

This form can be read for all scalar types, no matter wheter integer, boolean or floating point, even for the complex ones. Nevertheless, there is a second one specific for dimensions at most 2 which we shall also demonstrate for dd=[1 3; 2 4];: It is transformed into:



# name: dd
# type: matrix
# rows: 2
# columns: 2
 1 3
 2 4

The general principle is clear: After the line specifying the type comes the following sequence of lines:

  • The 3rd line specifies the number of rows as # rows: <numrows> followed in the 4th line which specifies the number of columns as # columns: <numcols>.
  • Starting with the 5th line each line represents a row which is a sequence of blank followed by the according entry of the matrix.

This second form only applies to floating point types including the complex ones and to the boolean type but not to the integer types.