f2py convert subroutine with argument has intent of inout - fortran

Through f2py -c sorting.f90 -m sortF, I get sortF.cpython-37m-x86_64-linux-gnu.so which is great.
sorting.f90
module sorting
use iso_fortran_env, only: i4 => int32, i8 => int64
implicit none
contains
subroutine bubbleSort(array)
implicit none
integer, dimension(:):: array
integer :: i, j, tem
i = size(array)
do while (i > 1)
do j = 1, i - 1
if (array(j) > array(j + 1)) then
tem = array(j)
array(j) = array(j + 1)
array(j + 1) = tem
end if
end do
i = i - 1
end do
end subroutine bubbleSort
end module sorting
In this subroutine, the input array is changed, therefore, I expect after I execute sorting.bubblesort(x), I hope x becomes [1, 2, 3, 5]
In [1]: from sortF import sorting
In [2]: x = [1, 2, 5, 3]
In [3]: print(sorting.bubblesort(x))
None
In [4]: x
Out[4]: [1, 2, 5, 3]

Related

Unique lists in nested list in numba

I would like to find the number of unique lists within a nested list in a nopython numba function, e.g:
from collections import Counter
def number_of_unique_lists_v1(a):
uniques = Counter(tuple(item) for item in a)
number = len(uniques.keys())
return number
print(number_of_unique_lists_v1([[1,2,3],[1,2],[3,4],[1,2,3])
>>> 3
or
def number_of_unique_lists_v2(a):
uniques = [list(x) for x in set(tuple(x) for x in a)]
number = len(uniques)
return number
print(number_of_unique_lists_v2([[1,2,3],[1,2],[3,4],[1,2,3])
>>> 3
Unfortunately, both ideas don't work with #nb.njit. How can I make it work?
Edit:
Using the approach of mpw2 I found that in principle the following code works:
from numba.typed import List
#nb.njit
def number_of_unique_lists_v3():
a = [[1, 2, 3], [1, 2], [3, 4], [1, 2, 3]]
s = List()
for x in a:
if not x in s:
s.append(x)
number = len(s)
return number
print(number_of_unique_lists())
>>> 3
BUT this does not work for me since the list a is created slightly differently in my function, similar as shown in a minimal example below.
from numba.typed import List
#nb.njit
def number_of_unique_lists():
a = [[0] for _ in range(4)]
a[0] = [1, 2, 3]
a[1] = [1, 2]
a[2] = [3, 4]
a[3] = [1, 2, 3]
s = List()
for x in a:
if not x in s:
s.append(x)
number = len(s)
return number
Now I get an error which I don't understand...
Here is one working solution using numba.typed.List() objects
import numba as nb
from numba.typed import List
#nb.njit
def number_of_unique_lists(a):
s = List()
for x in a:
if not x in s:
s.append(x)
number = len(s)
return number
a = [[1,2,3],[1,2],[3,4],[1,2,3]]
typed_a = List()
for x in a:
s = List()
for y in x:
s.append(y)
typed_a.append(s)
print(number_of_unique_lists(typed_a))
>>> 3

Gfortran and Undefined reference to '__[module_name]_MOD_[function_name]'

i am writing a program in Fortran which uses .mod files, .dll libraries and .h headers.
I must be forgetting something when i call the compiler, because i get the error:
undefined reference to '__[module_name]_MOD_[function_name]', where [module_name] is the name of one of the modules used by the main program and [function_name] is the name of a function contained in the module.
The only source file is called MAIN.f90:
! WORHP workspace access macros
#include "worhp/macros.h"
MODULE WORHP_INTERFACE
USE std
USE problem_definition_tools
CONTAINS
SUBROUTINE OBJ(N,X,F) BIND(C)
INTEGER(WORHP_INT) :: N
REAL(WORHP_DOUBLE) :: X(N),F
INTENT(in) :: N, X
INTENT(out) :: F
F = X(1)
END SUBROUTINE OBJ
SUBROUTINE CON(N,M,X,G) BIND(C)
INTEGER(WORHP_INT) :: N,M
REAL(WORHP_DOUBLE) :: X(N),G(M)
INTENT(in) :: N, M, X
INTENT(out) :: G
TYPE (orbit) :: O
O = final_orbit(X)
G = [O%Lp, O%La]
END SUBROUTINE CON
SUBROUTINE DOBJ(N,dfnnz,DFROW,X,DF) BIND(C)
INTEGER(WORHP_INT) :: N,dfnnz,DFROW(DFnnz)
REAL(WORHP_DOUBLE) :: X(N),DF(DFnnz)
INTENT(in) :: N, DFnnz, DFrow, X
INTENT(out) :: DF
DF = [1, 0, 0, 0, 0, 0]
END SUBROUTINE DOBJ
SUBROUTINE DCON(N,M,DGnnz,DGROW,DGCOL,X,DG) BIND(C)
INTEGER(WORHP_INT) :: N,M,DGnnz,DGROW(DGnnz),DGCOL(DGnnz)
REAL(WORHP_DOUBLE) :: X(N),DG(DGnnz)
INTENT(in) :: N,M,DGnnz,DGrow,DGcol,X
INTENT(out) :: DG
! Dummy
END SUBROUTINE DCON
SUBROUTINE HESS(N,M,HMnnz,HMrow,HMcol,X,Mu,HM) BIND(C)
INTEGER(WORHP_INT) :: N, M, HMnnz, HMrow(HMnnz), HMcol(HMnnz)
REAL(WORHP_DOUBLE) :: X(N),Mu(M),HM(HMnnz)
INTENT(in) :: N, M, HMnnz, HMrow, HMcol, X, Mu
INTENT(out) :: HM
! Dummy
END SUBROUTINE HESS
END MODULE WORHP_INTERFACE
program MAIN
USE WORHP_INTERFACE
USE Worhp_User
INTEGER (WORHP_INT) :: Mode, N, M, DFnnz, DGnnz, HMnnz
PARAMETER (N=6, M=2, DFnnz=1, DGnnz=12, HMnnz=12)
INTEGER (WORHP_INT) :: DFrow(DFnnz), DGrow(DGnnz), DGcol(DGnnz)
INTEGER (WORHP_INT) :: HMrow(HMnnz), HMcol(HMnnz)
INTEGER (WORHP_INT) :: Iparam(10)
REAL (WORHP_DOUBLE) :: X(N), L(N+M), U(N+M), Dparam(10)
REAL (WORHP_DOUBLE) :: Infty = 1d20
! Check Version of library and header files
CHECK_WORHP_VERSION
L = [9000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 200000.0, 35786000.0]
U = [10000.0, 5.0, 180.0, 0.15, 180.0, 0.15, 200000.0, 35786000.0]
X = [9520.00, 1.47490136, 71.50755639, 0.09948622, 97.00248532, 0.09296147]
DFrow = [6]
DGrow = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
DGcol = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6]
HMrow = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
HMcol = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6]
! Get default parameter values
Mode = 0
CALL WorhpSimple(Mode, N, M, X, L, U, Dparam, Iparam, &
DFnnz, DFrow, DGnnz, DGrow, DGcol, HMnnz, HMrow, HMcol, &
OBJ, CON, DOBJ, DCON, HESS)
! User-defined derivatives are available
Iparam(1) = 1
Iparam(2) = 0
Iparam(3) = 0
! Run the solver
Mode = 1
CALL WorhpSimple(Mode, N, M, X, L, U, Dparam, Iparam, &
DFnnz, DFrow, DGnnz, DGrow, DGcol, HMnnz, HMrow, HMcol, &
OBJ, CON, DOBJ, DCON, HESS)
end
The function final_orbit called by the subroutine CON is contained in the module "problem_definition_tools".
For the compilation i use the following windows batch file called "compile.bat"
x86_64-w64-mingw32-gfortran src\MAIN.f90 -cpp -Iinclude -Ifinclude\worhp -Ifinclude\aerospace -Jobj -Lbin -lworhp -o bin\megaceppa.exe
which gives the error
undefined reference to '__problem_definition_tools_MOD_final_orbit'
I run the command from the directory 'Test' which has the following structure
\bin\
libworhp.dll
\finclude
\worhp\
std.mod
\aerospace\
problem_definition_tools.mod
\include
\worhp\
macros.h
\lib
libworhp.lib
\obj
worhp_interface.mod
\src
MAIN.f90
compile.bat
I would like to specify that the module "problem_definition_tools" is written by me, and i know for sure that it works because i already used it in another program. Moreover, i re-compiled it with x86_64-w64-mingw32-gfortran in order to avoid any compatibility issues with this program.
I am sure that there is something wrong in the way i call the compiler, but i can't figure it out because of my limited experience with Fortran. I also triend to search for similar questions on this website, but i couldn't find anything closely related to my problem.
I think it might be related to some declaration of final_orbit function.
It seems close to the following problem:
Linking fortran module: "undefined reference"
And I think the problem should be located in the code of module problem_definition_tools

How to use fortran's spread function to copy an array block-wise instead of column-wise?

For example, this code:
program sandbox
implicit none
real, dimension(2, 2) :: p
p = reshape((/ 1, 3, 2, 4 /), shape(p))
print *, spread(P, 2, 2)
end program sandbox
returns this array:
1 1 2 2
3 3 4 4
but I'm trying to get it to return this"
1 2 1 2
3 4 3 4
Is this possible using spread? In actuality, it needs to be generalized, because I may be producing matrices like
1 2 1 2 1 2 1 2
3 4 3 4 3 4 3 4
depending on other variables that I won't know at compile time.
Try this (all is in the Fortran 90 standard except the [ ] notation in place of (/ /))
program sandbox
implicit none
real, dimension(2, 2) :: p
real, dimension(2, 4) :: q
integer i
print *, "p"
p = reshape([1, 3, 2, 4], shape(p))
do i=1, 2
print *, p(i, :)
end do
print *, "spread (orig)"
q = reshape(spread(p, 2, 2), [2, 4])
do i=1, 2
print *, q(i, :)
end do
print *, "spread"
q = reshape(spread(transpose(p), 2, 2), [2, 4], order=[2, 1])
do i=1, 2
print *, q(i, :)
end do
print *, "[p, p]"
q = reshape([p, p], [2, 4])
do i=1, 2
print *, q(i, :)
end do
end program sandbox

New to Prolog, Lists and Pairs

I'm new to Prolog and I'm having a bit of a hard time understanding how some of the mechanics actually works. Right now I'm trying to work on a particular problem.
I need to find all possible pairs from a single list and so I'm trying to define rules select_pairs(X,Y,_,Z).
Below is what I expect to see when I run the given queries.
The query: select_pairs(X,Y,[1,2,3],Z). returns the following:
X = 1, Y = 2, Zs = [3] ;
X = 1, Y = 3, Zs = [2] ;
X = 2, Y = 1, Zs = [3] ;
X = 2, Y = 3, Zs = [1] ;
X = 3, Y = 1, Zs = [2] ;
X = 3, Y = 2, Zs = [3]
AND the query select_pairs(1,2,Xs,[3]). returns the following:
Xs = [1, 2, 3] ;
Xs = [2, 1, 3] ;
Xs = [1, 3, 2] ;
Xs = [2, 3, 1] ;
Xs = [3, 1, 2] ;
Xs = [3, 2, 1] ;
As of right now, I can only get the first result from the first query to show up and nothing more. What's the best way from me to approach this? Thank you!
Your Prolog should come with select/3, a builtin that's doing exactly what's suggested by its name:
?- select(X,[1,2,3],R).
X = 1,
R = [2, 3] ;
X = 2,
R = [1, 3] ;
X = 3,
R = [1, 2] ;
false.
it also works 'backwards'
?- select(1,R,[2,3]).
R = [1, 2, 3] ;
R = [2, 1, 3] ;
R = [2, 3, 1] ;
false.
Then, to get a working select_pairs/4, you could just combine 2 select/3.

Does Haskell have List Slices (i.e. Python)?

Does Haskell have similar syntactic sugar to Python List Slices?
For instance in Python:
x = ['a','b','c','d']
x[1:3]
gives the characters from index 1 to index 2 included (or to index 3 excluded):
['b','c']
I know Haskell has the (!!) function for specific indices, but is there an equivalent "slicing" or list range function?
There's no built-in function to slice a list, but you can easily write one yourself using drop and take:
slice :: Int -> Int -> [a] -> [a]
slice from to xs = take (to - from + 1) (drop from xs)
It should be pointed out that since Haskell lists are singly linked lists (while python lists are arrays), creating sublists like that will be O(to), not O(to - from) like in python (assuming of course that the whole list actually gets evaluated - otherwise Haskell's laziness takes effect).
If you are trying to match Python "lists" (which isn't a list, as others note) then you might want to use the Haskell vector package which does have a built in slice. Also, Vector can be evaluated in parallel, which I think is really cool.
No syntactic sugar. In cases where it's needed, you can just take and drop.
take 2 $ drop 1 $ "abcd" -- gives "bc"
I don't think one is included, but you could write one fairly simply:
slice start end = take (end - start + 1) . drop start
Of course, with the precondition that start and end are in-bounds, and end >= start.
Python slices also support step:
>>> range(10)[::2]
[0, 2, 4, 6, 8]
>>> range(10)[2:8:2]
[2, 4, 6]
So inspired by Dan Burton's dropping every Nth element I implemented a slice with step. It works on infinite lists!
takeStep :: Int -> [a] -> [a]
takeStep _ [] = []
takeStep n (x:xs) = x : takeStep n (drop (n-1) xs)
slice :: Int -> Int -> Int -> [a] -> [a]
slice start stop step = takeStep step . take (stop - start) . drop start
However, Python also supports negative start and stop (it counts from end of list) and negative step (it reverses the list, stop becomes start and vice versa, and steps thru the list).
from pprint import pprint # enter all of this into Python interpreter
pprint([range(10)[ 2: 6], # [2, 3, 4, 5]
range(10)[ 6: 2:-1], # [6, 5, 4, 3]
range(10)[ 6: 2:-2], # [6, 4]
range(10)[-8: 6], # [2, 3, 4, 5]
range(10)[ 2:-4], # [2, 3, 4, 5]
range(10)[-8:-4], # [2, 3, 4, 5]
range(10)[ 6:-8:-1], # [6, 5, 4, 3]
range(10)[-4: 2:-1], # [6, 5, 4, 3]
range(10)[-4:-8:-1]]) # [6, 5, 4, 3]]
How do I implement that in Haskell? I need to reverse the list if the step is negative, start counting start and stop from the end of the list if these are negative, and keep in mind that the resulting list should contain elements with indexes start <= k < stop (with positive step) or start >= k > stop (with negative step).
takeStep :: Int -> [a] -> [a]
takeStep _ [] = []
takeStep n (x:xs)
| n >= 0 = x : takeStep n (drop (n-1) xs)
| otherwise = takeStep (-n) (reverse xs)
slice :: Int -> Int -> Int -> [a] -> [a]
slice a e d xs = z . y . x $ xs -- a:start, e:stop, d:step
where a' = if a >= 0 then a else (length xs + a)
e' = if e >= 0 then e else (length xs + e)
x = if d >= 0 then drop a' else drop e'
y = if d >= 0 then take (e'-a') else take (a'-e'+1)
z = takeStep d
test :: IO () -- slice works exactly in both languages
test = forM_ t (putStrLn . show)
where xs = [0..9]
t = [slice 2 6 1 xs, -- [2, 3, 4, 5]
slice 6 2 (-1) xs, -- [6, 5, 4, 3]
slice 6 2 (-2) xs, -- [6, 4]
slice (-8) 6 1 xs, -- [2, 3, 4, 5]
slice 2 (-4) 1 xs, -- [2, 3, 4, 5]
slice (-8)(-4) 1 xs, -- [2, 3, 4, 5]
slice 6 (-8)(-1) xs, -- [6, 5, 4, 3]
slice (-4) 2 (-1) xs, -- [6, 5, 4, 3]
slice (-4)(-8)(-1) xs] -- [6, 5, 4, 3]
The algorithm still works with infinite lists given positive arguments, but with negative step it returns an empty list (theoretically, it still could return a reversed sublist) and with negative start or stop it enters an infinite loop. So be careful with negative arguments.
I had a similar problem and used a list comprehension:
-- Where lst is an arbitrary list and indc is a list of indices
[lst!!x|x<-[1..]] -- all of lst
[lst!!x|x<-[1,3..]] -- odd-indexed elements of lst
[lst!!x|x<-indc]
Perhaps not as tidy as python's slices, but it does the job. Note that indc can be in any order an need not be contiguous.
As noted, Haskell's use of LINKED lists makes this function O(n) where n is the maximum index accessed as opposed to python's slicing which depends on the number of values accessed.
Disclaimer: I am still new to Haskell and I welcome any corrections.
When I want to emulate a Python range (from m to n) in Haskell, I use a combination of drop & take:
In Python:
print("Hello, World"[2:9]) # prints: "llo, Wo"
In Haskell:
print (drop 2 $ take 9 "Hello, World!") -- prints: "llo, Wo"
-- This is the same:
print (drop 2 (take 9 "Hello, World!")) -- prints: "llo, Wo"
You can, of course, wrap this in a function to make it behave more like Python. For example, if you define the !!! operator to be:
(!!!) array (m, n) = drop m $ take n array
then you will be able to slice it up like:
"Hello, World!" !!! (2, 9) -- evaluates to "llo, Wo"
and use it in another function like this:
print $ "Hello, World!" !!! (2, 9) -- prints: "llo, Wo"
I hope this helps, Jon W.
Another way to do this is with the function splitAt from Data.List -- I find it makes it a little easier to read and understand than using take and drop -- but that's just personal preference:
import Data.List
slice :: Int -> Int -> [a] -> [a]
slice start stop xs = fst $ splitAt (stop - start) (snd $ splitAt start xs)
For example:
Prelude Data.List> slice 0 2 [1, 2, 3, 4, 5, 6]
[1,2]
Prelude Data.List> slice 0 0 [1, 2, 3, 4, 5, 6]
[]
Prelude Data.List> slice 5 2 [1, 2, 3, 4, 5, 6]
[]
Prelude Data.List> slice 1 4 [1, 2, 3, 4, 5, 6]
[2,3,4]
Prelude Data.List> slice 5 7 [1, 2, 3, 4, 5, 6]
[6]
Prelude Data.List> slice 6 10 [1, 2, 3, 4, 5, 6]
[]
This should be equivalent to
let slice' start stop xs = take (stop - start) $ drop start xs
which will certainly be more efficient, but which I find a little more confusing than thinking about the indices where the list is split into front and back halves.
Why not use already existing Data.Vector.slice together with Data.Vector.fromList and Data.Vector.toList (see https://stackoverflow.com/a/8530351/9443841)
import Data.Vector ( fromList, slice, toList )
import Data.Function ( (&) )
vSlice :: Int -> Int -> [a] -> [a]
vSlice start len xs =
xs
& fromList
& slice start len
& toList
I've wrote this code that works for negative numbers as well, like Python's list slicing, except for reversing lists, which I find unrelated to list slicing:
slice :: Int -> Int -> [a] -> [a]
slice 0 x arr
| x < 0 = slice 0 ((length arr)+(x)) arr
| x == (length arr) = arr
| otherwise = slice 0 (x) (init arr)
slice x y arr
| x < 0 = slice ((length arr)+x) y arr
| y < 0 = slice x ((length arr)+y) arr
| otherwise = slice (x-1) (y-1) (tail arr)
main = do
print(slice (-3) (-1) [3, 4, 29, 4, 6]) -- [29,4]
print(slice (2) (-1) [35, 345, 23, 24, 69, 2, 34, 523]) -- [23,24,69,32,34]
print(slice 2 5 [34, 5, 5, 3, 43, 4, 23] ) -- [5,3,43]
Obviously my foldl version loses against the take-drop approach, but maybe someone sees a way to improve it?
slice from to = reverse.snd.foldl build ((from, to + 1), []) where
build res#((_, 0), _) _ = res
build ((0, to), xs) x = ((0, to - 1), x:xs)
build ((from, to), xs) _ = ((from - 1, to - 1), xs)
sublist start length = take length . snd . splitAt start
slice start end = snd .splitAt start . take end