function which return s-tuples with non-negative integers and a given sum $n$ - maple

I am trying to write a function which return s-tuples with non-negative integers and a given sum $n$ (the sum of each tuple is $n$). In the program, I need to use s nested loops:
for i1 from 0 to n do
for i2 from 1 to n do
...
for is from 1 to n do
end for;
end for;
end for;
How could I use only a few loops instead of s loops? Thank you very much.

I suggest the combinat:-composition() command. On its own, the command won't include zero terms, but you can instead partition n+s and remove 1 from each term at the end:
restart;
partitions := proc( n :: posint, s :: posint, { allowzero :: truefalse := false } )
local P, u:
if allowzero = false then
P := convert( combinat:-composition( n, s ), 'list' ):
return select( u -> numelems(u) = s, P ):
else
P := procname( n + s, s, ':-allowzero'=false ):
return map( u -> u -~ 1, P ):
end if:
end proc:
partitions( 5, 2, ':-allowzero'=false ); # [ [1,4], [2,3], [3,2], [4,1] ]
partitions( 5, 2, ':-allowzero'=true ); # [ [0,5], [1,4], [2,3], [3,2], [4,1], [5,0] ]

Related

Is this scala function using right-fold or left-fold?

def calculate(f: Int => Int, sumProd:(Int, Int)=>Int, n: Int, a:Int, b:Int):Int =
if (a>b) n
else sumProd(f(a), calculate(f, sumProd, n, a+1, b))
This scala function can in a chosen number area (a to b) do chosen calculations with them:
example calling:
calculate(x=>2*x, (x,y)=>x+y, 0, 2 , 4)
this calculates: 2*2 + 2*3 + 2*4 = 18
Which folding(right- or left folding) is this function using? And how to see that?
further example callings for the function:
calculate(x=>2+x, (x,y)=>x*y,1, 2 , 4)
calculate(x=>2+x, (a,b)=>a+b,0, 1, 5)
calculate(x=>2*x, (a,b)=>a+b,0, 1, 5)
What you have is equivalent to, in pseudocode,
calculate(f, sumProd, n, a, b)
=
fold-right( sumProd, n, map(f, [a .. b]))
where [a .. b] denotes a list of numbers from a to b, inclusive, increasing by the step of 1. In other words, it is the same as
=
sumProd( f(a),
sumProd( f(a2),
sumProd( f(a3),
...
sumProd( f(b), n) ... )))

How to implement A = sparse(I, J, K) (sparse matrix from triplet) in a Fortran mex file?

