Shape “Domain Error” Question

Learning APL or new to Dyalog? Ask "silly" questions here, without fear...

Shape “Domain Error” Question

Postby OregonTrailAPL on Sun Dec 16, 2018 2:08 pm

Hello, I’ve been interested in APL for a while and I’m finally digging into it. I went through the online tutorial and started Legrand’s book as well. It’s a lot to take in (in a good way) so forgive me if I’m overlooking something obvious. I’m reconstructing something in my own way that I believe I saw elsewhere; reshaping a character array into an nxm matrix where each row is padded as is necessary with spaces so they are all the same number of columns. I would like to wrap this all into a monadic function “reshape.”

To start, find length of rows and columns, the left hand side for dyadic shape:

name←'ed' 'sue' 'mike'

(⍴name),(⌈/⍴¨name)

this gives

3 4

The other part; a character vector, padded with spaces, of length “rows x columns” to be reshaped:

∊(⌈/⍴¨name)↑¨name

so far so good, however when I try and put them together, dyadic shape is giving me a “DOMAIN ERROR” message:

((⍴name),⌈/⍴¨name)⍴∊(⌈/⍴¨name)↑¨name

“DOMAIN ERROR”

I can’t figure it out.

The goal is this:

reshape←{((⍴⍵),⌈/⍴¨⍵)⍴∊(⌈/⍴¨⍵)↑¨⍵}

Just to experiment I tried this:

func1←{(⍴⍵),⌈/⍴¨⍵}

func1 name
3 4

func2←{⍺⍴∊(⌈/⍴¨⍵)↑¨⍵}

3 4func2 name
ed
sue
mike

⍝As expected. But…

(func1 name)func2 name
DOMAIN ERROR
func2[0] func2←{⍺⍴∊(⌈/⍴¨⍵)↑¨⍵}


I’m guessing there’s something fundamental in monadic vs. dyadic behavior in DFNs that I’m not getting.

Another experiment:

var← 3 4
var func2 name
ed
sue
mike

⍝As expected. But…

var2← func1 name
var2
3 4
var2 func2 name
DOMAIN ERROR
func2[0] func2←{⍺⍴∊(⌈/⍴¨⍵)↑¨⍵}



Like I said, it seems like something basic that I didn’t pick up. Thanks for your help!
OregonTrailAPL
 
Posts: 4
Joined: Fri Mar 23, 2018 11:28 am

Re: Shape “Domain Error” Question

Postby OregonTrailAPL on Sun Dec 16, 2018 2:12 pm

Just a note:

the "∧" in the error messages should be under the "⍴." Copy and paste shifted them.
OregonTrailAPL
 
Posts: 4
Joined: Fri Mar 23, 2018 11:28 am

Re: Shape “Domain Error” Question

Postby Veli-Matti on Sun Dec 16, 2018 9:09 pm

Hi, and welcome to the APL world!

Your testing is a good example of an innocent error. When you construct the shape, calculating the max length with
      ⌈/⍴¨name

produces (reading from left) first a vector of vectors, and then when you apply the maximum reduce, its result is a _nested_ scalar, i.e.
      ]box on
Was OFF
name←'ed' 'sue' 'mike'
⍴¨name
┌─┬─┬─┐
│2│3│4│
└─┴─┴─┘
⌈/⍴¨name
┌─┐
│4│
└─┘
(⍴name),⌈/⍴¨name
┌─┬─┐
│3│4│
└─┴─┘


Because the left argument to reshape cannot be a nested vector, you'll get the dreaded error message.

There are some ways worth experimenting. Using enlist removes the extra nesting:
      (∊(⍴name),⌈/⍴¨name)⍴∊(⌈/⍴¨name)↑¨name
ed
sue
mike


or using tally:
      ((≢name),⌈/≢¨name)⍴∊(⌈/≢¨name)↑¨name
ed
sue
mike


