Define a variable which evaluates when expression is evaluated, but not substitutes its definition to expression - maxima

Let's say, I want to declare an elliptic integral as
K(k):=elliptic_kc (k^2);
k:=<something like tanh()*coth()...>
The problem is that maxima will always substitute elliptic_kc(x^2) in place of K(x), and k's definition in place of k.
I want to prevent it, while still allowing numeric evaluation of K(), k, and simplifying expressions with these symbols.
...
A function, can be declared as "noun" for disabling substitution. But this also disables its evaluation.

Well, I use various strategies. Sometimes one approach works better than another.
(1) Put a single quote ' on function names to nounify that specific function call. At a later time, ev(expr, nouns) verbifies any nouns, so the functions are called. E.g. foo: 'integrate(sin(x), x); yields a noun expression. Then ev(foo, nouns); (which can be abbreviated to foo, nouns; at the console input) to actually calculate it.
(2) Don't define functions, but just let them be undefined symbols. Then substitute a lambda expression when you want to evaluate them. E.g. foo: f(2); then later subst(f = lambda([x], x + 1), foo);.
(3) Don't assign values, but let them be undefined, then substitute values later on. E.g. foo: a + b; then later subst([a = 123, b = y*z], foo);.

Related

Armadillo subview issue

The following fragment produces a compilation error:
arma::Mat<double> a(10,10,arma::fill::zeros);
arma::ucolvec w = whatever1;
whatever2 = a.rows(w).each_col() + another-col-vector;
The error is that arma::subview_elem2 has no member named each_col.
In a number of cases in Armadillo, the standard array functions are not always available on expressions or results of other function calls. Clearly the rows() function does not return a Mat object, but a subview_elem2 object, presumably for optimization. Another way to do this would be to declare all the array functions in interfaces/pure abstract classes that Mat and other internal classes, such as subviews, implement. It seems it should be possible to make all Armadillo array expressions interchangeable with array objects aside from write operations for expressions that only generate r-values.
So... I could wish for the following
a) An explanation of which methods are not available for which results.
b) Preferably, enabling all combinations of array methods that make sense.
Absent the above, how can accomplish the desired result, which is to evaluate the expression:
a.rows(w).each_col()
??
Some prior information about armadillo
The armadillo library uses templates heavily and most operations return expression templates. Only when you assign the result to a variable the actual computation is performed. This is why you should not store the result of some computation with armadillo using auto.
For instance, given some matrices A, B and C, something like
auto D = A * B + C;
will not perform the computation and only the expression template is stored in D. On the other hand, using
arma::mat D = A * B + C;
will force the computation to happen and the result is stored in D.
Solution to your problem
Particularly to your question, something like a.rows(w) returns an expression template of type subview_elem2 (this file is defined in the source code armadillo_bits/subview_elem2_bones.hpp). This "temporary type" does not have a .each_col method, which results in the error you got. One way around is to store the result of a.rows(w) in a variable, but since you are not interested in the variable you can use the .eval() method. The .eval() method forces the expression template to perform the actual computation up to that point and thus the subsequent call to .each_col will work. That is, replace
a.rows(w).each_col() + another-col-vector;
with
a.rows(w).eval().each_col() + another-col-vector;

Creating an 'add' computation expression