I'm trying to create a sparse square matrix in Matlab through a mex function (written in Fortran). I want something like A = sparse(I,J,K) . My triplets look like this, there are repetitions among the entries
femi = [1, 2, 3, 2, 2, 4, 5, 5, 4, 6, 6, 5, 5, 2]
femj = [2, 2, 1, 1, 1, 3, 3, 6, 3, 1, 1, 2, 2, 4]
femk = [2, 1, 5, 4, 2, 4, 5, 7, 2, 1, 6, 2, 1, 4]
I've written a rough piece of code, it works for small matrix dimensions, but it's much slower than the intrinsic Matlab's sparse. Since I have almost no background in coding, I don't know what I'm doing wrong (wrong way to allocate variables? too many do loops?). Any help is appreciated. Thank you. This is the mex computational subroutine. It returns the pr, ir, jc indices array to give to the sparse matrix
subroutine new_sparse(femi, femj, femk, pr, ir, jc, n, m)
implicit none
intrinsic:: SUM, COUNT, ANY
integer :: i, j, k, n, indjc, m
real*8 :: femi(n), femj(n), femk(n)
real*8 :: pr(n)
integer :: ir(n),jc(m+1)
logical :: indices(n)
indices = .false.
k = 1
indjc = 0
jc(1) = 0
do j=1,m
do i =1,m
indices = [femi==i .and. femj==j]
if (ANY(indices .eqv. .true.)) then
ir(k) = i-1
pr(k) = SUM(femk, indices)
k = k+1
indjc = indjc + 1
end if
end do
if (indjc/=0) then
jc(j+1) = jc(j) + indjc
indjc = 0
else
jc(j+1) = jc(j)
end if
end do
return
end
Edit:
As suggested by users #jack and #veryreverie in the comments below, it's better to sort directly femi, femj and femk. I guess that ranking/sorting femi first (and sorting femj and femk according to femi) and then ranking/sorting femj (and sorting femi and femk according to femj) provides the desired result. The only thing left is to deal with duplicates.
Edit #2 :
I translated line by line the serialized version of the C code by Engblom and Lukarksi . This document explains very clearly their reasoning and I think it's useful for beginners like me. However, due to my inexperience, I was unable to translate the parallelized version of the code. Maybe that prompts another question.
subroutine new_sparse(ir, jcS, pr, MatI, MatJ, MatK, n, m)
! use omp_lib
implicit none
integer, parameter :: dp = selected_real_kind(15,300)
integer, intent(in) :: n, m
real(dp), intent(in) :: MatK(n), MatI(n), MatJ(n)
! integer*8, intent(out) :: nnew
integer :: i, k, col, row, c, r !, nthreads
integer :: hcol(m+1), jcS(m+1), jrS(m+1)
integer :: ixijs, irank(n), rank(n)
real*8 :: pr(*)
integer :: ir(*)
hcol = 0
jcS = 0
jrS = 0
do i = 1,n
jrS(MatI(i)+1) = jrS(MatI(i)+1)+1
end do
do r = 2,m+1
jrS(r) = jrS(r) + jrS(r-1)
end do
do i = 1,n
rank(jrS(MatI(i))+1) = i
jrS(MatI(i)) = jrS(MatI(i)) + 1
end do
k = 1
do row = 1,m
do i = k , jrS(row)
ixijs = rank(i)
col = MatJ(ixijs)
if (hcol(col) < row) then
hcol(col) = row
jcS(col+1) = jcS(col+1)+1
end if
irank(ixijs) = jcS(col+1)
k = k+1
end do
end do
do c = 2,m+1
jcS(c) = jcS(c) + jcS(c-1)
end do
do i = 1,n
irank(i) = irank(i) + jcS(MatJ(i))
end do
ir(irank) = MatI-1
do i = 1,n
pr(irank(i)) = pr(irank(i)) + MatK(i)
end do
return
end
This should work:
module test
implicit none
! This should probably be whatever floating point format Matlab uses.
integer, parameter :: dp = selected_real_kind(15,300)
contains
subroutine new_sparse(femi, femj, femk, pr, ir, jc, n, m)
integer, intent(in) :: n ! The size of femi, femj, femk.
integer, intent(in) :: m ! The no. of rows (and cols) in the matrix.
integer, intent(in) :: femi(n) ! The input i indices.
integer, intent(in) :: femj(n) ! The input j indices.
real(dp), intent(in) :: femk(n) ! The input values.
real(dp), intent(out) :: pr(n) ! The output values.
integer, intent(out) :: ir(n) ! The output i indices.
integer, intent(out) :: jc(m+1) ! Column j has jc(j+1)-jc(j) non-zero entries
! loop indices.
integer :: a,b
! Initialise jc.
! All elements of `jc` are `1` as the output initially contains no elements.
jc = 1
! Loop over the input elements.
do_a : do a=1,n
associate(i=>femi(a), j=>femj(a), k=>femk(a))
! Loop over the stored entries in column j of the output,
! looking for element (i,j).
do b=jc(j),jc(j+1)-1
! Element (i,j) is already in the output, update the output and cycle.
if (ir(b)==i) then
pr(b) = pr(b) + femk(a)
cycle do_a
endif
enddo
! Element (i,j) is not already in the output.
! First make room for the new element in ir and pr,
! then add the element to ir and pr,
! then update jc.
ir(jc(j+1)+1:jc(m+1)) = ir(jc(j+1):jc(m+1)-1)
pr(jc(j+1)+1:jc(m+1)) = pr(jc(j+1):jc(m+1)-1)
ir(jc(j+1)) = i
pr(jc(j+1)) = k
jc(j+1:) = jc(j+1:) + 1
end associate
enddo do_a
end subroutine
end module
program prog
use test
implicit none
integer, parameter :: n = 14
integer, parameter :: m = 6
integer :: femi(n), femj(n)
real(dp) :: femk(n)
real(dp) :: pr(n)
integer :: ir(n),jc(m+1)
integer :: a,b
femi = [1, 2, 3, 2, 2, 4, 5, 5, 4, 6, 6, 5, 5, 2]
femj = [2, 2, 1, 1, 1, 3, 3, 6, 3, 1, 1, 2, 2, 4]
femk = real([2, 1, 5, 4, 2, 4, 5, 7, 2, 1, 6, 2, 1, 4], dp)
write(*,*) 'Input:'
do a=1,n
write(*,'(a,i0,a,i0,a,f2.0)') '(',femi(a),',',femj(a),') : ',femk(a)
enddo
write(*,*)
call new_sparse(femi,femj,femk,pr,ir,jc,n,m)
write(*,*) 'Output:'
do a=1,m
do b=jc(a),jc(a+1)-1
write(*,'(a,i0,a,i0,a,f2.0)') '(',ir(b),',',a,') : ',pr(b)
enddo
enddo
end program
This writes:
Input:
(1,2) : 2.
(2,2) : 1.
(3,1) : 5.
(2,1) : 4.
(2,1) : 2.
(4,3) : 4.
(5,3) : 5.
(5,6) : 7.
(4,3) : 2.
(6,1) : 1.
(6,1) : 6.
(5,2) : 2.
(5,2) : 1.
(2,4) : 4.
Output:
(3,1) : 5.
(2,1) : 6.
(6,1) : 7.
(1,2) : 2.
(2,2) : 1.
(5,2) : 3.
(4,3) : 6.
(5,3) : 5.
(2,4) : 4.
(5,6) : 7.
The bottleneck in your algorithm comes from the instructions indices = [femi==i .and. femj==j], any(indices .eqv. .true.) and sum(femk, indices). These all take O(n) operations, and as these are within a double loop the overall cost of the subroutine is O(m^2*n).
My algorithm works in two stages. The first stage, the do b=jc(j),jc(j+1)-1 loop, compares each element in the input with each element in the matching column of the output, for a maximum cost of O(mn) operations. If the input element is found in the output, then the value is updated and nothing more needs to be done.
If the input element is not found in the output, then it needs to be added to the output. This is handled by the second stage, the code after the do b... loop. Since this needs to move the output elements in order to make space for the new element, this stage has a maximum of O(n'^2) operations, where n' is the number of unique elements in the input, which should satisfy n'<=n and n'<<m^2 for a sparse matrix.
My algorithm should run a lot faster for large m and n, but it certainly has a lot of scope for improvement. I suspect it is worth using an intermediate data structure for storing ir and pr, so that new elements can be inserted without having to re-arrange all the elements to do so.

How do I use value of variable in Maple

How do I get Maple to give the value of a variable in the RHS of an expression, rather than treat it as a variable in an expression. In the following code I want a list of three functions of x which are quadratics with different offsets, but it's not what I get:
ix := [-1,0,1]:
b := []:
for a in ix
do
b := [op(b),x->(x-a)^2];
end do;
and the output is
while I would like it to be (for the last line)
b := [ x -> (x+1)^2, x -> x^2, x -> (x-1)^2 ]
Your problem is that you are trying to use values for a in the construction of the body of a procedure, and not the "RHS of an expression" as you stated.
Try not to use the term "function" in this context, as it just muddles the distinction between expression and procedure.
Here is a way to get the values from ix as replacements for a in a generated list of procedures with (x-a)^2 in the body.
restart;
ix := [-1,0,1]:
b := []:
for a in ix do
b := [op(b), unapply((x-a)^2,x)];
end do:
b;
[x -> (x+1)^2, x -> x^2, x -> (x-1)^2]
It is inefficient to construct lists in this way, by repeatedly concatenating them. Since that practice scales badly in performance you really ought to drop it as a practice.
You can construct the whole list with one call to seq.
Flist := [ seq( unapply((x-a)^2,x), a in ix ) ]:
Flist;
[x -> (x+1)^2, x -> x^2, x -> (x-1)^2]
Here, Flist is a list of procedures, each of which can be evaluated at a value by calling it with an argument.
Flist[1];
x -> (x+1)^2
Flist[3](3.4);
5.76
#plot(Flist, -2..2);
Note: Procedures which display with the arrow notation x -> ... are called operators.
For fun, here are equivalents, using expressions,
Elist := [ seq( (x-a)^2, a in ix ) ]:
Elist;
[ 2 2 2]
[(x + 1) , x , (x - 1) ]
Elist[1];
2
(x + 1)
eval(Elist[3], x=3.4);
5.76
#plot(Elist, x=-2..2);
There are other ways to generate the procedures, with values of a in the body being specified programmatically. The unapply command is not the only possible mechanism, although it is the easiest for your example.
Another way is to substitute, for example,
generic := x -> (x-_dummy)^2:
Hlist := [ seq( subs(_dummy=a, eval(generic)), a in ix ) ]:
Hlist;
[x -> (x+1)^2, x -> x^2, x -> (x-1)^2]

How to make a proc that aply for all variables in maple

for example supposed I want to program a proc that plus 1 to all results that is a real numbers in my program. Is there a way to do that ?
You can use anames('user') to obtain top-level, user-defined variables, and then select those that are real-valued. In the code below, calling incrementReals() will increment all such variables:
restart;
a, b, c := 3, 1 - I, 0.5;
# Procedure to increment by 1 all user-defined variables that are of type 'realcons'.
incrementReals := proc()
local A := select( u -> type( eval(u), 'realcons' ), [ anames( 'user' ) ] ):
local B := map( u -> eval(u) + 1, A ):
assign( A =~ B );
return NULL:
end proc:
# Increment.
incrementReals();
# Confirm that a and b were incremented, but b was not.
'a' = a, 'b' = b, 'c' = c; # a = 4, b = 1 - I, c = 1.5

list comprehension without parentheses in a function

I have a function that needs to return the last property of an object that satisfies the condition:
types = {
a: 1,
b: 2,
c: 3
}
g = (s) -> v for k, v of types when k is s
console.log g 'b'
this code prints [ 2 ]
I expected just 2, and not an array. And indeed, this code does print what I expect:
console.log v for k, v of types when k is 'b'
What is wrong?
P.S. I know that instead of this function I can just access the object's property using [], but this is a contrived example.
If we rearrange the code then things should be clearer.
Your second piece of code:
console.log v for k, v of types when k is 'b'
is just another way of writing this:
for k, v of types when k is 'b'
console.log(v)
or even:
for k, v of types
if k is 'b'
console.log(v)
Since there is only one 'b' key, only one console.log call is made.
Your first piece of code:
g = (s) -> v for k, v of types when k is s
is the same as this:
g = (s) ->
a = (v for k, v of types when k is s)
a
The loop, v for k, v of types when k is s yields an array by definition so a will be an array (with only one element) and g will return an array.
console.log v for k, v of types when k is 'b' will call console.log(v) for every v when k satisfies the condition whereas your first code snipped will call console.log(g(b)). If there were two elements in types that satisfied the condition, the outputs would be:
[1, 2]
and
1
2
To make g output the first element that satisfies the condition, you could use return with early out or just take the first element of the results array.
g = (s) -> return v for k, v of types when k is s