or just simply using disclose
      ⊃name
ed
sue
mike


(there are some people around who use another symbol for disclose, with their low values of []ML :) )

-Veli-Matti
Veli-Matti
 
Posts: 46
Joined: Sat Nov 28, 2009 3:12 pm

Re: Shape “Domain Error” Question

Postby OregonTrailAPL on Sun Dec 16, 2018 10:17 pm

Duh! Such an easy fix. Thanks for the insight. I'll know to look for things like this when trouble shooting next time.

Another question,

I have this, "⌈/≢¨⍵", occurring twice in the function.

reshape←{((≢⍵),⌈/≢¨⍵)⍴∊(⌈/≢¨⍵)↑¨⍵}

From an efficiency standpoint, should I worry about the redundancy? If it was a big deal I could go multi-line and do it once and put it in a variable inside the function. However, I was trying to think if there is something from the functional vocabulary like a fork that I could use to tidy that up? I know this is a toy example but for the sake of learning I'm over-thinking things.

Thanks!
OregonTrailAPL
 
Posts: 4
Joined: Fri Mar 23, 2018 11:28 am

Re: Shape “Domain Error” Question

Postby Veli-Matti on Mon Dec 17, 2018 8:09 am

Hmm - efficiency...

There are good tools to check the code (for me the optimum is efficient and clear code, sometimes it is quite hard to get). If we check the original code against some variants in v. 17 (and []ML 3):
      reshape0←{(∊(⍴⍵),⌈/⍴¨⍵)⍴∊(⌈/⍴¨⍵)↑¨⍵}    ⍝ the original function  
reshape←{((≢⍵),⌈/≢¨⍵)⍴∊(⌈/≢¨⍵)↑¨⍵} ⍝ tally-ho!
reshape2←{wd←⌈/≢¨⍵ ⋄ ((≢⍵),wd)⍴∊wd↑¨⍵} ⍝ avoid redundancy
reshape3←{((≢⍵),⌈/≢¨⍵)⍴∊⊃⍵} ⍝ direct cut with disclose
disclose←{⊃⍵} ⍝ direct disclose
names←'ed' 'sue' 'mike' ⍝ the original test set


The ]runtime user command is handy here (you could as well use the cmpx function in the dfns workspace):

      ]runtime "disclose names" "reshape0 names" "reshape names" "reshape2 names" "reshape3 names" -compare

disclose names → 3.7E¯7 | 0% ⎕⎕⎕⎕⎕
reshape0 names → 2.9E¯6 | +679% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
reshape names → 1.9E¯6 | +412% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
reshape2 names → 1.7E¯6 | +359% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
reshape3 names → 1.1E¯6 | +183% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕


As I expected - but usually the algorithms need to be tested with a more realistic data:

      ≢names←↑⎕NGET'B:\lista3.txt' 1          ⍝ a text file with variable line lengths    
1585
]runtime "disclose names" "reshape0 names" "reshape names" "reshape2 names" "reshape3 names" -compare

disclose names → 8.8E¯5 | 0% ⎕⎕⎕⎕⎕
reshape0 names → 6.7E¯4 | +664% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
reshape names → 3.8E¯4 | +338% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
reshape2 names → 3.8E¯4 | +334% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
reshape3 names → 1.3E¯4 | +52% ⎕⎕⎕⎕⎕⎕⎕⎕


-Veli-Matti
Veli-Matti
 
Posts: 46
Joined: Sat Nov 28, 2009 3:12 pm

Re: Shape “Domain Error” Question

Postby OregonTrailAPL on Mon Dec 17, 2018 12:14 pm

Wow, you gave me a lot to mull over! I really appreciate the long responses, super helpful.

Thanks again!

Carl
OregonTrailAPL
 
Posts: 4
Joined: Fri Mar 23, 2018 11:28 am


Return to New to Dyalog?

Who is online

Users browsing this forum: No registered users and 1 guest