Hi all,

Based on feedback I received today, I have now created versions of my examples of what CellML 1.2 might look like with embedded comments describing the MathML in a more succinct infix notation format (included in comments in the XML above the corresponding MathML). This should make them more readable and make it easier to comment on.

Best wishes,
Andrew
<c11:model xmlns:c11="http://www.cellml.org/cellml/1.1#"; 
xmlns:c12="http://www.cellml.org/cellml/1.2#"; 
xmlns:m="http://www.w3.org/1998/Math/MathML";>
  <c11:component name="TypeLibrary">
    <!-- type_from_type_function_type: The type of a function which takes a 
type and returns a type. -->
    <c12:variable name="type_from_type_function_type" type="type" 
public_interface="yes" />
    <!-- cartesian_complex_type_function: A function which converts a scalar 
type (parameter)
           into the type of the cartesian form of the complex number as a 
vector of two reals
           having the type of the parameter. -->
    <c12:variable name="complex_type_function" 
type="type_from_type_function_type" public_interface="yes"/>

    <!-- The following variables are used locally for bvars and the like 
only... -->
    <c12:variable name="base_type" type="type" />

    <m:math>
      <!-- type_from_type_function = function_type(type, type) -->
      <m:apply id="type_from_type_function_eqn"><m:eq/>
        <m:ci>type_from_type_function</m:ci>
        <m:apply><c12:function_type />
          <m:ci>type</m:ci>
          <m:ci>type</m:ci>
        </m:apply>
      </m:apply>

      <!-- We might want to build this into CellML 1.2 core (with the option
           that secondary specification don't support it) but if not, this is
           how complex numbers in their cartesian form could be defined. We
           probably should 
        -->
      <m:apply id="cartesian_complex_type_function_eqn"><m:eq/>
        <!-- complex_type_function = lambda base_type: vector_type(base_type, 
2) -->
        <m:ci>complex_type_function</m:ci>
        <m:lambda>
          <m:bvar><m:ci>base_type</m:ci></m:bvar>
        </m:lambda>
        <m:apply><c12:vector_type />
          <!-- First argument: type of vector elements... -->
          <m:ci>base_type</m:ci>
          <!-- Second argument: size of vector -->
          <m:cn c12:type="real_dimensionless">2</m:cn>
        </m:apply>
      </m:apply>
    </m:math>
  </c11:component>
</c11:model>
<c11:model xmlns:c11="http://www.cellml.org/cellml/1.1#"; 
xmlns:c12="http://www.cellml.org/cellml/1.2#"; 
xmlns:m="http://www.w3.org/1998/Math/MathML"; 
xmlns:xlink="http://www.w3.org/1999/xlink";>
  <c11:component name="ComplexUtilities">
    <!-- Connect up to the type you want this component to work with. -->
    <c12:variable name="base_type" type="type" public_interface="yes"/>

    <!-- The complex_type (can be computed from base_type). -->
    <c12:variable name="complex_type" type="type" public_interface="yes" />
    <c12:variable name="complex_to_base_function_type" type="type" 
public_interface="yes" />

    <!-- A function for fetching cartesian X co-ordinates. -->
    <c12:variable name="complex_get_cartesian_x" 
type="complex_to_base_function_type" public_interface="yes" />

    <c12:variable name="type_from_type_function_type" type="type" 
private_interface="yes" />
    <c12:variable name="complex_type_function" 
type="type_from_type_function_type" private_interface="yes"/>

    <!-- Local types -->
    <c12:variable name="base_type_to_dimensionless_function_type" type="type" />
    <c12:variable name="base_type_base_type_to_radians_function_type" 
type="type" />

    <!-- Local functions -->
    <c12:variable name="sign" type="base_type_to_dimensionless_function_type" />
    <c12:variable name="arctan2" 
type="base_type_base_type_to_radians_function_type" />

    <!-- Local bound variables -->
    <c12:variable name="complex" type="complex_type" />
    <c12:variable name="x" type="base_type" />
    <c12:variable name="y" type="base_type" />

    <m:math>
      <!-- An example of a units computation... -->
      <!-- complex_type = complex_type_function(base_type) -->
      <m:apply><m:eq/>
        <m:ci>complex_type</m:ci>
        <m:apply><m:ci>complex_type_function</m:ci>
          <m:ci>base_type</m:ci>
        </m:apply>
      </m:apply>

      <!-- complex_to_base_function_type = function_type(base_type, 
complex_type) -->
      <m:apply><m:eq/>
        <m:ci>complex_to_base_function_type</m:ci>
        <m:apply><c12:function_type/>
          <m:ci>base_type</m:ci>
          <m:ci>complex_type</m:ci>
        </m:apply>
      </m:apply>

      <!-- complex_get_real = lambda complex: vector_element(complex, 0) -->
      <m:apply><m:eq/>
        <m:ci>complex_get_real</m:ci>
        <m:lambda>
          <m:bvar><m:ci>complex</m:ci></m:bvar>
          <m:apply><c12:vector_element/>
            <m:ci>complex</m:ci>
            <m:cn c12:type="real_dimensionless">0</m:cn>
          </m:apply>
        </m:lambda>
      </m:apply>

      <!-- complex_get_imaginary = lambda complex: vector_element(complex, 1) 
-->
      <m:apply><m:eq/>
        <m:ci>complex_get_imaginary</m:ci>
        <m:lambda>
          <m:bvar><m:ci>complex</m:ci></m:bvar>
          <m:apply><c12:vector_element/>
            <m:ci>complex</m:ci>
            <m:cn c12:type="real_dimensionless">1</m:cn>
          </m:apply>
        </m:lambda>
      </m:apply>

      <!-- complex_get_polar_modulus = lambda complex: sqrt(complex_get_real^2 
+ complex_get_imaginary^2) -->
      <m:apply><m:eq/>
        <m:ci>complex_get_polar_modulus</m:ci>
        <m:lambda>
          <m:bvar><m:ci>complex</m:ci></m:bvar>
          <m:apply><m:root/>
            <m:apply><m:plus/>
              <m:apply><m:pow/>
                <m:apply><m:ci>complex_get_real</m:ci>
                  <m:ci>complex</m:ci>
                </m:apply>
                <m:cn c12:type="real_dimensionless">2</m:cn>
              </m:apply>
              <m:apply><m:pow/>
                <m:apply><m:ci>complex_get_imaginary</m:ci>
                  <m:ci>complex</m:ci>
                </m:apply>
                <m:cn c12:type="real_dimensionless">2</m:cn>
              </m:apply>
            </m:apply>
          </m:apply>
        </m:lambda>
      </m:apply>

      <!-- base_to_dimensionless_function_type = 
function_type(real_dimensionless, base_type) -->
      <m:apply><m:eq/>
        <m:ci>base_type_to_dimensionless_function_type</m:ci>
        <m:apply><c12:function_type/>
          <m:ci>real_dimensionless</m:ci>
          <m:ci>base_type</m:ci>
        </m:apply>
      </m:apply>

      <!-- base_type_base_type_to_radians_function_type = 
function_type(real_radians, base_type, base_type) -->
      <m:apply><m:eq/>
        <m:ci>base_type_base_type_to_radians_function_type</m:ci>
        <m:apply><c12:function_type/>
          <m:ci>real_radians</m:ci>
          <m:ci>base_type</m:ci>
          <m:ci>base_type</m:ci>
        </m:apply>
      </m:apply>

      <!-- This is a useful function; we could put it in another library. -->
      <!-- sign = lambda x: case when x = 0 then 0 when x < 0 then -1 else 1 
end -->
      <m:apply><m:eq/>
        <m:ci>sign</m:ci>
        <m:lambda>
          <m:bvar>x</m:bvar>
          <m:piecewise>
            <m:piece>
              <m:cn c12:type="real_dimensionless">0</m:cn>
              <m:apply><m:eq/>
                <m:ci>x</m:ci>
                <m:cn c12:type="base_type">0</m:cn>
              </m:apply>
            </m:piece>
            <m:piece>
              <m:cn c12:type="real_dimensionless">-1</m:cn>
              <m:apply><m:lt/>
                <m:ci>x</m:ci>
                <m:cn c12:type="base_type">0</m:cn>
              </m:apply>
            </m:piece>
            <m:otherwise>
              <m:cn c12:type="real_dimensionless">1</m:cn>
            </m:otherwise>
          </m:piecewise>
        </m:lambda>
      </m:apply>

      <!-- arctan2 = lambda x, y: (case when x = 0 then pi / 2 case when x > 0 
then arctan(|y/x|)
                                        otherwise pi - arctan(|y/x|) end) * 
sign(y)-->
      <m:apply><m:eq/>
        <m:ci>arctan2</m:ci>
        <m:lambda>
          <m:bvar><m:ci>y</m:ci></m:bvar>
          <m:bvar><m:ci>x</m:ci></m:bvar>
          <m:apply><m:times/>
            <m:piecewise>
              <m:piece>
                <m:apply><m:divide/>
                  <m:pi/>
                  <m:cn c12:type="real_dimensionless">2</m:cn>
                </m:apply>
                <m:apply><m:eq/>
                  <m:ci>x</m:ci>
                  <m:cn c12:type="base_type">0</m:cn>
                </m:apply>
              </m:piece>
              
              <m:piece>
                <m:apply><m:arctan/>
                  <m:apply><m:abs/>
                    <m:apply><m:divide/>
                      <m:ci>y</m:ci>
                      <m:ci>x</m:ci>
                    </m:apply>
                  </m:apply>
                </m:apply>
                <m:apply><m:gt/>
                  <m:ci>x</m:ci>
                  <m:cn c12:type="base_type">0</m:cn>
                </m:apply>
              </m:piece>
              
              <m:otherwise>
                <m:apply><m:minus/>
                  <m:pi />
                  <m:apply><m:arctan/>
                    <m:apply><m:abs/>
                      <m:apply><m:divide/>
                        <m:ci>y</m:ci>
                        <m:ci>x</m:ci>
                      </m:apply>
                    </m:apply>
                  </m:apply>
                </m:apply>
              </m:otherwise>
            </m:piecewise>
            
            <m:apply><m:ci>sign</m:ci>
              <m:ci>y</m:ci>
            </m:apply>
          </m:apply>
        </m:lambda>
      </m:apply>

      <!-- complex_get_polar_argument = lambda complex: 
arctan2(complex_get_cartesian_y, complex_get_cartesian_x) -->
      <m:apply><m:eq/>
        <m:ci>complex_get_polar_argument</m:ci>
        <m:lambda>
          <m:bvar><m:ci>complex</m:ci></m:bvar>
          <m:apply><m:ci>arctan2</m:ci>
            <m:apply><m:ci>complex_get_cartesian_y</m:ci>
              <m:ci>complex</m:ci>
            </m:apply>
            <m:apply><m:ci>complex_get_cartesian_x</m:ci>
              <m:ci>complex</m:ci>
            </m:apply>
          </m:apply>
        </m:lambda>
      </m:apply>
    </m:math>
  </c11:component>
  
  <c11:import xlink:href="type_library.cellml">
    <c11:component name="TypeLibrary" component_ref="TypeLibrary"/>
  </c11:import>
  
  <c12:encapsulation>
    <c11:component_ref component_ref="ComplexUtilities">
      <c11:component_ref component_ref="TypeLibrary"/>
    </c11:component_ref>
  </c12:encapsulation>

  <c12:connection component_1="TypeLibrary" component_2="ComplexUtilities">
    <c11:map_variables variable_1="type_from_type_function_type" 
variable_2="type_from_type_function_type" />
    <c11:map_variables variable_1="complex_type_function" 
variable_2="complex_type_function" />
  </c12:connection>
</c11:model>
_______________________________________________
cellml-discussion mailing list
[email protected]
http://www.cellml.org/mailman/listinfo/cellml-discussion

Reply via email to