ALU-n Procedure in Scheme - scheme

I'm a beginner to the Scheme language, so I'm having trouble writing a procedure to take in an n-bit number and put it into an ALU. The ALU is supposed to be constructed using 1-bit ALU's.
Here is the 1-bit ALU:
(define ALU1
(lambda (sel a b carry-in)
(multiplexor4 sel
(cons (andgate a b) 0)
(cons (orgate a b) 0)
(cons (xorgate a b) 0)
(multiplexor2 sub
(full-adder a b carry-in)
(full-adder a (notgate b) carry-in)))))
which, along with the multiplexors and full-adder, works.
Here is my attempt at using a couple of procedures to simulate the n-bit ALU:
(define ALU-helper
(lambda (selection x1 x2 carry-in n)
(if (= n 0)
'()
(ALU1 (selection x1 x2 carry-in)))))
(define ALUn
(lambda (selection x1 x2 n)
(ALU-helper (selection x1 x2 c n))))
And when it's done, it's supposed to take 2 n-bit numbers and add them, or subtract etc, according the to "selection." This would be the input:
(define x1 '(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) )
(define x2 '(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) )
(ALUn 'add x1 x2 32)
And I get errors when running it that seem to be happening because of the "selection" parameter. I'm sure I'm just getting confused by all the parameters, but I'm not sure how to fix the problem and get the ALU to work. I'm running this using the Dr. Racket program, language R5RS.

By putting parentheses around your arguments to ALU1 inside ALU-helper, you are asking selection to be treated as a function, and only passing 1 argument to ALU-helper. Try:
(ALU1 selection x1 x2 carry-in))))
Same thing for the call to ALU-helper in ALUn.

Related

unpacking binary file via octets->string->unpack fails: signed int `#(243 0)` is illegal UTF8

