Source code for gemseo_java.jnius_java_discipline
# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Contributors:
# INITIAL AUTHORS - initial API and implementation and/or initial
# documentation
# :author: Francois Gallard
# :author: Antoine Dechaume
# OTHER AUTHORS - MACROSCOPIC CHANGES
"""Python wrapper for Java Disciplines."""
from __future__ import annotations
from typing import Mapping
from gemseo.core.discipline import MDODiscipline
from jnius import autoclass
from numpy import array
from numpy import fromiter
from numpy import ndarray
HashMap = autoclass("java.util.HashMap")
ArrayList = autoclass("java.util.ArrayList")
Double = autoclass("java.lang.Double")
String = autoclass("java.lang.String")
Integer = autoclass("java.lang.Integer")
Float = autoclass("java.lang.Float")
List = autoclass("java.util.List")
JavaArray = autoclass("java.lang.reflect.Array")
[docs]def to_java(value):
"""Convert a python native typed object to a Java jnius object.
Args:
value: The value to convert.
Returns:
The converted object.
"""
if isinstance(value, str):
return String(value)
if isinstance(value, int):
return Integer(value)
if isinstance(value, float):
return Float(value)
if isinstance(value, (list, ndarray)):
java_value = ArrayList()
for v in value:
java_value.add(Double(v))
return java_value
if isinstance(value, Mapping):
java_map = HashMap()
for k, v in value.items():
java_map.put(String(k), to_java(v))
return java_map
raise TypeError(type(value))
[docs]def to_python(value):
"""Convert a jnius object to a Python native typed object.
Args:
value: The value to convert.
Returns:
The converted object.
"""
if isinstance(value, String):
return str(value)
if isinstance(value, Integer):
return int(value)
if isinstance(value, Float):
return float(value)
if isinstance(value, ArrayList):
return array([to_python(v) for v in value])
if isinstance(value, HashMap):
return {str(k): to_python(value.get(k)) for k in value.keySet()}
if isinstance(value, (float, int, str, list)):
return value
if isinstance(value, List):
return fromiter(value, dtype="d")
raise TypeError(type(value))
[docs]class JavaDiscipline(MDODiscipline):
"""A Java discipline wrapper.
Allow to call from Python a Java implementation that inherits from the Java
abstract class: com.irt.saintexupery.discipline.MDODiscipline.
To use it, call the constructor with the Java class path such as
disc=JavaDiscipline('com.irt.saintexupery.problems.sellar.Sellar1')
"""
def __init__(self, java_class_name, *klass_args):
"""Constructor.
Args:
java_class_name: The java class path.
*klass_args: The arguments to pass to the constructor use jnius types.
"""
super().__init__(java_class_name)
self.__klass = autoclass(java_class_name)
self.__instance = self.__klass(*klass_args)
input_names = [s for s in self.__instance.getInputDataNames()]
self.input_grammar.update(input_names)
output_names = [s for s in self.__instance.getOutputDataNames()]
self.output_grammar.update(output_names)
self.default_inputs = to_python(self.__instance.getDefaultInputs())
def _run(self):
"""Call the run method of the Java implementation.
The values values returned by java are converted to a dict of native Python
types.
"""
java_inpts = to_java(self.local_data)
out = self.__instance.runWithLists(java_inpts)
self.local_data = to_python(out)