Force evaluate index expression before passing to sum() - symbolic-math

I want to write an (somehow) enhanced sum function which takes a number of indices at once, but I cannot understand how to get it work. Here is what I currently have:
(%i1) nsum(indexes, expr) :=
if indexes = []
then expr
else nsum(rest(indexes), sum(expr, first(indexes),1, N)) $
(%i2) nsum([i,j], i+j), nouns;
sum: index must be a symbol; found intosym(first(indexes))
#0: nsum(indexes=[k,j],expr=k+j)
I think this could be fixed by forcing Maxima expand first(indexes) into a symbol before passing to sum function. I tried ''(...) and ev(..., nouns), but without any success.

After some reading and trying I came to the following solution which uses apply function to pre-evaluate arguments for sum:
nsum(indexes, expr) :=
if indexes = []
then expr
else nsum(rest(indexes), apply(sum, ['expr, indexes[1], 1, N])) $
UPD1:
Unfortunately, there is something wrong with the above code, as it works well only for relatively simple expressions. In my case the straightforward approach works fine where nsum fails:
(%i1) rot[i](f) := sum(sum(sum(sum(
G[r,i]*G[q,j]*w[i,j,k]*('diff(f[k], y[q]) + sum(K[k,q,m]*f[m], m, 1, N)),
r, 1, N),
j, 1, N),
k, 1, N),
q, 1, N) $
(%i2) rot2[i](f) := nsum( [r,j,k,q],
G[r,i]*G[q,j]*w[i,j,k]*('diff(f['k], y[q]) + sum(K[k,q,m]*f[m], m, 1, N))) $
(%i3) rot[1](f);
(%o3) ... Yelds the result.
(%i4) rot2[1](f);
apply: subscript must be an integer; found: k
lambda([i,j],diff(ys[i],x[j]))(i=k,j=1)
UPD2:
The code works indeed. It was 'k accidentally left in rot2 definition instead of just k.

Related

how to iterate with two iterators

I would like to use nimbioseq and iterate two files with the same number of sequences (using the readSeq()iterator), as:
for seq1, seq2 in readSeq(file1), readSeq(file2):
echo seq1.id, "\t", seq2.id
For this scenario I suppose I need some sort of "zipping" operator, which I couldn't understand how to use [ found this: https://hookrace.net/nim-iterutils/iterutils.html#zip.i,,Iterable[S] ].
or alternatively understand how to get a single "iteration" outside a for loop (if possible):
for seq1 in readSeq(file1):
let seq2 = readSeq(file2);
echo seq1.id, "\t", seq2.id
Thanks for you help!
toClosure from iterutils is limited, but you can:
import iterutils
template initClosure(id,iter:untyped) =
let id = iterator():auto{.closure.} =
for x in iter:
yield x
initClosure(f1,readSeq(file1))
#creates a new closure iterator, 'f1'
initClosure(f2,readSeq(file2))
#creates a new closure iterator, 'f2'
for seq1,seq2 in zip(f1,f2):
echo seq1.id,"\t",seq2.id
Edit: thanks to #pietropeter for pointing out the bug, here's their example rewritten using this template:
import iterutils
template initClosure(id:untyped,iter:untyped) =
let id = iterator():auto {.closure.} =
for x in iter:
yield x
iterator letters: auto =
for c in 'a' .. 'z':
yield c
# Now requires a parameter
iterator numbers(s: int): int =
var n = s
while true:
yield n
inc n
initClosure(cletter,letters())
initClosure(numbers8,numbers(8))
for (c, n) in zip(cletter, numbers8):
echo c, n
I'm going to use this iterators code from Manual, and insert your problem in it. I'm sure it has room for improvement:
type
Task = iterator (r: var int)
iterator f1(r: var int){.closure.} =
for n in [1, 3, 5]:
r = n
yield
iterator f2(r: var int){.closure.} =
for n in [2, 4, 6]:
r = n
yield
proc runTasks(t: varargs[Task]) =
var ticker = 0
var r: int
while true:
var x = t[ticker mod t.len]
x(r)
echo r
if finished(x): break
inc ticker
runTasks(f1, f2)
You'll see in the output 1,2,3,4,5,6,6 (finished is prone to error, as stated in the manual, and returns the last item twice). You have to update the code, replacing r: var int with whatever type returns readSeq(file) (r: var Record, I think), and replace the iterators for n in [1, 2, 3] with for s in readSeq(file).
If the type of behaviour you want is that of zip, the one from iterutils seems to work fine. The only caveat is that it requires closure iterators (see manual for the difference between inline and closure iterators). Example (https://play.nim-lang.org/#ix=2yXV):
import iterutils
iterator letters: char {.closure.} =
for c in 'a' .. 'z':
yield c
iterator numbers: int {.closure.}=
var n = 1
while true:
yield n
inc n
for (c, n) in zip(letters, numbers):
echo c, n
I see that readseq in nimbioseq is not closure but probably something like this could work (edit: its should not, see below):
iterator closureReadSeqs(filename: string): Record {.closure.} =
for rec in readSeqs(filename):
yield rec
Edit
For the case of iterator with a parameter in the comments, the fix is to have a proc that returns an iterator (which will be a closure iterator by default in this case). Updated example (https://play.nim-lang.org/#ix=2z0e):
import iterutils
iterator letters: char {.closure.} =
for c in 'a' .. 'z':
yield c
# Now requires a parameter
proc numbers(s: int): iterator(): int =
return iterator(): int =
var n = s
while true:
yield n
inc n
let numbers8 = numbers(8)
for (c, n) in zip(letters, numbers8):
echo c, n
Now my best guess on how to make this work for nimbioseq is:
proc closureReadSeqs(filename: string): iterator(): Record =
return iterator(): Record =
for rec in readSeqs(filename):
yield rec

Convert double for loop into recursion func

I work with two 3D arrays, which the second arr changes according to the first arr.
I try to turn double for loop into a recursive function, but the same error is repeated, RecursionErroe: maximum recursion depth exceeded in comparison.
The for loops i'm trying to convert:
def to_rec(arr):
new = arr.copy()
row_max = len(arr)
col_max = len(arr[0])
for i in range(row_max):
for j in range(col_max):
new[i, j, :] = 255- arr[i, j, :]
return new
RECURSIVE
def rec2(img, row_max, col_max, i, j, new):
if j == col_mac:
return new
else:
new[i, j, :] = 255 - img[i, j, :]
return rec2(img, row_max, col_max, i, j+1, new)
****************************************************
def rec1(img, row_max, col_max, i, j, new):
if i == row_max:
return new
else:
rec2(img, row_max, col_max, i, j, new)
return rec1(img, row_max, col_max, i+1, 0, new)
********************************************************
def to_rec(arr):
......
# The same data as in to_rac func with the for loop
......
new = rec1(arr, row_max, col_max, 0, 0, new)
return new
I can't figure out what is wrong
While this doesn't answer your question about recursion depth, I think the solution is quite simple. It seems you want to invert an image (new[i, j, 0] = 255- arr[i, j, 0]) by looping over all pixels in the image, and then manipulating the pixel value. This can be done highly efficiently using NumPy:
import numpy as np
img = load_img_data() # Replace this by your own data
new_img = 255 - np.array(img)
When your data is stored in a NumPy array, you can trivially perform scalar arithmetics (addition, multiplication, etc.) on matrices. This way you don't have to perform nested loops (or recursive operations).
The search term RecursionError: maximum recursion depth exceeded has plenty of answers on SO - the reason is simple:
you try to recuse but your function/data does not allow it:
data too big so that you would need to recurse max_depth+n times to solve it
your data (or method) will never reach the end-condition of your recursion
your function has no end condition
Your recursion is flawed and you never reach the end - hence you dive deeper and deeper and put callstack upon callstack until python raises the error to avoid a Stackoverflow from accumulated stack frames due to thousands of function calls.
Ex:
# recurses crashes every time (no end condition)
def no_end_1(k = True):
no_end_1(not k)
# recursion works if you call it with some data but not with other data
def no_end_2(i):
if i == 0:
return "Done"
no_end_2(i-1)
no_end(25) # works
no_end(-3) # crashes
def flawed_collatz_testmethod(a):
# collatz conjectur holds for numbers up to
# 2.361.183.346.958.000.000.001 (wikipedia), they converge on 1
if a%2 == 0:
new_a = a//2
else:
new_a = 3*a+1
if new_a < 1:
print ("Collatz was wrong")
else:
# will eventually end in a loop of 4-2-1-4-2-1-4-2-1-... and crash
flawed_method(new_a)
In any case .. you need to fix your function. Best way to do it is to take a small datasample, a pen and paper and draw/calculate what the function does to see why it recurses endlessly.

Setlength in Delphi 10.2.3 for array like types

Although I found some postings concerning the subject setlength I couldn't find out a solution for my problem:
With the code below - which is part of a much bigger program -
type TVektor2=array[20] of extended;
TElement2=array[20] of String;
Procedure Sort_Shell2(
element1X: TElement2; zahlX: TVektor2; var Element2X : TElement2;
var zahl2X : TVektor2);
var
bis, i, j, k, min : LongInt; l, laenge : single;
h,s,w,h1,h2, ElemX: string;
e : array[20] of String;
begin
laenge := 5; // just an example
SetLength(Element1X, 3); /// Error
//DynArraySetlength(e,l,1); /// how?
bis := High(e);
k := bis shr 1;// div 2
while (k > 0) do
begin
for i := 0 to (bis - k) do
begin
j := i;
h1 := e[j]; //I use this because before I had an Acces violation
h2 := e[j + k]; // using directly e[j] := e[j+k];
while (j >= 0) and (h1 > h2) do
begin
h := h1;
l:=zahlx[j]; //str(l:5:3,S);showmessage(h + s);
e[j] :=e[j + k];
zahlx[j] := zahlx[j+ k];
e[j + k] := h;
zahlx[j+ k]:=l;
if j > k then
Dec(j, k)
else
j := 0;
end; // {end while]
end; // { end for}
k := k shr 1; // div 2
end; // {end while}
Element2x:=e; zahl2x :=zahlx;
end;
I get the error 'incompatible types' if I try the setlength command like this.
I tried - with a for next loop -to attribute to each position of the static array (with 20 entries) or also to the correponding dynamic array and then to use setlength.
But it didn't work. Is there some casting possible to transform TElement2 to an array ? (since it is already an array!)
Why isn't it possible to use a simple static array[1..20] of strings = a, set for each position a[i] = TElement2[i] and use setlength(a,5)?
If I use DynArraySetLength(Pointer, typeInfo,dimCnt, lengthVec) what must I use for these variables?
I don't know nearly anything about Pointers and I have no idea for such problem what parameters I must use to get an array of a given length starting with the given TElement2 array. By the way, in general, is it a good idea to use dynamic arrays?
By the way there might also be an error in this sorting routine because it doesn't work well...
Can any one help me?
In order to use a Dynamic Array in Delphi you have to declare an array like this:
TElement2=array of String;
and not TElement2=array[20] of String or TElement2=array[1..20] of String;
If you declare TElement2 that way then SetLength(element1X, 3); is going to work.
moreover when you assign at the bottom of the code
Element2x:=e;
it's not going to compile unless both variable aren't declared of the same type:
e : TElement2;

Error using linsolve: Matrix must be positive definite

I am trying to use compressed sensing for a 2D matrix. I am trying to run the following piece of code -
Nf=800;
N=401;
E=E(Nf,N); %matrix of signal(this only for sampling) real matrix E is 2D matrix with size of Nf and N
% compressive sensing
M=ceil(0.3*N);
psi=fft(eye(N));
phi=randi(M,N);
EE = permute(E,[2 1]);
theta=phi*psi;
for k=1:Nf
y(:,k)=phi*EE(:,k);
end
x0 = theta.'*y;
for p=1:Nf
X_hat(:,p) = l1eq_pd(x0(:,p), theta, [], y(:,p), 1e-5); %l1eq_pd=l1-magic
end
X1_hat=psi*X_hat;
XX_hat=permute(X1_hat,[2 1]);
but while running the code I get the following error.
Error using linsolve
Matrix must be positive definite.
Error in l1eq_pd (line 77)
[w, hcond] = linsolve(A*A', b, opts);
Error in simulation_mono_SAR (line 91)
X_hat(:,p) = l1eq_pd(x0(:,p), theta, [], y(:,p), 1e-5);
Could someone point me, what is the problem? Is it a problem inherent to l1-magic? shall I use another solver?

shuffle array in Go

I tried to translate the following Python code to Go
import random
list = [i for i in range(1, 25)]
random.shuffle(list)
print(list)
but found my Go version lengthy and awkward because there is no shuffle function and I had to implement interfaces and convert types.
What would be an idiomatic Go version of my code?
dystroy's answer is perfectly reasonable, but it's also possible to shuffle without allocating any additional slices.
for i := range slice {
j := rand.Intn(i + 1)
slice[i], slice[j] = slice[j], slice[i]
}
See this Wikipedia article for more details on the algorithm. rand.Perm actually uses this algorithm internally as well.
As your list is just the integers from 1 to 25, you can use Perm :
list := rand.Perm(25)
for i, _ := range list {
list[i]++
}
Note that using a permutation given by rand.Perm is an effective way to shuffle any array.
dest := make([]int, len(src))
perm := rand.Perm(len(src))
for i, v := range perm {
dest[v] = src[i]
}
Since 1.10 Go includes an official Fisher-Yates shuffle function.
Documentation: pkg/math/rand/#Shuffle
math/rand: add Shuffle
Shuffle uses the Fisher-Yates algorithm.
Since this is new API, it affords us the opportunity
to use a much faster Int31n implementation that mostly avoids division.
As a result, BenchmarkPerm30ViaShuffle is
about 30% faster than BenchmarkPerm30,
despite requiring a separate initialization loop
and using function calls to swap elements.
See also the original CL 51891
First, as commented by shelll:
Do not forget to seed the random, or you will always get the same order.
For example rand.Seed(time.Now().UnixNano())
Example:
words := strings.Fields("ink runs from the corners of my mouth")
rand.Shuffle(len(words), func(i, j int) {
words[i], words[j] = words[j], words[i]
})
fmt.Println(words)
Answer by Evan Shaw has a minor bug. If we iterate through the slice from lowest index to highest, to get a uniformly (pseudo) random shuffle, according to the same article, we must choose a random integer from interval [i,n) as opposed to [0,n+1).
That implementation will do what you need for larger inputs, but for smaller slices, it will perform a non-uniform shuffle.
To utilize rand.Intn(), we can do:
for i := len(slice) - 1; i > 0; i-- {
j := rand.Intn(i + 1)
slice[i], slice[j] = slice[j], slice[i]
}
following the same algorithm from Wikipedia article.
Maybe you can also use the following function:
func main() {
slice := []int{10, 12, 14, 16, 18, 20}
Shuffle(slice)
fmt.Println(slice)
}
func Shuffle(slice []int) {
r := rand.New(rand.NewSource(time.Now().Unix()))
for n := len(slice); n > 0; n-- {
randIndex := r.Intn(n)
slice[n-1], slice[randIndex] = slice[randIndex], slice[n-1]
}
}
When using the math/rand package, do not forget to set a source
// Random numbers are generated by a Source. Top-level functions, such as
// Float64 and Int, use a default shared Source that produces a deterministic
// sequence of values each time a program is run. Use the Seed function to
// initialize the default Source if different behavior is required for each run.
So I wrote a Shuffle function that takes this into consideration:
import (
"math/rand"
)
func Shuffle(array []interface{}, source rand.Source) {
random := rand.New(source)
for i := len(array) - 1; i > 0; i-- {
j := random.Intn(i + 1)
array[i], array[j] = array[j], array[i]
}
}
And to use it:
source := rand.NewSource(time.Now().UnixNano())
array := []interface{}{"a", "b", "c"}
Shuffle(array, source) // [c b a]
If you would like to use it, you can find it here https://github.com/shomali11/util
Raed's approach is very inflexible because of []interface{} as input. Here is more convenient version for go>=1.8:
func Shuffle(slice interface{}) {
rv := reflect.ValueOf(slice)
swap := reflect.Swapper(slice)
length := rv.Len()
for i := length - 1; i > 0; i-- {
j := rand.Intn(i + 1)
swap(i, j)
}
}
Example usage:
rand.Seed(time.Now().UnixNano()) // do it once during app initialization
s := []int{1, 2, 3, 4, 5}
Shuffle(s)
fmt.Println(s) // Example output: [4 3 2 1 5]
And also, don't forget that a little copying is better than a little dependency
Use Shuffle() from the math/rand library.
Here's an example:
package main
import (
"fmt"
"math/rand"
"strings"
)
func main() {
words := strings.Fields("ink runs from the corners of my mouth")
rand.Shuffle(len(words), func(i, j int) {
words[i], words[j] = words[j], words[i]
})
fmt.Println(words)
}
Since it comes from the math/rand library it needs to be seeded. See here for more details.

Resources