Message Boards Message Boards

MatlabForm and ComsolForm

I extensively use Comsol for my work and I use Mathematica to modify or create some expressions that I utilize in Comsol.

Comsol has the same syntax as Matlab (for the most part). Hence, I created a simple function that outputs an expression ready to be inputted in Comsol.

I use the fact that FortranForm is pretty similar to Matlab, hence:

MatlabForm[L_List] := MatlabForm/@L
MatlabForm[expr_] := ToString@FortranForm[expr /. {
  Complex[0, Rational[1, b_]] :> "1j"/MatlabForm@b,
  Complex[0, Rational[a_, b_]] :> "1j"*MatlabForm[MatlabForm@a/MatlabForm@b],
  Complex[0, b_] :> "1j"*MatlabForm@b,
  Complex[a_, b_] :> MatlabForm@a + "1j"*MatlabForm@b,
  a_^Rational[1,2] | Sqrt[a_] :> sqrt@MatlabForm@a,
  E^x_ :> exp@MatlabForm@x,
  Rational[1, b_] :> 1/MatlabForm@b,
  Rational[a_, b_] :> MatlabForm[MatlabForm@a/MatlabForm@b],
  (op:Abs|Cos|Sin|Tan|Exp)[x_] :> ToLowerCase[ToString@op][MatlabForm@x],
  Conjugate[x_] :> "conj"@MatlabForm@x,
  Re[x_] :> "real"@MatlabForm@x,
  Im[x_] :> "imag"@MatlabForm@x
}] // StringReplace[#, {"**" -> "^", "\"" -> ""}] &

Which basically deals with some very basic (but nonetheless useful) operations/functions.

The final result also needs to human readable for debug purposes, so I created another function:

MatlabFormSimplify[expr_] := Block[{res},
    ClearAttributes[{Plus, Times}, Orderless];
    res = MatlabForm@Simplify[Simplify@expr, ComplexityFunction -> StringLength@*MatlabForm,
     TransformationFunctions -> {
       Automatic,
       Function[{e}, e /. (op:Times|Plus)[a___, b_, c_, d___] :> op[a, c, b, d]]
     }];
    SetAttributes[{Plus, Times}, Orderless];
    res
]

Which strip-out the Orderless attribute of Plus and Times, so b-a never evaluates to -a+b, which is ugly and has too many symbols.

A real example would be:

Cross[{Ax, Ay, Az}, Conjugate@{Bx, By, Bz}] // MatlabFormSimplify // TableForm
(* output *) 
"conj(Bz)*Ay - conj(By)*Az"
"conj(Bx)*Az - conj(Bz)*Ax"
"conj(By)*Ax - conj(Bx)*Ay"

Compare with the standard Mathematica output:

{-Az Conjugate[By] + Ay Conjugate[Bz], Az Conjugate[Bx] - Ax Conjugate[Bz], -Ay Conjugate[Bx] + Ax Conjugate[By]}

PS: I don't usually output lists as Matlab [...], since, as I already said, I use Comsol, hence is more important to define scalar quantities based on symbolic expressions. PSS: More functions can be easily added. I rather created my own function, that I fine-tuned, than use an outdated Package.

POSTED BY: Thales Fernandes
10 Replies
Posted 3 years ago

Would you consider submitting it to the Function Repository?

POSTED BY: Baker Ren

I extensively use Comsol for my work and I use Mathematica to modify or create some expressions that I utilize in COMSOL.

For 'modify' part, don't you also need an inverse definitions to import an existing COMSOL expression into Mathematica for simplification?

POSTED BY: Kapio Letto

For 'modify' part, don't you also need an inverse definitions to import an existing COMSOL expression into Mathematica for simplification?

I don't get your meaning of inverse definition, but you can access Comsol expressions by expanding the "equations" tag, where you can use Mathematica latter to parse the data by, for example, converting ewfd.Ez to a string "ewfd.Ez" or just stripping the ewfd tag. You can use Matlab to import all such equations, parse it into Mathematica, create a rule-based substitution and end-up with a simplified version of an equation.

POSTED BY: Thales Fernandes

Have you seen the ToMatlab package? It seems like a natural foundation to build on top of.

POSTED BY: Szabolcs Horvát

