## 9515 Reputation

18 years, 216 days

## multiple errors...

1. The parenthese in the final statement are mismatched;
2. The equal sign in the preceding statement should be an assignment operator;
3. The multiplication sign after m in the final statement is missing.

I think this is what you want

```if P2 = -Q2 then
return Expand( x-P1 ) mod p;
else
m := Expand( (3*P1^2+a)/(2*P2) );
return Expand( (y-P2 -m*(x-P1) ) / (x+P1+Q1-m^2  ));
end if;
```

## Missing separator....

There is no statement separator (: or ;) after the local y statement.

For the second problem, assign to h, not h(x).

## One approach...

While you could use a piecewise, a regular conditional seems better. What you planning to do with the sum (which is syntactically incorrect)? Better here would be to use an add. I'll assume you want to assign it to something, say s[k]:

```for k from 0 to 10 do
z[k] := ifelse(k=0, 1, 0);
s[k] := add((m^2-1)/z/(z[k]+1), m=0..k);  # this makes no sense
end do:
```

Note my comment; it doesn't make much sense to use both z and z[k] in an expression, though it is valid in Maple because z, following the assignment to z[k], is now a table, which will evaluate to a name (z). Unless you need to use z[k] later, I'd probably do something like

```for k from 0 to 10 do
zk := ifelse(k=0, 1, 0);
end do:
```

That avoids any weirdness with using a name (z) that evaluates to a table. However, it isn't clear whether you actually meant to use the unassigned name, z, in the expression. Maybe the addendum should be (m^2-1)/zk/(zk+1).

## ProcessOptions...

You can do this, more or less, by processing the arguments yourself.  See the help page for ProcessOptions.  This was how it was done back in the day.  The new way, where the kernel handles it, is much nicer.  My suggestion is to live with the current approach.

Later If you really want to do this and do not use either undeclared arguments or optional positional arguments, here is a hackish approach that could be used (I'm not recommending it). To make it palatable, I've envisioned it as a technique that would be used only during development---I see little reason to enforce your restrictions on users. The following shows the simple implementation. It uses preprocessor macros to assign code that would normally not be present; as such this would be only usable in text files (not in a worksheet).

```\$ifdef CHECK_CODE
\$define CHECK_ARGS \
if [_passed][1.._nparams] <> [_params[1.._nparams]] then \
error "the calling sequence does not match the parameter declaration"; \
end if;
\$else
\$define CHECK_ARGS
\$endif

f := proc(x :: integer, y :: integer, {key :: truefalse := false } )
CHECK_ARGS;
if key then
x + y;
else
x - y;
end if;
end proc:

f(1,2,key);
f(1,2);
f(1,key,2);
```

To test this using tty maple (command-line maple)

```\$ maple -q optional-args.mpl
3

-1

3
\$ maple -q -D CHECK_CODE  optional-args.mpl
3

-1

Error, (in f) the calling sequence does not match the parameter declaration
```

Later still Here's a too clever tip, usable if you have Maple2019. Rather than raising an error, use the following conditionally defined macro:

```\$ifdef CHECK_CODE
\$define CHECK_ARGS \
if [_passed][1.._nparams] <> [_params[1.._nparams]] then \
editsource(debugopts('callstack')[5]); \
end if;
\$else
\$define CHECK_ARGS
\$endif
```

If you have properly assigned the global variable `debugger/editor`, see the help page for the debugger, that should open the file that contains the source code for the procedure that generated the offending call. Probably you should raise the error after the call to editsource.

## Modelica syntax...

In addition to Carl's point, there are a few syntax errors in the modelica.  The class specifier should be model, not Model. Also, there is no semicolon after Main.  The Imports line should be removed. What version of MapleSim are you using?  The Modelica Code Editor should be able to catch those errors, when you save the model.

## Manage Style Sets...

Did you try the Manage Style Sets option in the Format menu?  See the help page ?worksheet,documenting,styles.

## linalg...

The aFshear routine is attempting to assign to a parameter (R).  That is not allowed.

You really should not be using linalg; it's been deprecated for quite a while.  There are equivalent methods in LinearAlgebra for the few linalg procedures you are using; the help pages for the linalg commands mentions what is appropriate.

## simplify with side relations...

Another way to do this is to use simplify with the siderels option. See the help page ?simplify,siderels for details.

```eqn1 := e1*i1 + e2*i2 + e3*i3 = 0:
sol := solve( { eqn1 } , { i1 } , 'explicit' ):
eqn2 := n12 = e1/e2:
simplify(sol, {eqn2}, {e1,e2});
{i1 = (-e3*i3*n12-e1*i2)/n12/e1}
expand(%);
{i1 = -1/e1*e3*i3-i2/n12}
```

## Details...

What version of Maple are you using? Is the error generated by the second line? Consider using the more robust with(Maplets:-Elements); using the colon-dash prevents an evaluation of Elements.

## Matrix Composition...

If you do this regularly, it might be useful to define a procedure/operator that performs the composition.  For example

````&@` := proc(M1 :: Matrix, M2 :: Matrix)
local M, i, j, k, m, n, p, q;
(m,n) := upperbound(M1);
(p,q) := upperbound(M2);
if n <> p then
error "Matrix dimensions are not compatible";
end if;
M := Matrix(m,q);
for i to m do
for j to q do
M[i,j] := add(M1[i,k](M2[k,j]), k = 1..n);
end do;
end do;
M;
end proc:
```

Here is a typical usage

```(**) M1 := Matrix([[D[1], 0],[0, D[1]+D[2]],[1,D[1]-2*D[2]]]):
(**) M2 := Matrix([[U[1],U[2]],[U[3],U[4]]]):
(**) M1 &@ M2;
[         D[1](U[1])                       D[1](U[2])          ]
[                                                              ]
[   D[1](U[3]) + D[2](U[3])          D[1](U[4]) + D[2](U[4])   ]
[                                                              ]
[1 + D[1](U[3]) - 2 D[2](U[3])    1 + D[1](U[4]) - 2 D[2](U[4])]

(**) map(apply, %, x,y);
[            D[1](U[1])(x, y)                             D[1](U[2])(x, y)             ]
[                                                                                      ]
[   D[1](U[3])(x, y) + D[2](U[3])(x, y)          D[1](U[4])(x, y) + D[2](U[4])(x, y)   ]
[                                                                                      ]
[1 + D[1](U[3])(x, y) - 2 D[2](U[3])(x, y)    1 + D[1](U[4])(x, y) - 2 D[2](U[4])(x, y)]

(**) convert(%, diff);
[             d                                          d                         ]
[             -- U[1](x, y)                              -- U[2](x, y)             ]
[             dx                                         dx                        ]
[                                                                                  ]
[   /d            \   /d            \          /d            \   /d            \   ]
[   |-- U[3](x, y)| + |-- U[3](x, y)|          |-- U[4](x, y)| + |-- U[4](x, y)|   ]
[   \dx           /   \dy           /          \dx           /   \dy           /   ]
[                                                                                  ]
[    /d            \     /d            \        /d            \     /d            \]
[1 + |-- U[3](x, y)| - 2 |-- U[3](x, y)|    1 + |-- U[4](x, y)| - 2 |-- U[4](x, y)|]
[    \dx           /     \dy           /        \dx           /     \dy           /]

```

LaterThis isn't quite right, the 1 in M1 doesn't act like the identity operator. I wish Maple provided a builtin for that. You could replace it with x->x.

## Differentiation...

Am not sure this is doable.  As an aside, you might want to use the inert forms, Sum and Int, in the procedure assignments, to avoid any attempt at a futile symbolic evaluation.

As a gross simplification, I think you want something like

```y := Sum(u[k]*v[k], k=1..n):
diff(y, u[j]);
```

to return either v[j] or, more ideally, piecewise(j :: integer[1..n], u[j], 0) (note that the latter is not actually valid Maple unless n is explicitly assigned a value). I'm not aware of any Maple packages that will do that.

## External Text Files...

The best way to do this is put the Maple source in ascii files and use version control on them.  Use either a read statement in a worksheet to read the source, or, better, create an mla (Maple Library Archive file) from the source, install it in a custom toolbox and use it from any Maple interface.

## Workaround...

Did you try what I suggested for your related question?  You should be able to use the same technique for a completely custom port, just enter the name you gave for the custom port in the text area. Hmm.  I see that there is a bug.  You can work around it by first inserting a copy of the custom port you created onto the main MapleSim canvas, then reclicking the Apply Custom button in the Custom Component Template (see my directions at your other post).

## Custom Port...

2. In the Type: combo-box, select Custom (it's the last choice).
3. In the text-area below that, enter Modelica.Thermal.FluidHeatFlow.Interfaces.FlowPort
4. Click the Apply Custom button

The rest should be handled as any other port.  You'll see signals for the pressure, enthalpy, mass flow rate and enthalpy flow rate.

## evalf...

Use evalf:

```sol := solve(g(x)>0,[x]):
evalf(sol);
[[x < -0.3399702769], [1.278826630 < x]]
```

Pass a positive integer as the second argument to evalf to select the number of digits

`evalf(sol, 20);`
 First 12 13 14 15 16 17 18 Last Page 14 of 114
﻿