Group Abstract Group Abstract

Message Boards Message Boards

0
|
7.8K Views
|
7 Replies
|
3 Total Likes
View groups...
Share
Share this post:

How do I convey to a func that its arguments are quaternions by default?

Posted 10 years ago

I'd like to be able to do something like (mixed syntax)

q1=Quaternion,

q2=Quaternion,

q3=Quaternion,:

f[q1_, q2_, q3_]:= [some function that only makes sense for quaternions.]

The specific question is how do I convey to f that the arguments are quaternions by default?

Thanks for helping this newbie (I worry that in some way this question doesn't even make sense in MMA - if so please educate me.)

POSTED BY: lester welch
7 Replies
Posted 10 years ago

Mathematica is not strongly typed. If you provide arguments that match the structure of the definition, so that the function as used does in fact match the definition, then the function will evaluate as expected. If the form of the arguments as used does not match the definition, the rule which was established by the function definition will not apply, and Mathematica will just return the input. You can restrict the match by using Conditionals in the function definition.

For example, here are a few lines of code that define our own complex numbers, as ordered pairs, by rules for adding and multiplying them. No type restrictions were needed:

In[1]:= complexPlus[{r1_, i1_}, {r2_, i2_}] := {r1 + r2, i1 + i2}

In[2]:= complexTimes[{r1_, i1_}, {r2_, i2_}] := {r1 r2 - i1 i2, 
  r1 i2 + r2 i1}

In[3]:= (* argument structure does not match definition *)

In[4]:= complexPlus[a, b]

Out[4]= complexPlus[a, b]

In[5]:= (* this matches *)

In[6]:= complexPlus[{x, y}, {u, v}]

Out[6]= {u + x, v + y}

In[7]:= c1 = {x, y}; c2 = {u, v};

(* so does this *)

In[9]:= complexPlus[c1, c2]

Out[9]= {u + x, v + y}
POSTED BY: David Keith

You can use TagSet to enforce type safety. Create a predicate with TagSet.

q1 /: IsQuaternian[q1] = True
q2 /: IsQuaternian[q2] = True
q3 /: IsQuaternian[q3] = True

Now if you do pattern matching in your function definition using this new predicate, you'll enforce "type safety"

func[q_?IsQuaternian] := 1

In[17]:= func[q1]
Out[17]= 1
In[18]:= func[t2]
Out[18]= func(t2)
POSTED BY: Eric Smith
Posted 10 years ago

Thanks. I know that as one gains experience in a new paradigm, it becomes more natural. I'm an "old-timer" - started in FORTRAN II - migrated through Fortran versions, assemblers (VAX, 8080 family),Pascal, Modula II, LISP,C, (even a bit - ashamed to say- COBOL), C++, HTML, and was just getting into JAVA and the use of programmer's GUI interfaces when I retired. When I first encountered "object-oriented" programming I was stumped as well, but learned the benefits - as I will do with MMA. Good community and very helpful. I've actually got some problems solved now! :-)

POSTED BY: lester welch
Posted 10 years ago

Thanks. Looks useful.

POSTED BY: lester welch
Posted 10 years ago

And yes, Mathematica is not strongly typed, but the interesting question is "how does strong typing benefit me?". Having answered that question, look for ways that Mathematica can provide those same benefits. Mathematica actual does have powerful facilities for helping you attain correctness in your code. While I personally think it's unhelpful to try to mimic object oriented programming with Mathematica (and, yes, that can be done), you can get similar benefits by using more Mathematica-natural idioms. For example, using custom symbols as heads for data structures allows you to define functions that apply to only those data structures. You can then create custom constructors, accessors, etc. You won't get compile time type mismatch errors (that doesn't even make sense with Mathematica), but you will get un-simplified expression, which in some ways is actually better, because you can inspect exactly what the expression is that didn't get pattern-matched to anything. (This is exactly what happened in the example in your previous post that was missing the comma--something pretty easy to detect once you've worked in Mathematica for awhile.)

POSTED BY: Eric Rimbey
Posted 10 years ago

You can also override built in functions for certain argument types:

In[10]:= x = MyType["x"]

Out[10]= MyType["x"]

In[11]:= y = MyType["y"]

Out[11]= MyType["y"]

In[12]:= Plus[a_MyType, b_MyType] ^:= Join[a, b]

In[13]:= Plus[x, y]

Out[13]= MyType["x", "y"]
POSTED BY: Eric Rimbey
Posted 10 years ago

Lester,

Look at documentation for Pattern (and follow the related links). There are several ways to restrict your functions to specific argument "types" (i.e. make the pattern matching more restrictive).

For example:

In[1]:= mySum[a_Integer, b_Integer] := a + b

In[2]:= mySum[1.1, 2.2]

Out[2]= mySum[1.1, 2.2]

In[3]:= mySum[1, 2]

Out[3]= 3

Or

In[4]:= myPositiveSum[a_?Positive, b_?Positive] := a + b

In[5]:= myPositiveSum[1.1, 2.2]

Out[5]= 3.3

In[6]:= myPositiveSum[-1.1, 2.2]

Out[6]= myPositiveSum[-1.1, 2.2]

Or

In[7]:= myOrderedSum[a_, b_] := a + b /; a > b

In[8]:= myOrderedSum[1, 1]

Out[8]= myOrderedSum[1, 1]

In[9]:= myOrderedSum[2, 1]

Out[9]= 3
POSTED BY: Eric Rimbey
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard