MathGroup Archive 2006

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Types in Mathematica, a practical example

  • To: mathgroup at smc.vnet.net
  • Subject: [mg63615] Re: [mg62940] Re: [mg62800] Types in Mathematica, a practical example
  • From: "Ingolf Dahl" <ingolf.dahl at telia.com>
  • Date: Sat, 7 Jan 2006 02:29:51 -0500 (EST)
  • Sender: owner-wri-mathgroup at wolfram.com

This letter contains answers to [mg62940], [mg63087], [mg63188], [mg63190],
[mg63192] and [mg63198]. It has taken some time.

Hi Andrzej,
Comments are interlaced in the text below   

> -----Original Message-----
> From: Andrzej Kozlowski [mailto:akoz at mimuw.edu.pl] 
To: mathgroup at smc.vnet.net
> Subject: [mg63615] [mg62940] Re: [mg62800] Types in Mathematica, a 
> practical example
> 
> 
> On 8 Dec 2005, at 22:11, Ingolf Dahl wrote:
> 
> > I feel it as a round-about way to solve the problem.
> > Andrzej Kozlowski, who suggests such a solution, thinks that I am 
> > looking at Mathematica from the wrong view point. It is my strong 
> > belief that one should be able, especially when mathematics is 
> > involved, to observe from as many different view points as 
> possible. 
> > An item is not really beautiful, or properly designed, if it is not 
> > beautiful from all view points. The same should apply to 
> Mathematica, 
> > and I have also understood that Mathematica was 
> intentionally designed 
> > to be well-behaved when seen from different view points. Or?
> 
> 
> About mathematics: it seems to me that almost all beautiful 
> solutions  
> of difficult problems involve finding the right "point of view".   
> Often once the right point of view is found the problem is 
> almost solved, while from the other "wrong" points of view 
> the problem looks extremely hard  and often uninteresting - 
> (usually because it appears that the only way to solve it is 
> by a tedious computation or, in the case o finite problems, 
> by an exhaustive examination of all possible cases).
> About Mathematica: it is true that Mathematica allows many 
> styles of programming and that this has many practical 
> advantages, but it certainly is not true that all these 
> styles are equally efficient, elegant and equally suitable to 
> all types of problems. So if you mean that for any problem 
> that one wants to tackle with Mathematica it should not 
> matter whether you choose a functional approach, a procedural 
> approach, a re-write rule based approach, a recursive 
> approach etc,  well this definitely is not true and I do not 
> think it is reasonable to expect otherwise. In a similar vein 
> in mathematics certain problems are more suited to be tackled 
> with algebraic techniques, certain with topological, others 
> with analytic etc.

Oh, now you are thinking about different ways of solving problems. I
understand that you mean that functional programming gives the best view
point for what you conceive is my problem. Of course I do not think that all
methods are equally suitable for solving a specific problem. But to find the
best one has to investigate several view points. The method to solve a
difficult problem very often lies in the transformation itself between
different representations.
But what I was thinking of was also different ways to use Mathematica. It
might be used for making advanced calculations in a fast OR memory-efficient
way. One could make very specialized programs with very low flexibility in
the input, or general programs accepting an input range of high diversity.
It could be used for constructing mathematical proofs. But it might also be
used as a mathematical sandbox for playing with symbolic math for the
derivation of new formulas, or as a way to describe algorithms, or as a
didactic tool for transmitting and communicating mathematical ideas,
concepts and procedures. A functional-programming one-liner with lots of #,&
and @@ signs can be very efficient from the first point of view, but might
be a catastrophe if used in a pedagogic context in a premature school class.

> 
> About  your concrete proposal : I personally do not think it 
> would fit in well with the functional style of programming 
> that is usually the most natural way to tackle problems 
> involving lists, matrices etc in Mathematica and also I  do 
> not feel any need for what you are proposing and hence do not 
> see any benefit if something of this kind were to be 
> implemented in Mathematica. But I am sure that this is just a 
> matter of taste, exactly as my preferring certain areas of 
> mathematics to others is only a matter of taste.
> 
> Andrzej Kozlowski
> 

