Related
Haskell's HMatrix allows you to conveniently get slices:
m ?? (All, Take 3)
But how can you set slices, especially non-rectangular ones? For instance, in Python's Numpy I'd do:
>>> x = np.arange(12).reshape(3, 4)
>>> x
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> x[[0,0], [1,3]] += x[[2,2], [1,3]] # to ix (0, 1) add (2, 1) and to ix (0, 3) add (2, 3)
>>> x
array([[ 0, 10, 2, 14],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
I'm able to write this helper function myself, but, it's sure ugly, and partial, and required I add zipWith3M_ which should exist in the vector library but doesn't:
setSlice :: (Element t, Num t) => Matrix t -> (Extractor, Extractor) -> Vector t -> Matrix t
setSlice parent (Pos (V.map fromIntegral -> irows), Pos (V.map fromIntegral -> icols)) sub = runST $ do
tparent <- thawMatrix parent
zipWith3M_ (writeMatrix tparent) irows icols sub
freezeMatrix tparent
NOTE: I'm not allowed to use any built-in functions
Given positive ints r and c indicating the number of rows and columns, create a 2D list that represents the "augmented identity matrix" with that dimension: It's the k x k identity matrix (where k = min(r,c)), and augmented rightwards or downwards as needed with zeroes in order to be of size r x c. Stated another way, it's an r x c matrix filled with zeroes that has ones along its main diagonal. I have to write this in both python and Haskell. I wrote the python solution but I'm kinda stuck on Haskell. The Haskell function has to be the following form:
augdentity :: Int -> Int -> [[Int]]
*Homework4> augdentity 3 3
[[1,0,0],[0,1,0],[0,0,1]]
*Homework4> augdentity 3 5
[[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0]]
*Homework4> augdentity 5 3
[[1,0,0],[0,1,0],[0,0,1],[0,0,0],[0,0,0]]
*Homework4> augdentity 2 2
[[1,0],[0,1]]
def augdentity(r,c):
answer = []
for row in range(0, r):
newRow = [0] * c
for col in range(0, c):
if row == col:
newRow[col] = 1
answer.append(newRow)
return answer
So I got this for my haskell function. Put zeros in list when x != y but I don't know how to put 1 when x == y
augdentity :: Int -> Int -> [[Int]]
augdentity x y = [[0 | y <- [1 .. y], x /= y] | x <- [1 .. x]]
How about using if ... then ... else:
augdentity :: Int -> Int -> [[Int]]
augdentity r c = [[ if i == j then 1 else 0 | j <- [1..c] ] | i <- [1..r] ]
main = mapM_ (print . uncurry augdentity) [(3,3),(3,5),(5,3),(2,2)]
-- [[1,0,0],[0,1,0],[0,0,1]]
-- [[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0]]
-- [[1,0,0],[0,1,0],[0,0,1],[0,0,0],[0,0,0]]
-- [[1,0],[0,1]]
Similarly, the python code could be simplified:
def augdentity(rows, cols):
return [[int(i == j) for j in range(cols)] for i in range(rows)]
for dim in [(3,3),(3,5),(5,3),(2,2)]:
print(augdentity(*dim))
# [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
# [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]]
# [[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 0], [0, 0, 0]]
# [[1, 0], [0, 1]]
I'm working on such project, and got question for code compression.
There are many ways for list concatenation a+b, a.extend(b), and so on.
but my question is, there are any way for shallow concatenation of the lists; for example,
a = [1,2,3]
b = [4,5]
c = a+b
c
>> [1,2,3,4,5]
b[0] = 10
c
>> [1,2,3,4,5]
but, my desired result is [1,2,3,10,5], then how to define c for this?
If you create a nested list from a and b you can kinda achieve what you are looking for:
>>> a = [1, 2, 3]
>>> b = [4, 5]
>>> c = [a, b]
>>> b[0] = 10
>>> c
[[1, 2, 3], [10, 5]]
>>> c = [val for sub_list in c for val in sub_list]
>>> c
[1, 2, 3, 10, 5]
a = [1,2,3]
b = [4,5]
b[0] = 10
c = a+b
print(c)
or
import copy
a = [1,2,3]
b = [4,5]
c=[a,b]
bb = copy.copy(c)
c[1][0]=10
print([val for l in c for val in l])
# refer this link for shallow-deep-copy reference
# https://www.programiz.com/python-programming/shallow-deep-copy
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Im trying to create a function that replace a given existing place with a new place
data Place = Place String Coord [Int]
deriving (Ord,Eq,Show,Read)
data Coord = Cord Double Double
deriving (Ord ,Eq ,Show ,Read)
testData :: [Place]
testData = [ Place "London" (Cord 51.5 (-0.1)) [0, 0, 5, 8, 8, 0, 0],
Place"Cardiff" (Cord 51.5 (-3.2)) [12, 8, 15, 0, 0, 0, 2],
Place"Norwich" (Cord 52.6 (1.3) ) [0, 6, 5, 0, 0, 0, 3],
Place "Birmingham" (Cord 52.5 (-1.9)) [0, 2, 10, 7, 8, 2, 2],
Place"Liverpool" (Cord 53.4 (-3.0)) [8, 16, 20, 3, 4, 9, 2],
Place "Hull" (Cord 53.8 (-0.3)) [0, 6, 5, 0, 0, 0, 4],
Place "Newcastle" (Cord 55.0 (-1.6)) [0, 0, 8, 3, 6, 7, 5],
Place "Belfast" (Cord 54.6 (-5.9)) [10, 18, 14, 0, 6, 5, 2],
Place "Glasgow" (Cord 55.9 (-4.3)) [7, 5, 3, 0, 6, 5, 0],
Place"Plymouth" (Cord 50.4 (-4.1)) [4, 9, 0, 0, 0, 6, 5],
Place "Aberdeen" (Cord 57.1 (-2.1)) [0, 0, 6, 5, 8, 2, 0],
Place "Stornoway" (Cord 58.2 (-6.4)) [15, 6, 15, 0, 0, 4, 2],
Place"Lerwick" (Cord 60.2 (-1.1)) [8, 10, 5, 5, 0, 0, 3],
Place"St Helier" (Cord 49.2 (-2.1)) [0, 0, 0, 0, 6, 10, 0] ]
replaceLocate :: String -> Place -> [Place] -> [Place]
replaceLocate _ _ [] = []
replaceLocate str (Place l d rains) ((Place p c rain):xs)
| str == p = Place l d rains : replaceLocate (Place l d rains) str xs
| otherwise = Place p c rain : replaceLocate (Place l d rains) str xs
while using String to search for the Places that I wanted to change.
But it gives me this error :
Smth.hs:96:22: error:
• Couldn't match type ‘Place’ with ‘[Char]’
Expected type: String
Actual type: Place
• In the pattern: Place l d rains
In an equation for ‘replaceLocate’:
replaceLocate str (Place l d rains) ((Place p c rain) : xs)
| str == p
= Place l d rains : replaceLocate (Place l d rains) str xs
| otherwise
= Place p c rain : replaceLocate (Place l d rains) str xs
|
96 | replaceLocate str (Place l d rains) ((Place p c rain):xs) | ^^^^^^^^^^^^^^^
Smth.hs:97:16: error:
• Couldn't match type ‘[Char]’ with ‘Place’
Expected type: Place
Actual type: String
• In the second argument of ‘(==)’, namely ‘p’
In the expression: str == p
In a stmt of a pattern guard for
an equation for ‘replaceLocate’:
str == p
|
97 | | str == p = Place l d rains : replaceLocate (Place l d rains) str xs | ^
Smth.hs:97:82: error:
• Couldn't match type ‘Place’ with ‘[Char]’
Expected type: String
Actual type: Place
• In the second argument of ‘replaceLocate’, namely ‘str’
In the second argument of ‘(:)’, namely
‘replaceLocate (Place l d rains) str xs’
In the expression:
Place l d rains : replaceLocate (Place l d rains) str xs
|
97 | | str == p = Place l d rains : replaceLocate (Place l d rains) str xs | ^^^
Smth.hs:98:86: error:
• Couldn't match type ‘Place’ with ‘[Char]’
Expected type: String
Actual type: Place
• In the second argument of ‘replaceLocate’, namely ‘str’
In the second argument of ‘(:)’, namely
‘replaceLocate (Place l d rains) str xs’
In the expression:
Place p c rain : replaceLocate (Place l d rains) str xs
|
98 | | otherwise = Place p c rain : replaceLocate (Place l d rains) str xs | ^^^
In your recurve call you are swapping the first two parameters. You need to replace this:
replaceLocate (Place l d rains) str xs
With this:
replaceLocate str (Place l d rains) xs
My current code is below. I think all of the functions, except for the last one are correct. What I'm trying to achieve with changeValueMatrix is to give a matrix, a matrix position and a value and then that value will replace the one that is at the current position. I've managed to reach the position and to change the value but I can only return the row on which I changed it and not the whole matrix. I am a Haskell beginner and I've only learned recursion just now but it would be ideal to use it here if possible.
type Matrix a = [[a]]
type MatrixDimension = (Int,Int)
type MatrixPosition = (Int,Int)
matrixDimension :: Matrix a -> MatrixDimension
matrixDimension m = (length m, length (head m))
returnValueList :: Int -> [a] -> a
returnValueList 0 (x:xs) = x
returnValueList i(x:xs) = returnValue (i-1)(xs)
changeValueList :: Int -> a -> [a] -> [a]
changeValueList 0 value (x:xs) = (value:xs)
changeValueList i value (x:xs) = x:(changeValueList (i-1) (value) (xs))
returnValueMatrix :: MatrixPosition-> Matrix a -> a
returnValueMatrix(m,n) matrix = returnValueList n (returnreturnValueList matrix)
changeValueMatrix :: MatrixPosition -> a -> Matrix a -> Matrix a
changeValueMatrix(0,c) value (x:xs) = a:xs
where a = changeValueList c value x
changeValueMatrix(r,c) valor (x:xs) =
where
row = returnValueList r (x:xs)
b = changeValueList c value row
You can build changeValueMatrix from the functions you’ve already defined:
changeValueMatrix :: MatrixPosition -> a -> Matrix a -> Matrix a
changeValueMatrix (r, c) value matrix
= changeValueList r -- (3)
(changeValueList c value -- (2)
(returnValueList r matrix)) -- (1)
matrix
At (1) you look up the row at index r in matrix, at (2) you replace the element at column c in that row with value, and at (3) you replace the row at index r in matrix with the modified row. For example:
-- Given: mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
changeValueMatrix (1, 1) 0 mat
==
changeValueList 1
(changeValueList 1 0
(returnValueList 1 mat))
mat
==
changeValueList 1
(changeValueList 1 0 [4, 5, 6])
mat
==
changeValueList 1 [4, 0, 6] mat
==
[ [1, 2, 3]
, [4, 0, 6]
, [7, 8, 9]
]
If you want a version of this using explicit recursion, which only traverses the rows once, you can inline the definition of changeValueList into changeValueMatrix:
changeValueMatrix (0, c) value (x : xs)
= changeValueList c value x : xs
changeValueMatrix (r, c) value (x : xs)
= x : changeValueMatrix (r - 1, c) value xs
Be aware that your code has a few failure cases, though:
Negative indices will produce infinite loops because you only test for 0 and recur with i - 1 on any other number
Overly large indices will run into the end of the list and crash because you don’t handle the [] case—the pattern matches are non-exhaustive, which the compiler will point out when enabling all warnings with -Wall
Similarly, matrices of zero width or height are representable, but these functions don’t handle the possibility (e.g. matrixDimension calls head on a possibly-empty list); you can avoid this using Data.List.NonEmpty or Data.Array as your backing type, the latter of which is also more efficient