Hi all!

These two F# programs describe what initiates the special handling. It might be different in J, but the functionality should be the same, at least from what my tests show. Except from the error case. JWithATwist hides no error cases.

   let rec RankMonadic uVerb functionRank  xNoun : JNoun =
        let xShape=xNoun.JShape
        //Rank in the call to the J verb is the min of functionRank and x rank
        let xRank = xShape.Length
        let rank = min xRank functionRank
        //If outershape contains zero, there is nothing to operate on.
        //This is no problem if innershape contains zero. Then the corresponding empty array is used in the call.         //If outershape contains zero and innershape does not, we need something to operate on to         //determine type and shape of the empty result. We then generate a default object of the correct
        //shape and type to operate on.
        let xShape = xNoun.JShape
        let innerShape = Array.sub xShape (xRank-rank) rank
        let outerShape = Array.sub xShape 0 (xRank-rank)
        match innerShape, outerShape with
        |innerShape, outerShape when (0=Array.fold (*) 1 outerShape) &&  (( 0<>Array.fold (*) 1 innerShape) || innerShape=[||]) ->             RankMonadicEmptyArraySpecialHandling uVerb rank xNoun outerShape innerShape
        |_ ->
            let boxesOfNoun = RankMonadicBox  uVerb rank xNoun
            RankMonadicOpen boxesOfNoun


    let rec RankDyadic uVerb functionRank xNoun yNoun: JNoun =
        let xShape,yShape=xNoun.JShape,yNoun.JShape
        //Rank in the call to the J verb is the min of functionRank and x rank
        let xyRank = [|xShape.Length;yShape.Length|]
        let rank = min xyRank functionRank
        // TODO: Duplicated code in RankDydic and RankDyadicBox because of planned restructuring.
        let xShape,yShape=xNoun.JShape,yNoun.JShape
        let xRank,yRank = xShape.Length,yShape.Length
        let xOperationRank,yOperationRank =
            match rank with
            |[|xOperationRank;yOperationRank|] ->
                xOperationRank,yOperationRank
            |_ ->
                raise JExceptionLengthError
         //x
        let xInnerShape = Array.sub xShape (xRank-xOperationRank) xOperationRank
        //let xFrameSize = Array.fold (*) 1 xInnerShape
        let xOuterShape = Array.sub xShape 0 (xRank-xOperationRank)
        let xNValues = max 1 (Array.fold (*) 1 xOuterShape)
        //y
        let yInnerShape = Array.sub yShape (yRank-yOperationRank) yOperationRank
        //let yFrameSize = Array.fold (*) 1 yInnerShape
        let yOuterShape = Array.sub yShape 0 (yRank-yOperationRank)
        let yNValues = max 1 (Array.fold (*) 1 yOuterShape)
        //
        let nValues,outerShape =
            match xOuterShape,yOuterShape with
            |x,y when x.Length < y.Length ->
                yNValues,yOuterShape
            |x,y when x.Length >= y.Length ->
                xNValues,xOuterShape
            |_ ->
                raise JExceptionSystemError
        match xNValues,yNValues with
        |xNValues,yNValues when xNValues=yNValues || xNValues = 1 || yNValues = 1 ->
            //If outershape contains zero, there is nothing to operate on.
            //This is no problem if innershape contains zero. Then the corresponding empty array is used in the call.             //If outershape contains zero and innershape does not, we need something to operate on to             //determine type and shape of the empty result. We then generate a default object of the correct
            //shape and type to operate on.
            let xSpecialHandling = ( 0<>Array.fold (*) 1 xInnerShape) || xInnerShape=[||]             let ySpecialHandling = ( 0<>Array.fold (*) 1 yInnerShape) || yInnerShape=[||]
            match xInnerShape,yInnerShape,outerShape with
            |xInnerShape,yInnerShape,outerShape when (0=Array.fold (*) 1 outerShape) && ( xSpecialHandling || ySpecialHandling) ->                 RankDyadicEmptyArraySpecialHandling xSpecialHandling ySpecialHandling uVerb rank xNoun yNoun outerShape xInnerShape yInnerShape
            |_ ->
                let boxesOfNoun = RankDyadicBox uVerb rank xNoun yNoun
                RankMonadicOpen boxesOfNoun
        |_->
            raise JExceptionLengthError

The rest of the code is available in the Base.fs file in JWithATwist. For copyright reasons I don't look in the J code base, so I can not point to the problem in the J code.

Cheers,
Erling Hellenäs

Den 2017-12-20 kl. 15:00, skrev Erling Hellenäs:
We have a problem in the Rank operator, which I described. I am trying to create a discussion about solutions to this problem. /Erling


Den 2017-12-20 kl. 13:31, skrev Raul Miller:
Actually, J does support arrays of nothing.  That's what i.0 is, after
all. And, if you want a scalar containing an array of nothing, then a:
matches that specification.

And we have an algebra here - though if (as in your previous message)
you do multiplication and call it addition, this becomes very
difficult to talk about.

That said, remember that we can add an arbitrary number of leading 1
dimensions to any array without changing the number of elements in
that array.

Thanks,


----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to