(scheme) How to add elements in a matrix? - matrix

This function is supposed to find the sum of each row and put it in a list. I thought something like this would work but it doesn't. It gives me a weird output.
Like, if I have a matrix that has two rows and two columns of 1's, it returns this:
(2 . 1)
Instead of this:
(2 2)
Help?
(define (sum mat)
(let loop ([r 0]
[c 0])
(if (> r (matrix-rows mat)) '()
(if (>= c (sub1 (matrix-cols mat))) (add1 r)
(cons (+ (matrix-ref mat r c) (matrix-ref mat r (add1 c))) (loop r (add1 c)))))))

Instead of calling (add1 r) you should call (loop (+ r 1) 0). Note: this suggestion is correct; however, there are likely other errors in your code, specifically your computation with the matrix-ref calls doesn't look like it will add up a row. You can see that by testing with a matrix of more than two rows.
Here is a fix:
(define (sum mat)
(let loop ((r 0) (c 0) (s 0) (a '()) ;; row, col, sum, ans
(cond ((>= r (matrix-rows mat)) (reverse a))
((>= c (matrix-cols mat)) (loop (+ r 1) 0 0 (cons s a)))
(else (loop r (+ c 1) (+ s (matrix-ref mat r c)) a)))))

Related

How to make a list with generators in Scheme

I'm having problems with this problem because i don't know how to make a list with recursivity using generators. The idea is to create a function that receives a generator that generates n numbers and returns a list with those numbers.
This is my code
;GENERATOR THAT GENERATES "INFINITE NUMBERS OF FIBONACCI"
(define (fib)
(let ((a 0) (b 1))
(lambda ()
(let ((ret a))
(set! a b)
(set! b (+ ret b))
ret))))
;RETURNS A GENERATOR THAT GENERATES NUMBERS OF FIBONACCI UP TO N
(define (taking n g)
(let ((i 1))
(lambda ()
(if (> i n)
#f
(begin
(set! i (+ i 1))
(g))))))
Your definitions are fine! You just need to call them correctly to see it.
> (define t (taking 10 (fib)))
> (t)
0
> (t)
1
> (t)
1
> (t)
2
> (t)
3
> (t)
5
>
UPDATE
(define (generator->list n g)
(if (= n 0)
'()
(cons (g) (generator->list (- n 1) g))))
(generator->list 10 (fib))
So something like this:
(define (to-list gen)
(let loop ((l '()))
(let ((r (gen)))
(if r
(loop (cons r l))
(reverse! l)
))))
Untested. What this does is build up a list in reverse consing the truthy items. When it gets a falsy item, it stops and returns the reverse of the accumulation list.

Extended Euclidian Algorithm in Scheme

I'm trying to write a code for extended Euclidian Algorithm in Scheme for an RSA implementation.
The thing about my problem is I can't write a recursive algorithm where the output of the inner step must be the input of the consecutive outer step. I want it to give the result of the most-outer step but as it can be seen, it gives the result of the most inner one. I wrote a program for this (it is a bit messy but I couldn't find time to edit.):
(define ax+by=1
(lambda (a b)
(define q (quotient a b))
(define r (remainder a b))
(define make-list (lambda (x y)
(list x y)))
(define solution-helper-x-prime (lambda (a b q r)
(if (= r 1) (- 0 q) (solution-helper-x-prime b r (quotient b r) (remainder b r)))
))
(define solution-helper-y-prime (lambda (a b q r)
(if (= r 1) (- r (* q (- 0 q) )) (solution-helper-y-prime b r (quotient b r) (remainder b r))
))
(define solution-first-step (lambda (a b q r)
(if (= r 1) (make-list r (- 0 q))
(make-list (solution-helper-x-prime b r (quotient b r) (remainder b r)) (solution-helper-y-prime b r (quotient b r) (remainder b r))))
))
(display (solution-first-step a b q r))
))
All kinds of help and advice would be greatly appreciated. (P.S. I added a scrrenshot of the instructions that was given to us but I can't see the image. If there is a problem, please let me know.)
This is a Diophantine equation and is a bit tricky to solve. I came up with an iterative solution adapted from this explanation, but had to split the problem in parts - first, obtain the list of quotients by applying the extended Euclidean algorithm:
(define (quotients a b)
(let loop ([a a] [b b] [lst '()])
(if (<= b 1)
lst
(loop b (remainder a b) (cons (quotient a b) lst)))))
Second, go back and solve the equation:
(define (solve x y lst)
(if (null? lst)
(list x y)
(solve y (+ x (* (car lst) y)) (cdr lst))))
Finally, put it all together and determine the correct signs of the solution:
(define (ax+by=1 a b)
(let* ([ans (solve 0 1 (quotients a b))]
[x (car ans)]
[y (cadr ans)])
(cond ((and (= a 0) (= b 1))
(list 0 1))
((and (= a 1) (= b 0))
(list 1 0))
((= (+ (* a (- x)) (* b y)) 1)
(list (- x) y))
((= (+ (* a x) (* b (- y))) 1)
(list x (- y)))
(else (error "Equation has no solution")))))
For example:
(ax+by=1 1027 712)
=> '(-165 238)
(ax+by=1 91 72)
=> '(19 -24)
(ax+by=1 13 13)
=> Equation has no solution

Matrix multiplication in scheme, List of lists

I started to study Scheme and I do not understand some of it. I'm using DrRacket.
I wrote the following code:
(define mult_mat
(λ (A B)
(Trans_Mat (map (λ (x) (mul_Mat_vec A x))
(Trans_Mat B)))))
That uses this functions:
(define Trans_Mat
(λ (A)
(apply map (cons list A))))
(define mul_Mat_vec
(λ (A v)
(map (λ (x) (apply + (map * x v)))
A)))
In mult_mat, I multiply the matrix A in each vector of the transpose matrix B.
It works fine.
I found a code on the web that makes the multiplication in a way that I don't understand:
(define (matrix-multiply matrix1 matrix2)
(map
(λ (row)
(apply map
(λ column
(apply + (map * row column)))
matrix2))
matrix1))
In this code, row is a list of the lists of matrix A, but I don't understand how the column updates.
This part of the code: (apply + (map * row column)) is the dot product of vector row and vector column
For example: A is a matrix 2X3 and B is a matrix 3X2 and if instead of (apply + (map * row column)) I write 1, then I'll get a matrix 2X2 with entries valued 1
I don't understand how it works.
Thanks.
Ah, the old ( apply map foo _a_list_ ) trick. Very clever.
In fact (apply map (cons list A)) is the same as (apply map list A). That's just how apply is defined to work.
Trying out some concrete examples usually helps to "get it":
(apply map list '((1 2 3) (10 20 30)) )
=
(apply map (cons list '((1 2 3) (10 20 30))))
=
(apply map (list list '(1 2 3) '(10 20 30) ))
=
( map list '(1 2 3) '(10 20 30) )
=
'((1 10) (2 20) (3 30))
so that the elements of the last argument, '((1 2 3) (10 20 30)), are spliced in into the wholeapply map ... form.
Matrix transposition (list of lists, really).
So you have
(define (mult_mat A B)
(Trans_Mat (map (λ (B_column) (mul_Mat_vec A B_column))
(Trans_Mat B))))
(define (Trans_Mat A)
(apply map list A))
(define (mul_Mat_vec A v)
(map (λ (A_row) (apply + (map * A_row v)))
A))
(define (matrix-multiply A B)
(map
(λ (A_row)
(apply map
(λ B_column
(apply + (map * A_row B_column)))
B))
A))
Notice it's (λ B_column ..., without parentheses. In ((λ args ...) x y z), when the lambda is entered, args gets all the arguments packaged in a list:
((λ args ...) x y z)
=
(let ([args (list x y z)])
...)
Also notice
(apply map
(λ B_column
(apply + (map * A_row B_column)))
B)
follows the same "tricky" pattern. It's in fact the same as
(apply map (cons
(λ B_column
(apply + (map * A_row B_column)))
B ) )
=
( map
(λ B_column
(apply + (map * A_row B_column)))
B_row1
B_row2
....
B_rowN )
=
(cons (let ([B_column_1 (map car B)])
(apply + (map * A_row B_column_1)))
(map (λ B_column
(apply + (map * A_row B_column)))
(cdr B_row1)
(cdr B_row2)
....
(cdr B_rowN)) )
=
(cons
(apply (λ B_column (apply + (map * A_row B_column)))
(map car B))
(apply map
(λ B_column
(apply + (map * A_row B_column)))
(map cdr B)))
by the definition of map.
Thus, by applying the map, the matrix is "opened up" into the list of its elements the rows, and then when the multi-argument map gets to work on these rows as its arguments, the lambda function gets applied to each row's subsequent numbers, in unison, correspondingly; thus achieving the same effect as the explicit transposition would. But now the added bonus is, we don't need to transpose the result back into the proper form, as we had to with the first version.
This is very clever, and nice.
So, armed with all this understanding, let's try re-reading the original code and see if we can see into it as it is as well.
(define (matrix-multiply matrix1 matrix2)
(map
(λ (row)
(apply map
(λ column ;; <<------ no parens!
(apply + (map * row column)))
matrix2))
matrix1))
This reads: for each row in matrix1, multi-arg map a lambda over matrix2. matrix2 is itself also a list of rows; when we multi-arg-map over the rows, the lambda gets applied to each column in the rows in turn.
So, for each row in matrix1, for each column in matrix2, multiply that row and that column element-wise and sum the results; thus transforming each row into the list of these sums. This obviously works out only if the length of the row and the lengths of each of the columns are the same: if the "width" of the first matrix and the "height" of the second matrix are the same.
If you prefer to use while loops (which may be easier for a beginner), I recommend splitting the problem into 7 main helper functions (along with some other simple functions):
This is not the most efficient method (by far), but it is easy to understand
getRow mat i: Gets row i of matrix mat (list of lists)
(define (getRow mat i)
(nthElement mat i))
(define (nthElement lisT n)
(if (= n 0)
(car lisT)
(nthElement (cdr lisT) (- n 1))))
getCol mat i: Gets column i of matrix mat (list of lists)
(define (getCol mat i)
(define col (list))
(define row 0)
(while (< row (length mat))
(set! col (append col (list (valueAtIJ mat row i))))
(set! row (+ row 1)))
col)
(define (valueAtIJ mat i j)
(nthElement (nthElement mat i) j))
listMult list1 list2: Performs element-wise multiplication on two lists
(define (listMult list1 list2)
(if (not (null? list1))
(cons (* (car list1) (car list2)) (listMult (cdr list1) (cdr list2)))
null))
sum aList: Calculates the sum of all the elements in a list
(define (sum aList)
(if (null? aList)
0
(+ (car aList) (sum (cdr aList)))))
length aList: Finds the length of a list
(define (length lisT)
(if (null? lisT)
0
(+ 1 (length (cdr lisT)))))
newMatrix m n val: Create an m by n matrix filled with val
(define (newMatrix m n val)
(define i 0)
(define row (list val))
(define mat (list))
(if (= n 0)
(list)
(begin
(while (< i (- n 1))
(set! row (append row (list val)))
(set! i (+ i 1)))
(set! i 0)
(while (< i m)
(set! mat (append mat (list row)))
(set! i (+ i 1)))
mat)))
setValueAtIJ mat i j val: Set the value val at position i,j in mat (0-based)
(define (setValueAtIJ mat i j val)
(set! mat (setNthElementFinal mat i (setNthElementFinal (nthElement mat i) j val)))
mat)
These can all be combined to create the matrix multiplication function
(define (matrixMult mat1 mat2)
(define mat1Dim (list (length mat1) (length (nthElement mat1 0))))
(define mat2Dim (list (length mat2) (length (nthElement mat2 0))))
(define i 0)
(define j 0)
(define newMat (newMatrix (car mat1Dim) (car (cdr mat2Dim)) 0))
(if (not (= (car (cdr mat1Dim)) (car mat2Dim)))
null
(begin
(while (< i (length newMat))
(while (< j (length (nthElement newMat 0)))
(set! newMat (setValueAtIJ newMat i j (sum (listMult (getRow mat1 i) (getCol mat2 j)))))
(set! j (+ j 1)))
(set! j 0)
(set! i (+ i 1)))
newMat)))
This solution might not the best way to write it, but it's easy to understand:
(define (matrixMultiply matrix1 matrix2)
(define matrix2Transpose (matrixTranspose matrix2) ) ; Calculate matrix2 transpose to prevent recalculation in future
(map
(lambda (row) ; Step1. Iterate through matrix1 rows
(map
(lambda (column) ; Step3. Iterate through matrix2 columns
(apply + (map * row column)) ; Step4. Multiply rows and columns by peer to peer and add them
; Example:
; If row be (1 2) and column be (5 7) then:
; Map part does: ((1 * 5) (2 * 7)) -> (5 14)
; Apply part does: 5 + 14 -> 19
)
matrix2Transpose ; Step2. Use matrix2 transpose to get columns for every iteration
)
)
matrix1
)
)
(define (matrixTranspose matrix)
(apply map (lambda _ _) matrix)
)
(display
(matrixMultiply '((1 2) (3 4)) '((5 6) (7 8)) )
)
Output: ((19 22) (43 50))

Scheme quadratic function/square root check

Im want to make a function where rootcheck has a list L as input, L always is 3 atoms (a b c) where a is coefficient of x^2, b coef of x and c is the constant. it checks if the equation is quadratic, using discriminant (b^2 - 4ac) and should output this (num 'L) where num is the number of roots and L is a list that contains the roots themselves (using quadratic formula), L is empty in case of no roots. here is my code:
(define roots-2
(lambda (L)
(let ((d (- (* (cdr L) (cdr L)) (4 (car L) (caddr L))))))
(cond ((< d 0) (cons(0 null)))
((= d 0) (cons(1 null)))
(else((> d 0) (cons(2 null)))))
))
its giving me no expression in body error.
also I tried to code the quadratic function and even tried some that are online, one compiled fint but gave me an error when I inserted input this is the code for the quadratic function, NOT MINE!
(define quadratic-solutions
(lambda (a b c) (list (root1 a b c) (root2 a b c))))
(define root1
(lambda (a b c) (/ (+ (- b) (sqrt (discriminant a b c)))
(* 2 a))))
(define root2
(lambda (a b c) (/ (- (- b) (sqrt (discriminant a b c)))
(*2 a))))
(define discriminant
(lambda (a b c) (- (square b) (* 4 (* a c)))))
There are several mistakes in the code:
Some parentheses are incorrectly placed, use a good IDE to detect such problems. This is causing the error reported, the let doesn't have a body
You forgot to multiply in the 4ac part
You're incorrectly accessing the second element in the list
The else part must not have a condition
The output list is not correctly constructed
This should fix the errors, now replace null with the actual call to the function that calculates the roots for the second and third cases (the (< d 0) case is fine as it is):
(define roots-2
(lambda (L)
(let ((d (- (* (cadr L) (cadr L)) (* 4 (car L) (caddr L)))))
(cond ((< d 0) (list 0 null))
((= d 0) (list 1 null))
(else (list 2 null))))))
for the quadractic function part, I found a code online and tweaked it to provide both roots of a quadratic equation. returns a list of both roots
(define (solve-quadratic-equation a b c)
(define disc (sqrt (- (* b b)
(* 4.0 a c))))
(list (/ (+ (- b) disc) (* 2.0 a))
(/ (- (- b) disc) (* 2.0 a))
))

I have a procedure with no arguments that creates a matrix, but returns nothing, how can i access the matrix?

I have a procedure with no arguments that creates a matrix, but returns nothing, how can i access the matrix?
This is my code:
(define matrix
(lambda (rows columns)
(do ((m (make-vector rows))
(i 0 (+ i 1)))
((= i rows) m)
(vector-set! m i (make-vector columns)))))
(define Mod-matrix!
(lambda (m i j)
(vector-ref (vector-ref m i) j)))
(define (board)
(mk-w (matrix 8 8) 0 0))
(define (mk-b b l c)
(cond ((and (< l 8) (< c 8)) (begin
(Mod-matrix! b l c p)
(mk-b b l (+ c 2))))
((and (>= c 8) (< l 8))(mk-b b (+ l 2) 0))
(else (mk-w b 0 1))))
(define (mk-b b l c)
(cond ((and (< l 8) (< c 8)) (begin
(Mod-matrix! b l c b)
(mk-w ti l (+ c 2))))
((and (>= c 8) (< l 8)) (mk-white b (+ l 2) 0))))
Your mk-w function is not returning the matrix. Try the following:
(define (mk-w b l c)
(cond
((and (< l 8) (< c 8))
(begin (Mod-matrix! b l c)
(mk-w b l (+ c 2))
b))
((and (>= c 8) (< l 8))
(begin
(mk-w b (+ l 2) 0)
b))))
Note that in each case the last expression in the begin block is the matrix itself, this is because the return value of a begin block is the value of the last expression. In your post, those last expressions returned an undefined value.
If you want to access the matrix, have the function return the matrix rather than nil or whatever. It's generally considered bad form, but you could set! the matrix to some variable inside the function.
If you can't change the function, you can't access the matrix.

Resources