Have you seen the ToMatlab package? It seems like a natural foundation to build on top of.

Yes, I have. But an 18-year-old package seems quite a lot to me. It was also made with the thought that everything is a matrix. So every expression has a "." preceding it. Comsol does not accept such a things. I needed something simpler. No need to get overly complicated with things, the bare bones would suffice. And what better ways do to things as to "recycle" a built-in function to do your deeds?

POSTED BY: Thales Fernandes

But an 18-year-old package seems quite a lot to me.

Old is not usually bad :-) It is designed to be easily extensible.

It was also made with the thought that everything is a matrix.

That is literally the case in MATLAB. MATLAB does not know about scalars or vectors. The lowest-dimensional array it can work with is 2, even for types like struct or char (!!) It is called MATrix LABoratory for a reason.

Comsol does not accept such a things.

Of course, then you need something else.

POSTED BY: Szabolcs Horvát

That is literally the case in MATLAB. MATLAB does not know about scalars or vectors. The lowest-dimensional array it can work with is 2, even for types like struct or char (!!) It is called MATrix LABoratory for a reason.

A 1x1 matrix is what we usually call scalars and 1xn or nx1 matrix is what we call vectors... In Matlab you can totally fine run something like:

x = 2;
y = x^2;
z = y.^2;

Whereas y and z give the same result. But if the definition of x is changed to a vector or non-square matrix we get for y:

error

So, obviously, Matlab knows what a scalar is... It is a 1x1 matrix!

So the drawback of using such a package is this one, it always assumes the variables to be matrices (or tensors). And, as stated, I mainly use this piece of code in Comsol, but, it could be used entirely fine in Matlab.

POSTED BY: Thales Fernandes

A 1x1 matrix is what we usually call scalars and 1xn or nx1 matrix is what we call vectors...

That depends on who "we" is. Physicist usually call a two-index tensor a matrix, even if it is a 1 by 1 tensor. I know that many engineering books just fall back to "row matrices" and "column matrices" for vectors.

What I meant is that the data structure that MATLAB uses is always a two (or higher) dimensional array. You can see this if you work with the MEX interface, because it exposes the data representation.

But it also has practical consequences in how one does calculations. Since MATLAB does not have true vectors, you cannot write vector*matrix*vector, as you can do vector.matrix.vector in Mathematica. You must keep in mind whether you have a "column vector" (column matrix really) or "row vector" and you must transpose when needed.

Another consequence of this representation is that MATLAB supports both 0 by n and n by 0 matrices (and distinguishes them). Only the latter can be represented in Mathematica as {{}}, but not the former.

Finally, * is an element-wise product in Mathematica. Thus converting a*b to a*b may be correct for Comsol, but it is only correct for "scalars" in MATLAB. The translation a.*b is correct for both "scalars" and larger matrices.

POSTED BY: Szabolcs Horvát

That depends on who "we" is. Physicist usually call a two-index tensor a matrix, even if it is a 1 by 1 tensor. I know that many engineering books just fall back to "row matrices" and "column matrices" for vectors.

As a physicist myself, I'm not part of this "norm"... Tensors in physics have a physical meaning, matrices don't. Matrices are far too general, they don't need to transform covariantly. But call all you want, a rank 17 tensor in 1 dimension is still a scalar, no matter how pretty and more sophisticated it would be to be to call it a tensor. An equally valid point would be to call all real numbers Octonions with zero imaginary part, and argue that there are no "true" real numbers... But I don't think such pedantic matters on semantics has much to add to the discussion. One should use the lingo which one is used to...

Matlab indeed treats everything as a matrix (I never argued to oppose it), but not all definitions need to be "vectorized". You can be equally happy by making a function that only accepts scalars. As in Mathematica, not all functions have attribute Listable.

Matlab own error handling call 1x1 matrices scalars, so, why can't we all? Just because internally they are two-dimensional arrays? Should we still can a matrix a matrix if it has rank different then 2? Or call it an array? Tensor?

In Comsol, you can only modify vectors, tensors, component-wisely, so, there is no need to have a high-level representation in terms of dot products, matrix multiplication etc.

POSTED BY: Thales Fernandes
Posted 7 years ago

I am also a COMSOL user. Thanks very much for this!

POSTED BY: David Keith
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract