model_function2

Two models, A & B, that send/receive scalars and arrays. Model A iterates over received array input from a table, calling the indicated model function for each array element, and then sends all of outputs from the iteration as an array to model B. Model B receives input arrays from model A and sends it’s output to a file. Both models are functions that are automatically wrapped by yggdrasil with the appropriate interface calls. This example demonstrates the use of the function model YAML parameter and auto-wrapping as well as iteration over input/output arrays via the iter_function_over model YAML paramter.

C Version

Model Code:

1#include <stdio.h>
2
3int model_function(float x, float* y) {
4  y[0] = x + 1.0;
5  printf("Model A: %f -> %f\n", x, *y);
6  return 0;
7
8}
 1#include <stdio.h>
 2
 3int model_function(float *x, uint64_t length_x,
 4		   float **y, uint64_t *length_y) {
 5  uint64_t i;
 6  length_y[0] = length_x;
 7  y[0] = (float*)malloc(length_x * sizeof(float));
 8  for (i = 0; i < length_x; i++)
 9    (*y)[i] = x[i] + 2.0;
10  printf("Model B: [");
11  for (i = 0; i < length_x; i++)
12    printf("%f ", x[i]);
13  printf("] -> [");
14  for (i = 0; i < length_x; i++)
15    printf("%f ", (*y)[i]);
16  printf("]\n");
17  return 0;
18
19}

Model YAML:

 1models:
 2  - name: c_modelA
 3    language: c
 4    args: ./src/model_function_modelA.c
 5    function: model_function
 6    iter_function_over: [x, y]
 7    inputs:
 8      name: x
 9      default_file:
10        name: ./Input/input.txt
11        filetype: table
12        as_array: true
13    outputs: y
14  - name: c_modelB
15    language: c
16    args: ./src/model_function_modelB.c
17    function: model_function
18    inputs: x
19    outputs:
20      name: y
21      default_file:
22        name: ./output.txt
23        filetype: table
24        as_array: true
25        field_names: [mass]
26        field_units: [g]
27
28connections:
29  - input: c_modelA:y  # Connection between model A output & model B input
30    output: c_modelB:x

C++ Version

Model Code:

1#include <iostream>
2
3int model_function(float x, float& y) {
4  y = x + 1.0;
5  std::cout << "Model A: " << x << "->" << y << std::endl;
6  return 0;
7}
 1#include <iostream>
 2#include <vector>
 3
 4int model_function(std::vector<float> x,
 5		   std::vector<float> &y) {
 6  std::vector<float>::iterator it;
 7  for (it = x.begin(); it != x.end(); it++)
 8    y.push_back(*it + 2.0);
 9  std::cout << "Model B: [";
10  for (it = x.begin(); it != x.end(); it++)
11    std::cout << *it << " ";
12  std::cout << "] -> [";
13  for (it = y.begin(); it != y.end(); it++)
14    std::cout << *it << " ";
15  std::cout << "]" << std::endl;
16  return 0;
17
18}

Model YAML:

 1models:
 2  - name: cpp_modelA
 3    language: c++
 4    args: ./src/model_function_modelA.cpp
 5    function: model_function
 6    iter_function_over: [x, y]
 7    inputs:
 8      name: x
 9      default_file:
10        name: ./Input/input.txt
11        filetype: table
12        as_array: true
13    outputs: y
14  - name: cpp_modelB
15    language: c++
16    args: ./src/model_function_modelB.cpp
17    function: model_function
18    inputs: x
19    outputs:
20      name: y
21      default_file:
22        name: ./output.txt
23        filetype: table
24        as_array: true
25        field_names: [mass]
26        field_units: [g]
27
28connections:
29  - input: cpp_modelA:y  # Connection between model A output & model B input
30    output: cpp_modelB:x

Fortran Version

Model Code:

1function model_function(x) result(y)
2  real(kind=4), intent(in) :: x
3  real(kind=4) :: y
4  y = x + 1.0
5  write(*, '("Model A: ",F10.5," -> ",F10.5)') x, y
6end function model_function
 1function model_function(x) result(y)
 2  real(kind=4), dimension(:), intent(in) :: x
 3  real(kind=4), dimension(:), allocatable :: y
 4  integer :: i
 5  allocate(y(size(x, 1)))
 6  do i = 1, size(x, 1)
 7     y(i) = x(i) + 2.0
 8  end do
 9  write(*, '("Model B: [")', advance="no")
10  do i = 1, size(x, 1)
11     write(*, '(F10.5," ")', advance="no") x(i)
12  end do
13  write(*, '("] -> [")', advance="no")
14  do i = 1, size(y, 1)
15     write(*, '(F10.5," ")', advance="no") y(i)
16  end do
17  write(*, '("]")')
18end function model_function

Model YAML:

 1models:
 2  - name: fortran_modelA
 3    language: fortran
 4    args: ./src/model_function_modelA.f90
 5    function: model_function
 6    iter_function_over: [x, y]
 7    inputs:
 8      name: x
 9      default_file:
10        name: ./Input/input.txt
11        filetype: table
12        as_array: true
13    outputs: y
14  - name: fortran_modelB
15    language: fortran
16    args: ./src/model_function_modelB.f90
17    function: model_function
18    inputs: x
19    outputs:
20      name: y
21      default_file:
22        name: ./output.txt
23        filetype: table
24        as_array: true
25        field_names: [mass]
26        field_units: [g]
27
28connections:
29  - input: fortran_modelA:y  # Connection between model A output & model B input
30    output: fortran_modelB:x

Julia Version

Model Code:

1using Unitful
2using Printf
3
4function model_function(x)
5  y = x .+ 1.0u"g"
6  @printf("Model A: %s -> %s\n", x, y)
7  return y
8end
1using Unitful
2using Printf
3
4function model_function(x)
5  y = x .+ 2.0u"g"
6  @printf("Model B: %s -> %s\n", x, y)
7  return y
8end

Model YAML:

 1models:
 2  - name: julia_modelA
 3    language: julia
 4    args: ./src/model_function_modelA.jl
 5    function: model_function
 6    iter_function_over: [x, y]
 7    inputs:
 8      name: x
 9      default_file:
10        name: ./Input/input.txt
11        filetype: table
12        as_array: true
13    outputs: y
14  - name: julia_modelB
15    language: julia
16    args: ./src/model_function_modelB.jl
17    function: model_function
18    inputs: x
19    outputs:
20      name: y
21      default_file:
22        name: ./output.txt
23        filetype: table
24        as_array: true
25        field_names: [mass]
26
27connections:
28  - input: julia_modelA:y  # Connection between model A output & model B input
29    output: julia_modelB:x

Matlab Version

Model Code:

1function y = model_function_modelA(x)
2  if isa(x, 'sym')
3    y = x + 1.0 * str2symunit('g');
4    fprintf('Model A: %f -> %f\n', separateUnits(simplify(x)), separateUnits(simplify(y)));
5  else;
6    y = x + 1.0;
7    fprintf('Model A: %f -> %f\n', x, y);
8  end;
9end
1function y = model_function_modelB(x)
2  if isa(x, 'sym')
3    y = x + 2.0 * str2symunit('g');
4    fprintf('Model B: %f -> %f\n', separateUnits(simplify(x)), separateUnits(simplify(y)));
5  else;
6    y = x + 2.0;
7    fprintf('Model B: %f -> %f\n', x, y);
8  end;
9end

Model YAML:

 1models:
 2  - name: matlab_modelA
 3    language: matlab
 4    args: ./src/model_function_modelA.m
 5    function: model_function_modelA
 6    iter_function_over: [x, y]
 7    inputs:
 8      name: x
 9      default_file:
10        name: ./Input/input.txt
11        filetype: table
12        as_array: true
13    outputs: y
14  - name: matlab_modelB
15    language: matlab
16    args: ./src/model_function_modelB.m
17    function: model_function_modelB
18    inputs: x
19    outputs:
20      name: y
21      default_file:
22        name: ./output.txt
23        filetype: table
24        as_array: true
25        field_names: [mass]
26        field_units: [g]
27
28connections:
29  - input: matlab_modelA:y  # Connection between model A output & model B input
30    output: matlab_modelB:x

Python Version

Model Code:

1from yggdrasil import units
2
3
4def model_function(x):
5    y = x + units.add_units(1.0, 'g')
6    print("Model A: %s -> %s" % (x, y))
7    return y
1from yggdrasil import units
2
3
4def model_function(x):
5    y = x + units.add_units(2.0, 'g')
6    print("Model B: %s -> %s" % (x, y))
7    return y

Model YAML:

 1models:
 2  - name: python_modelA
 3    language: python
 4    args: ./src/model_function_modelA.py
 5    function: model_function
 6    iter_function_over: [x, y]
 7    inputs:
 8      name: x
 9      default_file:
10        name: ./Input/input.txt
11        filetype: table
12        as_array: true
13    outputs: y
14  - name: python_modelB
15    language: python
16    args: ./src/model_function_modelB.py
17    function: model_function
18    inputs: x
19    outputs:
20      name: y
21      default_file:
22        name: ./output.txt
23        filetype: table
24        as_array: true
25        field_names: [mass]
26
27connections:
28  - input: python_modelA:y  # Connection between model A output & model B input
29    output: python_modelB:x

R Version

Model Code:

1model_function <- function(x) {
2  y <- x + units::set_units(1.0, "g", mode="standard")
3  print(sprintf("Model A: %f -> %f", x, y))
4  return(y)
5}
1model_function <- function(x) {
2  y <- x + units::set_units(2.0, "g", mode="standard")
3  print(sprintf("Model B: %f -> %f", x, y))
4  return(y)
5}

Model YAML:

 1models:
 2  - name: r_modelA
 3    language: R
 4    args: ./src/model_function_modelA.R
 5    function: model_function
 6    iter_function_over: [x, y]
 7    inputs:
 8      name: x
 9      default_file:
10        name: ./Input/input.txt
11        filetype: table
12        as_array: true
13    outputs: y
14  - name: r_modelB
15    language: R
16    args: ./src/model_function_modelB.R
17    function: model_function
18    inputs: x
19    outputs:
20      name: y
21      default_file:
22        name: ./output.txt
23        filetype: table
24        as_array: true
25        field_names: [mass]
26
27connections:
28  - input: r_modelA:y  # Connection between model A output & model B input
29    output: r_modelB:x