I'd like the example computation expression and values below to return 6. For some the numbers aren't yielding like I'd expect. What's the step I'm missing to get my result? Thanks!
type AddBuilder() =
let mutable x = 0
member _.Yield i = x <- x + i
member _.Zero() = 0
member _.Return() = x
let add = AddBuilder()
(* Compiler tells me that each of the numbers in add don't do anything
and suggests putting '|> ignore' in front of each *)
let result = add { 1; 2; 3 }
(* Currently the result is 0 *)
printfn "%i should be 6" result
Note: This is just for creating my own computation expression to expand my learning. Seq.sum would be a better approach. I'm open to the idea that this example completely misses the value of computation expressions and is no good for learning.
There is a lot wrong here.
First, let's start with mere mechanics.
In order for the Yield method to be called, the code inside the curly braces must use the yield keyword:
let result = add { yield 1; yield 2; yield 3 }
But now the compiler will complain that you also need a Combine method. See, the semantics of yield is that each of them produces a finished computation, a resulting value. And therefore, if you want to have more than one, you need some way to "glue" them together. This is what the Combine method does.
Since your computation builder doesn't actually produce any results, but instead mutates its internal variable, the ultimate result of the computation should be the value of that internal variable. So that's what Combine needs to return:
member _.Combine(a, b) = x
But now the compiler complains again: you need a Delay method. Delay is not strictly necessary, but it's required in order to mitigate performance pitfalls. When the computation consists of many "parts" (like in the case of multiple yields), it's often the case that some of them should be discarded. In these situation, it would be inefficient to evaluate all of them and then discard some. So the compiler inserts a call to Delay: it receives a function, which, when called, would evaluate a "part" of the computation, and Delay has the opportunity to put this function in some sort of deferred container, so that later Combine can decide which of those containers to discard and which to evaluate.
In your case, however, since the result of the computation doesn't matter (remember: you're not returning any results, you're just mutating the internal variable), Delay can just execute the function it receives to have it produce the side effects (which are - mutating the variable):
member _.Delay(f) = f ()
And now the computation finally compiles, and behold: its result is 6. This result comes from whatever Combine is returning. Try modifying it like this:
member _.Combine(a, b) = "foo"
Now suddenly the result of your computation becomes "foo".
And now, let's move on to semantics.
The above modifications will let your program compile and even produce expected result. However, I think you misunderstood the whole idea of the computation expressions in the first place.
The builder isn't supposed to have any internal state. Instead, its methods are supposed to manipulate complex values of some sort, some methods creating new values, some modifying existing ones. For example, the seq builder1 manipulates sequences. That's the type of values it handles. Different methods create new sequences (Yield) or transform them in some way (e.g. Combine), and the ultimate result is also a sequence.
In your case, it looks like the values that your builder needs to manipulate are numbers. And the ultimate result would also be a number.
So let's look at the methods' semantics.
The Yield method is supposed to create one of those values that you're manipulating. Since your values are numbers, that's what Yield should return:
member _.Yield x = x
The Combine method, as explained above, is supposed to combine two of such values that got created by different parts of the expression. In your case, since you want the ultimate result to be a sum, that's what Combine should do:
member _.Combine(a, b) = a + b
Finally, the Delay method should just execute the provided function. In your case, since your values are numbers, it doesn't make sense to discard any of them:
member _.Delay(f) = f()
And that's it! With these three methods, you can add numbers:
type AddBuilder() =
member _.Yield x = x
member _.Combine(a, b) = a + b
member _.Delay(f) = f ()
let add = AddBuilder()
let result = add { yield 1; yield 2; yield 3 }
I think numbers are not a very good example for learning about computation expressions, because numbers lack the inner structure that computation expressions are supposed to handle. Try instead creating a maybe builder to manipulate Option<'a> values.
Added bonus - there are already implementations you can find online and use for reference.
1 seq is not actually a computation expression. It predates computation expressions and is treated in a special way by the compiler. But good enough for examples and comparisons.

How to use rank operator instead of each in APL

I have
dummytxt←'abcdefghijk'
texttoadd←'down'
rfikv←20 30 50
and need following output
defghijk20down defghijk30down defghijk50down
I can do it with:
scenv←(¯10↑¨(⊂dummytxt),¨⍕¨rfikv),¨⊂texttoadd
but please help me to write without each operator but using rank ⍤
I use Dyalog APL, but please do not use trains.
Thank you
Expressions using Each, like f¨x, can be expressed in terms of Rank as {⊂f⊃⍵}⍤0⊢x (note that ⊢ is to separate the array right operand, 0 from the array right argument x). In other words, on the scalars of the argument we:
disclose the scalar: ⊃⍵
apply the function: f⊃⍵
enclose the result: ⊂f⊃⍵
A similar expression applies for the dyadic case, x f¨y, but we need to:
disclose both scalars: (⊃⍺)…(⊃⍵)
apply the function: (⊃⍺)f(⊃⍵)
enclose the result: ⊂(⊃⍺)f(⊃⍵)
This gives us x{⊂(⊃⍺)f(⊃⍵)}⍤0⊢y. We can thus use Rank to build our own Each operator which allows both monadic and dyadic application of the derived function:
Each←{⍺←⊢ ⋄ ⍺ ⍺⍺{×⎕NC'⍺':⊂(⊃⍺)⍺⍺(⊃⍵) ⋄ ⊂⍺⍺⊃⍵}⍤0⊢⍵}
(¯10↑Each(⊂dummytxt),Each⍕Each rfikv),Each⊂texttoadd
defghijk20down defghijk30down defghijk50down
Alternatively, we can substitute the two simpler equivalences into your expression:
(¯10{⊂(⊃⍺)↑(⊃⍵)}⍤0⊢(⊂dummytxt){⊂(⊃⍺),(⊃⍵)}⍤0{⊂⍕⊃⍵}⍤0⊢rfikv){⊂(⊃⍺),(⊃⍵)}⍤0⊂texttoadd
defghijk20down defghijk30down defghijk50down
Notice that we are enclosing texttoadd so it becomes scalar, and then we use ⍤0 to address that entire scalar, only to disclose it again. Instead, we can use ⍤0 1 to say that want to use the entire vector right argument when applying the function, which in turn doesn't need to disclose its right argument:
(¯10{⊂(⊃⍺)↑(⊃⍵)}⍤0⊢(⊂dummytxt){⊂(⊃⍺),(⊃⍵)}⍤0{⊂⍕⊃⍵}⍤0⊢rfikv){⊂(⊃⍺),⍵}⍤0 1⊢texttoadd
defghijk20down defghijk30down defghijk50down
rfikv and ¯10 are a simple scalars, so disclosing them has no effect:
(¯10{⊂⍺↑(⊃⍵)}⍤0⊢(⊂dummytxt){⊂(⊃⍺),(⊃⍵)}⍤0{⊂⍕⍵}⍤0⊢rfikv){⊂(⊃⍺),⍵}⍤0 1⊢texttoadd
defghijk20down defghijk30down defghijk50down
dummytxt is in the same situation as texttoadd above, but as left argument, so we can skip the enclose-disclose and ask Rank to use the entire vector left argument; ⍤1 0:
(¯10{⊂⍺↑(⊃⍵)}⍤0⊢dummytxt{⊂⍺,(⊃⍵)}⍤1 0{⊂⍕⍵}⍤0⊢rfikv){⊂(⊃⍺),⍵}⍤0 1⊢texttoadd
defghijk20down defghijk30down defghijk50down
This is about as simple as it gets using a general method. However, if we instead observe that the only non-scalar is rfikv, we can treat dummytxt and texttoadd as global constants and express the entire thing as a single ⍤0 function application on rfikv:
{⊂(¯10↑dummytxt,⍕⍵),texttoadd}⍤0⊢rfikv
defghijk20down defghijk30down defghijk50down
Of course, Each can do this too:
{(¯10↑dummytxt,⍕⍵),texttoadd}¨rfikv
defghijk20down defghijk30down defghijk50down

When to use parentheses when calling a function in f#?

I'm learning about f# and I understand you don't need to use parentheses when calling a function.
Ex
let addOne arg1 =
arg1 + 1
addOne 1
vs
this.GetType()
Why do I have to use parentheses on the second function?
There is a bit of a mismatch between working with .NET libraries and working with F# libraries when it comes to parameters, but you can generally see () not as parentheses, but as a special value of type unit that means "no useful information".
This means that when you say:
addOne 1
You are calling addOne with a value - number 1 - as a parameter. Now, when you apply the same reading to the second example:
this.GetType()
You can read this as calling this.GetType with a value - the special () unit value as a parameter. If you wanted to be consistent, you could write this with space too:
this.GetType ()
In practice, most people will omit the space when calling .NET libraries. When you do not write the space, F# also supports method chaining so you can write e.g. foo().bar().
Many F# functions taking multiple parameters will use the "curried" form, which means that the parameters need to be separated by spaces. For example:
let add a b = a + b
let mul a b = a * b
add 10 (mul 20 3)
Here, you need parentheses around the second expression, so that the compiler knows how to parse the code. This is in contrast with typical .NET methods, which take parameters as a tuple. F# tuples are written as (10, "hello") and so you can see a method call as an ordinary call accepting a tuple:
some.Operation (10, "Hello")
Again, typically you wouldn't write the space here, because you know this is actually a .NET method call, rather than "passing tuple to a function", but conceptually, you can think of it in both ways.
This is the summary - there are a few corner cases where method calls do not really behave like tuples (e.g. when it comes to named parameters), but this way of thinking about it should give you an idea about how things work.

Zero and Combine in Computation Expression

I have the following computation expression builder:
type ExprBuilder() =
member this.Return(x) =
Some x
let expr = new ExprBuilder()
I understand the purpose of methods Return, Zero and Combine, but I don't understand what is the difference between expressions shown below:
let a = expr{
printfn "Hello"
return 1
} // result is Some 1
let c = expr{
return 1
printfn "Hello"
} // do not compile. Combine method required
I also don't understand why in the first case Zero method in not required for printfn statement?
In the first expression, you perform some computation that results in value 1, and that's it. You don't need a Zero in it, because Zero is only needed for return-less expressions (that's why it's called "zero" - it's what is there when nothing is there), and your expression does have a return.
To specifically answer your question, Zero is not required "for the printfn statement", because not every line within the expression gets transformed. When compiling computation expressions, the compiler breaks them up at "special" points, such as let!, do!, return, etc., leaving all the rest of the code between those points intact. In this case, your printfn call just becomes part of the code that executes before the return.
In the second expression, you perform two computations: the first one results in value 1, and second one results in Zero (which is implicitly assumed when expression lacks a return). But the whole computation expression can't have two return values, it must have one. So in order to bring results of the two computations together (one might say, combine them), you need the Combine method.
Besides Combine and Zero, you'd also need to implement Delay for this to work. Multipart (i.e. "combined") computations are also wrapped in Delay in order to allow the builder to defer evaluation and possibly drop some parts within the Combine implementation.
I recommend reading through this introduction by Scott Wlaschin, specifically part 3 about Delay and Run.

Resources