I have tried to find out exactly what is meant by "functional programming".
As far as I have understood the concept is here used in a rather vague way.
I have got the impression from what I have learnt that if I should claim
that I use a functional programming style in Mathematica, I should at least
follow three rules:
1) Programming structures (sequences, iterations, selections...) should be
reformulated and replaced by appropriate operation of functions.
2) Functions should not have side effects. (Maybe printing or other effects
well outside the program could be allowed.)
3) The command Set (=) should not be used for write&wipe of variables.
Setting a variable once to a constant value could maybe be tolerated, and
maybe some very local indices in sums, etc. In general SetDelayed (:=)
should be used instead of Set.
I do not really see any conflict with my proposal here. My proposal was
about how to define a matrix or a list (or anything with a head) when you
have partial knowledge about it, a quite common situation if you have your
eyes open for that possibility. I do not know if you also consider such
problems when you mention "problems involving lists, matrices etc in
Mathematica".
I have a very limited knowledge about functional programming, but I have
difficulties in understanding that functional programming in any way should
affect the amount of information that we adhere to the variables e.g. by
"typing".
I wonder if your style of functional programming is best suited to cases
when the programmer at the instance of programming has full control of the
character of all involved variables; the numeric content of the variables
may vary, but the interpretation about what the variable represents is kept
outside the program as implicit "exformation".
(http://www.worldwidewords.org/turnsofphrase/tp-exf1.htm)
When the programmer is in that lucky situation, the programs can be very
short and efficient. In other cases the input might be of greater
variability, and then we might need to provide the program with more
explicit information about the interpretation of the input data. Then
"tagging" or "object oriented programming" might be more appropriate, with
the extra overload required. And I think that this really is in the spirit
of the main principle of functional programming: try to solve problems by
constructing appropriate functions. Mathematical "objects" and "typed"
variables can be the appropriate functions mapping objects, structures or
concepts from a real or imagined universe outside the programming
environment to the mathematical structures inside. 


> -----Original Message-----
> From: Andrzej Kozlowski [mailto:akoz at mimuw.edu.pl] 
To: mathgroup at smc.vnet.net
> Subject: [mg63615] [mg63087] Re: [mg62800] Types in Mathematica, a 
> practical example
> 
> Here is an alternative approach, which I am suspect you will 
> not like, but which is the kind of thing I would probably do 
> if I felt the problem you describe as a serious enough 
> inconvenience. The solution is in the spirit of what I regard 
> as the main principle of functional programming: try to solve 
> problems with syntax by defining appropriate functions. In 
> this case the function we need is very
> simple:
> 
> MatrixPlus[x_?MatrixQ, y_?MatrixQ] /; Dimensions[x] == 
> Dimensions [y] := x + y
> 
> Now you can at once do:
> 
> 
> a = {{1, 2}, {3, 4}};
> 
> 
> MatrixPlus[a, -x] /. x -> a
> 
> {{0, 0}, {0, 0}}
> 
> Since you like to be "in the typing business" you would 
> probably want to have an infix notation for MatrixPlus. One 
> could choose some suitable symbol and use the Notation 
> package to achieve it.
> 
> In fact, it might be a good idea to add some more specialised 
> matrix functions that would have properties like:
> 
> MatrixExpand[(a_).MatrixPlus[b_, c_]] := MatrixPlus[a.b, a.c ]
> 
> etc, that would make it possible to do more with symbols that 
> represent matrices (some of which could be actual matrices 
> while others just undefined symbols). All of this seems quite 
> feasible and probably might even be useful for someone who 
> does a lot of symbolic work with matrices. For all I know 
> someone might even have implemented something like this already.
> 
> Andrzej Kozlowski
> 

Now you are in the "rebuilding Mathematica" business. Since Mathematica has
quite general programming capabilities, we could use the power of
Mathematica to more or less rebuild the whole program. This is always a
temptation when problems occur, but then we cannot reuse already written
code. In this case, I cannot see the benefits of doing it. I can use my
proposed method, so I would not be helped. And you do not see the problem I
see, and do not need my proposal, so I do not think you are helped either.
And if you, or anyone else, build such a package, you soon might want to
form linear combinations of matrices, and then there is a need again of
mixing of symbols for numbers and matrices. Then you either have to type the
symbols explicitly in some way, or do it implicitly by applying some
functions to numbers and other to matrices. 
It is not that I do not like your approach, the thing is that it did not
answer the question I asked (or meant to ask). Asking questions is a
difficult thing that I do not master fully. To really make the question
exact and precise one has to know the answer. And then there is of course no
reason to ask the question. I asked for a way to "type" x and not for a way
to redefine Plus, since I was more interested in the "typing" problem than
to resolve the example I gave.


> -----Original Message-----
> From: Andrzej Kozlowski [mailto:akoz at mimuw.edu.pl] 
To: mathgroup at smc.vnet.net
> Subject: [mg63615] [mg63188] Re: EUREKA Re: [mg62800] Types in 
> Mathematica, a practical example
> 
> 
> On 17 Dec 2005, at 02:26, Ingolf Dahl wrote:
> 
> >
> >
> > My suggestion to define a 2x2 list of undefined elements is the
> > following:
> >
> > x = {{HoldForm[x[[1,1]]], HoldForm[x[[1,2]]]}, {HoldForm[x[[2,1]]], 
> > HoldForm[x[[2,2]]]}};
> 
> You really do love this typing business ;-) Why not:
> 
> 
> In[1]:=
> x = Array[HoldForm[x[[##1]]] & ,
>     {2, 2}]
> 
> Out[1]=
> {{HoldForm[x[[1,1]]],
>     HoldForm[x[[1,2]]]},
>    {HoldForm[x[[2,1]]],
>     HoldForm[x[[2,2]]]}}

Nice! Thanks!
 
> >
> > Occasionally, when you have defined some of the undefined elements, 
> > you may convert to Input Form or have to apply ReleaseHold or 
> > ReplaceAll[#,HoldForm[Part[a__]]:>Part[a]]& @ to get rid of the 
> > invisible HoldForm surrounding the indexed elements. For Set and 
> > SetDelayed you can get this automatically by the command
> 
> Hm... have you really tried it:
> 
> ReplaceAll[#,HoldForm[Part[a__]]:>Part[a]]& @x
> 
> {{HoldForm[x[[1,1]]],
>     HoldForm[x[[1,2]]]},
>    {3, HoldForm[x[[2,2]]]}}
> 
Snipped in from [mg63192]:
 
> It seems I forgot to copy and paste enough from Mathematica 
> to make my point clear. So here it is more fully. Define:
> 
> 
> 
> x = Array[HoldForm[x[[##1]]] & , {2, 2}]
> 
> 
> {{HoldForm[x[[1,1]]], HoldForm[x[[1,2]]]},
>    {HoldForm[x[[2,1]]], HoldForm[x[[2,2]]]}}
> 
> 
> Now set x[[1,1]] to 3
> 
> x[[1,1]] = 3; x
> 
> Out[6]=
> {{3, HoldForm[x[[1,2]]]}, {HoldForm[x[[2,1]]],
>     HoldForm[x[[2,2]]]}}
> 
> Let's remove HoldForm (you can use ReplaceAll[#,HoldForm[Part 
> [a__]]:>Part[a]]& @ as you suggested: it won't make any difference):
> 
> 
> x /. HoldForm -> Identity
> 
> Out[7]=
> {{3, HoldForm[x[[1,2]]]}, {HoldForm[x[[2,1]]],
>     HoldForm[x[[2,2]]]}}
> 
> 
> You see, nothing changed at all because when HoldForm[x[[1,2]]] was  
> released x[[1,2]] was immediately replaced by 
> HoldForm[x[[1,2]], etc.  
> In fact I completely fail to see any benefits of having 
> HoldForm here  
> compared with (for example) defining
> 
> 
> x=Array[Unique[x]&,{2,2}]
> 
> Have I missed your point?
> 
> Andrzej Kozlowski
> 

I was unclear here, and maybe too rapid. As I see it now, there is only one
case when this replacement would be useful, and that is if you have a
complicated expression, which is held by Hold, and want to get rid of all
HoldForm expressions inside. Not too common, maybe. However, say that we
have an expression

f = Det[x] 

where x is defined as Array[HoldForm[x[[##1]]] & ,{2, 2} . 
The value of f is

(-HoldForm[x[[1,2]]])*HoldForm[x[[2,1]]] +
HoldForm[x[[1,1]]]*HoldForm[x[[2,2]]]

If we now set 

x[[2,1]] = 3

then f will still keep the same value. We can the either apply the above
replacement operator, or simply do ReleaseHold to enter the value 3 into the
value of f. Thus

ReleaseHold[f]

gives

-3*HoldForm[x[[1,2]]] + HoldForm[x[[1,1]]]*HoldForm[x[[2,2]]]

 
> 
> >
> > Unprotect[HoldForm]; HoldForm /: Set[ HoldForm[ 
> Part[a__]],b_]:= Set[ 
> > Part[a],b]; HoldForm /: SetDelayed[ HoldForm[ Part[a__]],b_]:= 
> > SetDelayed[ Part[a],b];  Protect[HoldForm];
> 
> Since I consider redefining basic built in functions as 
> "unnecessary evil" I will stop at this. Personally I just 
> can't see any point in all of this  but of course this is 
> just a personal opinion. Those who  
> like or imagine it could be useful it can pursue this further.   
> However, there is just one more thing to deal with:
 
These redefinitions are not necessary, but could maybe be convenient
sometimes. I do not think it is too dangerous to give meaning to things that
had no meaning before.

> 
> > ___________________________________________________________
> > When I played with this, I came across the following:
> >
> > Assume, that the value of axxx is not defined. Then
> >
> > Hold[Part[axxx, 57, 62]] /. {axxx -> b}
> >
> > returns
> >
> > Hold[b[[57,62]]]
> >
> > but if we first assign any value to axxx, e.g. Indeterminate, we 
> > instead obtain
> >
> > Hold[axxx[[57,62]]]
> >
> > Can someone explain?
> 
> This is pretty obvious and I am sure you can explain it yourself.  
> However, since you asked ..
> 
> If aaax has the value Intermediate then in
> 
> ReplaceAll[Hold[Part[axxx, 57, 62]], {Rule[axxx, b]}]
> 
> the second argument evaluates to Intermediate->b, so all you 
> are doing is evaluating:
> 
> Hold[Part[axxx, 57, 62]] /. {Intermediate -> b}
> 
> Use instead
> 
> 
> Hold[axxx[[57,62]]] /.
>    {HoldPattern[axxx] -> b}
> 
> 
> Hold[b[[57,62]]]
 
Thanks, silly of me.
 
> >
> > And I wish everybody A Merry Christmas and A Happy New Year!
> >
> 
> I fully agree with this!
> 
> Andrzej Kozlowski
> 

> -----Original Message-----
> From: Andrzej Kozlowski [mailto:akoz at mimuw.edu.pl] 
To: mathgroup at smc.vnet.net
> Subject: [mg63615] [mg63190] Re: EUREKA Re: [mg62800] Types in 
> Mathematica, a practical example
> 
> If you feel really want do it in this sort of  way, I  suggest 
> the following approach:
> 
> 
> x=Array[Unique[x]&,{2,2}]
> 
> 
> {{x$23,x$24},{x$25,x$26}}
> 
> etc.
> 
> I think in this way you get all the benefits of your approach 
> without all the problems that will result from using 
> HoldForm. (Somebody might have suggested this already; I have 
> not followed all the suggestions carefully since I do not 
> myself feel any need for a solution to this problem.)
> 
> Andrzej Kozlowski
> 
> 


> -----Original Message-----
> From: Andrzej Kozlowski [mailto:akoz at mimuw.edu.pl] 
To: mathgroup at smc.vnet.net
> Subject: [mg63615] [mg63198] Re: EUREKA Re: [mg62800] Types in 
> Mathematica, a practical example
> 
> I forgot one thing: how to deal with your original problem.
> 
> In[1]:=
> a=Array[Unique[a]&,{2,2}]
> 
> Out[1]=
> {{a$17,a$18},{a$19,a$20}}
> 
> In[2]:=
> a-x/.Flatten[Thread/@Thread[a->x]]
> 
> Out[2]=
> {{0,0},{0,0}}
> 
> 
> Seems to me a little simpler than with the HoldForm approach.
> 
> Andrzej
>  

This makes sense if we instead take 

a = {{1, 2}, {3, 4}}; x = Array[Unique[x] &, {2, 2}]; 
a - x /. Flatten[Thread /@ Thread[x -> a]] 

In this example the names generated by Unique are of no importance, so your
approach is OK here. Mathematica often allows many roads towards the goal.
However, if we would like to derive symbolic expressions, such variables
would be extremely ugly.

Best regards

Ingolf Dahl
RE: [mg63185] Re: EUREKA Re: [mg62800] Types in Mathematica, a practical
example


> 
> 
> On 6 Dec 2005, at 03:41, Ingolf Dahl wrote:
> 
> > To MathGroup,
> >
> > I am not an advocate for strong typing in Mathematica, but consider 
> > the following simple example: I want to see if two matrices 
> are equal.
> > One of
> > them was the result from some equation, and is given inside 
> a rule.  
> > Then I
> > write some code similar to this:
> >
> >
> >
> > a = {{1, 2}, {3, 4}};
> >
> > x - a /. {x -> a}
> >
> >
> >
> > I of course hope to get a matrix filled by zeroes, but if x is 
> > undefined, the following is returned:
> >
> >
> >
> > {{{{0, 1}, {2, 3}}, {{-1, 0}, {1, 2}}}, {{{-2, -1}, {0, 1}}, {{-3, 
> > -2}, {-1, 0}}}}
> >
> >
> >
> > First x was assumed to be a number, and (x - a) was 
> evaluated. Then x 
> > was substituted by the matrix a. No bug in Mathematica, but 
> it was not 
> > what I wanted as user. It is easy to make such a mistake in the 
> > programming. Of course there are many ways to get around 
> this problem, 
> > but is there any reasonably simple way to "type" x to be a list of 
> > lists without specifying the elements, in such a way that the above 
> > example works?
> >
> >
> >
> > I could do
> >
> >
> >
> > ReleaseHold[Hold[x - a] /. {x -> a}]
> >
> >
> >
> > but then we are not in the "typing business" any longer.
> >
> >
> 
> 



  • Prev by Date: Re: Re: EUREKA Re: Types in Mathematica, a practical example
  • Next by Date: Re: Re: Conditional drop of list elements
  • Previous by thread: Re: Re: EUREKA Re: Types in Mathematica, a practical example
  • Next by thread: Another question: How to add some assumptions to this Integrand?