I am parsing a binary file (nifti) with a mix of chars, floats, ints, and shorts (using the PDL::IO::Nifti cpan module as reference).
I am having some luck parsing sequences of octets to a string so they can be passed to cl-pack:unpack. This is convoluted but convenient for porting using the perl module as reference.
This strategy fails on reading #(243 0) as binary
(setf my-problem (make-array 2
:element-type '(unsigned-byte 8)
:initial-contents #(243 0)))
(babel:octets-to-string my-problem)
Illegal :UTF-8 character starting at position 0
and, when trying to read the file as char*
the octet sequence #(243 0 1 0) cannot be decoded.
I'm hoping there is a simple encoding issue I haven't figured out. Trying to go in the reverse direction (packing 243 and getting octets) gives a vector of length 3 for what I expect to be 2.
(babel:string-to-octets (cl-pack:pack "s" 243))
; yields #(195 179 0) expect #(243 0)
Full context
;; can read up to position 40. at which we expect 8 signed ints.
;; 4th int is value "243" but octet cannot be parsed
(setq fid-bin (open "test.nii" :direction :input :element-type 'unsigned-byte))
(file-position fid-bin 40)
(setf seq (make-array (* 2 8) :element-type '(unsigned-byte 8)))
(read-sequence seq fid-bin)
; seq: #(3 0 0 1 44 1 243 0 1 0 1 0 1 0 1 0)
(babel:octets-to-string seq) ; Illegal :UTF-8 character starting at position 6.
(sb-ext:octets-to-string seq) ; Illegal ....
;; first 3 are as expected
(cl-pack:unpack "s3" (babel:octets-to-string (subseq seq 0 6)))
; 3 256 300
(setf my-problem (subseq seq 6 8)) ; #(243 0)
(babel:octets-to-string my-problem) ; Illegal :UTF-8 character starting at position 0.
;; checking the reverse direction
;; 243 gets represented as 3 bytes!?
(babel:string-to-octets (cl-pack:pack "s3" 3 256 300)) ; #(3 0 0 1 44 1)
(babel:string-to-octets (cl-pack:pack "s4" 3 256 300 243)) ; #(3 0 0 1 44 1 195 179 0)
(setq fid-str (open "test.nii" :direction :input))
(setf char-seq (make-array (* 2 8) :initial-element nil :element-type 'char*))
(file-position fid-str 40)
(read-sequence char-seq fid-str)
;; :UTF-8 stream decoding error on #<SB-SYS:FD-STREAM ....
;; the octet sequence #(243 0 1 0) cannot be decoded.
The perl equivalent
open my $f, "test.nii";
seek $f, 46, 0;
read $f,my $b, 2;
print(unpack "s", $b); # 243
The problem is that you are using functions which try to treat some sequence of octets as a representation of an encoding of a sequence of characters (or of some Unicode things: I think there are things other than characters in Unicode). In particular, in your case, the functions you are using are treating a sequence of octets as the UTF-8 encoding of some string. Well, not all sequences of octets are legal UTF-8 so the functions are, correctly, puking on an illegal sequence of octets.
But that's because you're not doing the right thing: what you want to do is to take a sequence of octets and make a string whose char-codes are those octets. You don't want to be doing with any silly encoding-big-characters-in-small-integers rubbish, because you will never see any big characters. You want something like these functions (both somewhat misnamed, since they aren't fussed about the whole octet thing unless you are).
(defun stringify-octets (octets &key
(element-type 'character)
(into (make-string (length octets)
:element-type element-type)))
;; Smash a sequence of octets into a string.
(map-into into #'code-char octets))
(defun octetify-string (string &key
(element-type `(integer 0 (,char-code-limit)))
(into (make-array (length string)
:element-type element-type)))
;; smash a string into an array of 'octets' (not actually octets)
(map-into into #'char-code string))
And now you can check everything works:
> (octetify-string (pack "s" 243))
#(243 0)
> (unpack "s" (stringify-octets (octetify-string (pack "s" 243))))
243
and so on. Given your example sequence:
> (unpack "s8" (stringify-octets #(3 0 0 1 44 1 243 0 1 0 1 0 1 0 1 0)))
3
256
300
243
1
1
1
1
A really much better approach would be to have the packing & unpacking functions simply handle sequences of octets. But I suspect that's a lost cause. An interim approach which is horrible but less horrible than converting sequences of octets to characters would be to read the file as text but with an external-format which does no translation at all. How to do that is implementation-dependent (but something based on latin-1 will be a good start).
It seems that the problem is indeed encoding-related:
CL-USER> (cl-pack:pack "s" 243)
"ó\0"
which is the same as the result of:
(babel:octets-to-string my-problem :encoding :iso-8859-1)

Adding parenthesis changes evaluation of condition

I'm starting to learn Scheme and stumbled on this curious thing:
Given the following procedure:
(define (test x y) (if (= x 0) 0 y ))
When I create a conditional, it evaluates "as expected" when I add parenthesis to it: (test 0 1) gives 0. But when I don't add parenthesis (and I use the same input) it evaluates to the false condition: test 0 1 gives 1.
Why is this?
If you write:
test 0 1
This is the same as:
(begin
test ; evaluate variable test => #<procedure:something...> or similar value
0 ; evaluate literal 0 => 0
1) ; evaluate literal 1 => 1
==> 1 ; because 1 is the last expression in the block it is the result of it.
When you do (test 0 1) you are calling the procedure you'll get by evaluating variable test with the two arguments 0 and 1 which gets evaluated to the numbers they represent. If you do substitution it becomes:
(if (= 0 0) ; if 0 is the same numeric value as 0
0 ; then evaluate 0
1) ; else evaluate 1
==> 0
The same in JavaScript:
const test = (x, y) => x === 0 ? 0 : y;
test;0;1
==> 1 // result in node is 1 since it was the last expression
test(0, 1); // calling the fucntion behind the variable test with the arguments 0 and 1
==> 0
So parentheses matters around stuff as they matter afdter stuff in JavaScript. Basically (one two three) in Scheme is one(two, three) in JS. Just adding parentheses around somtheing is to just add () after something in JS.

How to apply not operator to all matrix elements in Julia?

I need to apply "not" operator to matrix of zeros and ones in Julia.
In Matlab I would do this:
A=not(B);
In Julia I tried doing this:
A = .~ B;
and
A = .! B;
It should turn zeros to ones and ones to zeros but I get error as a result or all matrix elements are some negative numbers that I didn't enter.
Thanks in advance!
The issue with A = .!B is that logical negation, !(::Int64), isn't defined for integers. This makes sense: What should, say, !3 reasonably give?
Since you want to perform a logical operation, is there a deeper reason why you are working with integers to begin with?
You could perhaps work with a BitArray instead which is vastly more efficient and should behave like a regular Array in most operations.
You can easily convert your integer matrix to a BitArray. Afterwards, applying a logical not works as expected.
julia> A = rand(0:1, 5,5)
5×5 Array{Int64,2}:
0 0 0 1 1
0 1 0 0 1
0 1 1 1 0
1 1 0 0 0
1 1 1 0 0
julia> B = BitArray(A)
5×5 BitArray{2}:
0 0 0 1 1
0 1 0 0 1
0 1 1 1 0
1 1 0 0 0
1 1 1 0 0
julia> .!B
5×5 BitArray{2}:
1 1 1 0 0
1 0 1 1 0
1 0 0 0 1
0 0 1 1 1
0 0 0 1 1
The crucial part here is that the element type (eltype) of a BitArray is Bool, for which negation is obviously well defined. In this sense, you could also use B = Bool.(A) to convert all the elements to booleans.
For a general solution to going from A where A is a matrix of numbers to a boolean matrix with true values where there were zeros and false values elsewhere, you can do this:
julia> A = rand(0:3, 5, 5)
5×5 Array{Int64,2}:
1 0 1 0 3
2 0 1 1 0
2 1 1 3 1
1 0 3 0 3
1 3 3 1 2
julia> (!iszero).(A)
5×5 BitArray{2}:
1 0 1 0 1
1 0 1 1 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
To break down what's going on here:
iszero is a predicate that tests if a scalar value is zero
!iszero is a predicate that returns if a scalar value is not zero
(!iszero).(A) broadcasts the !iszero function over the matrix A
This returns a BitArray with the desired pattern of zeros (falses) and ones (trues). Note that in an array context, false prints as 0 and true prints as 1 (they are numerically equal). You can also compare with the number 0 like this:
julia> A .!= 0
5×5 BitArray{2}:
1 0 1 0 1
1 0 1 1 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
You can also roll your own:
not(x) = (x |> Bool |> !) |> Float64
defines a method that will convert x to boolean, apply not, and then convert the result back to numbers. not.(A) will act element-wise on the array A. Here |> redirects the output to the next method and works with broadcasting.
While not conceptually the cleanest, A=1.-B will do what you want. The problem with ~ is that it is performing a bitwise not on integers, which produces negative numbers. Not sure what is wrong wiht ! except it maybe should be !.B

How to export flattened image with GIMP Script-Fu

I've got a script that's supposed to flatten, resize and export an initial image. I'm stuck on the export. I'm using file-png-save. It seems fine with my parameters except for the third parameter, which is supposed to be a drawable.
For the drawable, I'm using the flattened layer I got from gimp-image-flatten. I'm getting a response that my third argument is invalid. Do layers not always work as drawables? Do I need to convert it?
(define (script-fu-panel-export inImg drawable inWidth)
(define filename (car(gimp-image-get-filename inImg)))
(define comHeight (/ inWidth .75))
(define piece (car(cdr(cdr(cdr(cdr(cdr(strbreakup filename "/"))))))))
(define base (car(strbreakup piece ".")))
(define destination (string-append "/home/samjones/Dev/mobinge/lib/images/" base "-" (number->string inWidth) ".png"))
(let* ((duplicateImg (car(gimp-image-duplicate inImg))))
(gimp-image-scale duplicateImg inWidth comHeight)
(let* ((flatLayer (gimp-image-flatten duplicateImg)))
(file-png-save 1 duplicateImg flatLayer destination destination 1 0 0 0 0 0 0)
)
(gimp-display-new duplicateImg)
)
)
(script-fu-register
"script-fu-panel-export"
"Export Panel. . ."
"Creates a flattened image export to a selected size.."
"Sam Jones"
"copyright 2017, Sam Jones"
"December 19, 2017"
""
SF-IMAGE "Image" 0
SF-DRAWABLE "Maybe unused" 0
SF-ADJUSTMENT "Width" '(320 20 1200 10 50 0 SF-SLIDER)
)
(script-fu-menu-register "script-fu-panel-export" "<Image>/Filters")
Looking around for people who save from scripts, I found a slightly different route that worked. I replaced these two lines:
(let* ((flatLayer (gimp-image-flatten duplicateImg)))
(file-png-save 1 duplicateImg flatLayer destination destination 1 0 0 0 0 0 0))
With this:
(gimp-image-flatten duplicateImg)
(file-png-save 1 duplicateImg (car(gimp-image-get-active-drawable duplicateImg))_destination destination 1 0 0 0 0 0 0)
So I think gimp-image-flatten probably returns a list with the layer as its first element instead of returning a layer. I now know that gimp-image-get-active returns a list with the element.
It's weird, but it works.
You are not accessing the desired element of the result of gimp-image-flatten. Use car to access it:
(let* ((flatLayer (car (gimp-image-flatten duplicateImg))))
(file-png-save 1 duplicateImg flatLayer destination destination 1 0 0 0 0 0 0)
)

General position find function in q

I need something like Position function for Mathematica (http://reference.wolfram.com/mathematica/ref/Position.html) but in Q. My solution for rectangular matrix is following:
q) colrow:{sz:count x; $[(count first x) = 1; enlist y; (floor y % sz; y mod sz)]}
q) position:{flip colrow[x;(where raze x = y)]}
It works straightforward for rectangular matrices and lists:
q) t:(1 -1 1; / matrix test
-1 3 4;
1 -1 1);
q) pos1:position[t;-1] / try to find all positions of -1
q) pos1
0 1
1 0
2 1
q) t ./: pos1 / here get items
-1 -1 -1
q) l:1 0 3 0 2 3 4 1 0 / list test
q) pos2:position[l;0] / try to find all positions of 0
q) pos2
1
3
8
q) l ./: pos2 / get items
0 0 0
This works but it'd be good to have more general solution for arbitrary lists and not only rectangular matrices. For instance code above won't work correctly for arguments like:
position[(1 2 3; 1 2; 1 2 1 4); 1]
May be someone has generic solution for that ?
How's this look? I think it should work for all two-dimensional lists, ragged or rectangular, and also for vectors. (I haven't worked out a version for arbitrary dimensions yet.)
q)position:{{$[type x;enlist each where x;raze flip each flip(til count x;raze each .z.s each x)]}x=y}
q)t
1 -1 1
-1 3 4
1 -1 1
q)l
1 0 3 0 2 3 4 1 0
q)r
1 2 3
1 2
1 2 1 4
q)pos1:position[t;-1]
q)pos2:position[l;0]
q)pos3:position[r;1]
q)pos1
0 1
1 0
2 1
q)pos2
1
3
8
q)pos3
0 0
1 0
2 0
2 2
q)t ./:pos1
-1 -1 -1
q)l ./:pos2
0 0 0
q)r ./:pos3
1 1 1 1
q)
EDIT:
Here's a version that works for all dimensions except 1 (and 0 of course):
q)position2:{{$[type x;where x;raze each raze flip each flip(til count x;.z.s each x)]}x=y}
q)r2:(r;r)
q)0N!r2;
((1 2 3;1 2;1 2 1 4);(1 2 3;1 2;1 2 1 4))
q)pos4:position2[r2;1]
q)0N!pos4;
(0 0 0;0 1 0;0 2 0;0 2 2;1 0 0;1 1 0;1 2 0;1 2 2)
q)r2 ./:pos4
1 1 1 1 1 1 1 1
q)r ./:position2[r;1]
1 1 1 1
q)t ./:position2[t;-1]
-1 -1 -1
q)
On vectors, though, it returns an address vector, not an address matrix, so it has to be used with #, not .:
q)0N!position2[l;0];
1 3 8
q)l ./:position2[l;0]
'type
q)l position2[l;0]
0 0 0
q)
If you really need it to work the same way on vectors as on higher-dimensional structures, the simplest solution is probably just to special-case them directly:
q)position3:{$[type x;enlist each where#;{$[type x;where x;raze each raze flip each flip(til count x;.z.s each x)]}]x=y}
q)position3[l;0]
1
3
8
q)l ./:position3[l;0]
0 0 0
q)r2 ./:position3[r2;1]
1 1 1 1 1 1 1 1
q)r ./:position3[r;1]
1 1 1 1
q)t ./:position3[t;-1]
-1 -1 -1
q)
Below should also work.
Not the exact solution but workable.
pos:{$[type x;where x=y;where each x=y]}
val:{raze ($[0h=type x;x#';x#])pos[x;y]}
q)t:(1 -1 1;-1 3 4;1 -1 1)
q)pos[t;-1]
1
0
1
q)val[t;-1]
-1
-1
-1
q)l:1 0 3 0 2 3 4 1 0
q)pos[l;0]
1 3 8
q)val[l;0]
0 0 0
q)r:(1 2 3; 1 2; 1 2 1 4)
q)pos[r;1]
,0
,0
0 2
q)val[r;1]
1 1 1 1

Resources