## 5127 Reputation

16 years, 111 days

"A map that tried to pin down a sheep trail was just credible,

but it was an optimistic map that tried to fix a the path made by the wind,

or a path made across the grass by the shadow of flying birds."

- _A Walk through H_, Peter Greenaway

## consider...

@Christopher2222 Look, your `b` contains "This is a test", uncompressed, no deflation.

```a:=[80, 75, 3, 4, 10, 0, 2, 0, 0, 0, -102, 109, 81, 65,
50, -97, 122, -64, 14, 0, 0, 0, 14, 0, 0, 0, 9, 0,
0, 0, 116, 101, 115, 116, 49, 46, 116, 120, 116, 84,
104, 105, 115, 32, 105, 115, 32, 97, 32, 116, 101,
115, 116, 80, 75, 1, 2, 20, 0, 10, 0, 2, 0, 0, 0,
-102, 109, 81, 65, 50, -97, 122, -64, 14, 0, 0, 0,
14, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 1, 0, 32, 0,
-74, -127, 0, 0, 0, 0, 116, 101, 115, 116, 49, 46,
116, 120, 116, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1,
0, 55, 0, 0, 0, 53, 0, 0, 0, 0, 0]:

b:=convert(a,Array,datatype=integer[1]):

convert(b[40..53],list);

[84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 116, 101, 115, 116]

StringTools:-FromByteArray(b[40..53]);
"This is a test"
```

Note that FromByteArray does not do any decompression. Your zip program chose to not deflate it (perhaps because it was so short). So, what do you think all the other entries in `a` and `b` are?

Now consider the following

```convert(StringTools:-Compress("This is a test"),list);

[120, -100, 11, -55, -56, 44, 86, 0, -94, 68, -123, -110, -44,
-30, 18, 6, 0, 41, 105, 4, -10]

StringTools:-Uncompress(%,output=string);

"This is a test"
```

## ??...

@Christopher2222 You wrote, "So essentially Uncompress should work on a zipped file."

If you are saying that you think that, with the right incantation, the current implementation of StringTools:-Uncompress would succeed then I don't see any justification for that conclusion. Doesn't your Array `b` contain "This is a test"  uncompressed, simply as a subsequence of bytes? I think that you can show this with StringTools:-FromByteArray, if you search in `b`.

Opening a zip file in binary mode, and then supposing that any implementation of merely the data uncompression scheme would simply work, is strange thinking to me. What about file headers? What about whatever wrapping information pkzip applications due to insert multiple deflated files inside a single .zip file?

If you are instead saying that you think that StringTools:-Uncompress should be altered so that it could handle the raw integer[1] of from a binary mode read, then I would disagree. That sounds like a job for FileTools:-Compressed, which could be extended to cover .zip format.

## previous a1..a6 and t?...

@elango8 Could you try to make use of the values of a1..a6 and t that were computed (along with w)? So, in the next call to fsolve you could try using the previous root's values for a1..a6,t as initial guess values in the call to fsolve? And if that fails to converge then you might try a set of narrow ranges around each of the previous root's values.

How to implement this? I suppose that the procedure Q could store the current solution it receives from fsolve in some global table. And when Q is called next it could use the stored table values to manufacture the initial guess or narrower ranges (leaving out a value for w). Of course, the code to handle this inside Q would use something 0..1 ranges, the first time, when no previous set of a1..a6,t values were available.

Root-tracking can be difficult.

## previous a1..a6 and t?...

@elango8 Could you try to make use of the values of a1..a6 and t that were computed (along with w)? So, in the next call to fsolve you could try using the previous root's values for a1..a6,t as initial guess values in the call to fsolve? And if that fails to converge then you might try a set of narrow ranges around each of the previous root's values.

How to implement this? I suppose that the procedure Q could store the current solution it receives from fsolve in some global table. And when Q is called next it could use the stored table values to manufacture the initial guess or narrower ranges (leaving out a value for w). Of course, the code to handle this inside Q would use something 0..1 ranges, the first time, when no previous set of a1..a6,t values were available.

Root-tracking can be difficult.

## parameterization...

A variation,

```R:=3: r:=1: h:=0.25:

Colors:=["Red", "HotPink",  "Blue", "BlueViolet", "DeepSkyBlue", "LightBlue",
"LightSteelBlue", "LimeGreen", "Lime", "Yellow", "Orange", "Gold"]:

EE:=seq(plot3d([(R+r*cos(11/3*(q+t)))*cos(t),
(R+r*cos(11/3*(q+t)))*sin(t),
r*sin(11/3*(q+t))],
t=6*k/12*3.14..6*(k+1)/12*3.14, q=0..h,
color=Colors[k+1], style=surface), k=0..11):

plots[display]( EE, scaling=constrained);
```

## parameterization...

A variation,

```R:=3: r:=1: h:=0.25:

Colors:=["Red", "HotPink",  "Blue", "BlueViolet", "DeepSkyBlue", "LightBlue",
"LightSteelBlue", "LimeGreen", "Lime", "Yellow", "Orange", "Gold"]:

EE:=seq(plot3d([(R+r*cos(11/3*(q+t)))*cos(t),
(R+r*cos(11/3*(q+t)))*sin(t),
r*sin(11/3*(q+t))],
t=6*k/12*3.14..6*(k+1)/12*3.14, q=0..h,
color=Colors[k+1], style=surface), k=0..11):

plots[display]( EE, scaling=constrained);
```

## evaluation...

@Chris When you call `exp` of something, it might evaluate to something involving `I` and radicals, or trig calls, etc. If calling `exp` never computed anything then it wouldn't be helpful.

You could delay the evaluation of the `exp` calls, or you could use a trick to prevent it.

```restart:

z:=-2-2*sqrt(3)*I;

(1/2)
-2 - 2 I 3

r,th := abs(z), simplify(arctan(evalc(Im(z)),evalc(Re(z))));

2
4, - - Pi
3

ans:=[seq(surd(r,2)*(cos+I*sin)((th+2*k*Pi)/2),k=0..2-1)];

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

simplify(map(convert,ans,polar));

[     /     1   \       /   2   \]
[polar|2, - - Pi|, polar|2, - Pi|]
[     \     3   /       \   3   /]

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

quicktovanish:=[seq(surd(r,2)*'exp'(I*(th+2*k*Pi)/2),k=0..2-1)];

[     / 1     \       /2     \]
[2 exp|-- I Pi|, 2 exp|- I Pi|]
[     \ 3     /       \3     /]

quicktovanish; # any subsequent evaluation take away what you wanted

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

expans:=[seq(surd(r,2)*exp(``(I*(th+2*k*Pi)/2)),k=0..2-1)];

[     // 1     \\       //2     \\]
[2 exp||-- I Pi||, 2 exp||- I Pi||]
[     \\ 3     //       \\3     //]

expans; # it sticks around, visually available

[     // 1     \\       //2     \\]
[2 exp||-- I Pi||, 2 exp||- I Pi||]
[     \\ 3     //       \\3     //]

evalc(expand(expans)); # we'll have to unstick it, to compute with it

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]
```

## evaluation...

@Chris When you call `exp` of something, it might evaluate to something involving `I` and radicals, or trig calls, etc. If calling `exp` never computed anything then it wouldn't be helpful.

You could delay the evaluation of the `exp` calls, or you could use a trick to prevent it.

```restart:

z:=-2-2*sqrt(3)*I;

(1/2)
-2 - 2 I 3

r,th := abs(z), simplify(arctan(evalc(Im(z)),evalc(Re(z))));

2
4, - - Pi
3

ans:=[seq(surd(r,2)*(cos+I*sin)((th+2*k*Pi)/2),k=0..2-1)];

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

simplify(map(convert,ans,polar));

[     /     1   \       /   2   \]
[polar|2, - - Pi|, polar|2, - Pi|]
[     \     3   /       \   3   /]

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

quicktovanish:=[seq(surd(r,2)*'exp'(I*(th+2*k*Pi)/2),k=0..2-1)];

[     / 1     \       /2     \]
[2 exp|-- I Pi|, 2 exp|- I Pi|]
[     \ 3     /       \3     /]

quicktovanish; # any subsequent evaluation take away what you wanted

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]

expans:=[seq(surd(r,2)*exp(``(I*(th+2*k*Pi)/2)),k=0..2-1)];

[     // 1     \\       //2     \\]
[2 exp||-- I Pi||, 2 exp||- I Pi||]
[     \\ 3     //       \\3     //]

expans; # it sticks around, visually available

[     // 1     \\       //2     \\]
[2 exp||-- I Pi||, 2 exp||- I Pi||]
[     \\ 3     //       \\3     //]

evalc(expand(expans)); # we'll have to unstick it, to compute with it

[       (1/2)          (1/2)]
[1 - I 3     , -1 + I 3     ]
```

## exp...

@Chris I didn't give a way, earlier, to get the exponential form. You've inadvertantly partially undone that additional desired conversion when you applied `simplify` in your modification of what I did for the polar form.

```restart:

z:=-2-2*sqrt(3)*I;

(1/2)
-2 - 2 I 3

r,th := abs(z), simplify(arctan(evalc(Im(z)),evalc(Re(z))));

2
4, - - Pi
3

ans := [seq(surd(r,3)*(cos+I*sin)((th+2*k*Pi)/3),k=0..3-1)];

[ (2/3) /   /2   \        /2   \\
[2      |cos|- Pi| - I sin|- Pi||,
[       \   \9   /        \9   //

(2/3) /   /4   \        /4   \\
2      |cos|- Pi| + I sin|- Pi||,
\   \9   /        \9   //

(2/3) /    /1   \        /1   \\]
2      |-cos|- Pi| - I sin|- Pi||]
\    \9   /        \9   //]

simplify(map(convert,ans,polar));

[     / (2/3)    2   \       / (2/3)  4   \       / (2/3)    8   \
[polar|2     , - - Pi|, polar|2     , - Pi|, polar|2     , - - Pi|
[     \          9   /       \        9   /       \          9   /

]
]
]

convert(ans,exp);

[ (2/3)    / 2     \   (2/3)    /4     \    (2/3)    /1     \]
[2      exp|-- I Pi|, 2      exp|- I Pi|, -2      exp|- I Pi|]
[          \ 9     /            \9     /             \9     /]

[seq(surd(r,3)*exp(I*(th+2*k*Pi)/3),k=0..3-1)];

[ (2/3)    / 2     \   (2/3)    /4     \   (2/3)    / 8     \]
[2      exp|-- I Pi|, 2      exp|- I Pi|, 2      exp|-- I Pi|]
[          \ 9     /            \9     /            \ 9     /]
```

You seem yo have switched from cube roots to square roots, in a few places, without saying so.

The purpose of line

```       {seq(simplify(p^3), p in ans)}
```

was to check the result. By raising all the three purported roots to the power 3, and putting these results in a set and then getting just a single entry equivalent to original `z`, then you can see whether they really are cube roots of that original complex number.

## exp...

@Chris I didn't give a way, earlier, to get the exponential form. You've inadvertantly partially undone that additional desired conversion when you applied `simplify` in your modification of what I did for the polar form.

```restart:

z:=-2-2*sqrt(3)*I;

(1/2)
-2 - 2 I 3

r,th := abs(z), simplify(arctan(evalc(Im(z)),evalc(Re(z))));

2
4, - - Pi
3

ans := [seq(surd(r,3)*(cos+I*sin)((th+2*k*Pi)/3),k=0..3-1)];

[ (2/3) /   /2   \        /2   \\
[2      |cos|- Pi| - I sin|- Pi||,
[       \   \9   /        \9   //

(2/3) /   /4   \        /4   \\
2      |cos|- Pi| + I sin|- Pi||,
\   \9   /        \9   //

(2/3) /    /1   \        /1   \\]
2      |-cos|- Pi| - I sin|- Pi||]
\    \9   /        \9   //]

simplify(map(convert,ans,polar));

[     / (2/3)    2   \       / (2/3)  4   \       / (2/3)    8   \
[polar|2     , - - Pi|, polar|2     , - Pi|, polar|2     , - - Pi|
[     \          9   /       \        9   /       \          9   /

]
]
]

convert(ans,exp);

[ (2/3)    / 2     \   (2/3)    /4     \    (2/3)    /1     \]
[2      exp|-- I Pi|, 2      exp|- I Pi|, -2      exp|- I Pi|]
[          \ 9     /            \9     /             \9     /]

[seq(surd(r,3)*exp(I*(th+2*k*Pi)/3),k=0..3-1)];

[ (2/3)    / 2     \   (2/3)    /4     \   (2/3)    / 8     \]
[2      exp|-- I Pi|, 2      exp|- I Pi|, 2      exp|-- I Pi|]
[          \ 9     /            \9     /            \ 9     /]
```

You seem yo have switched from cube roots to square roots, in a few places, without saying so.

The purpose of line

```       {seq(simplify(p^3), p in ans)}
```

was to check the result. By raising all the three purported roots to the power 3, and putting these results in a set and then getting just a single entry equivalent to original `z`, then you can see whether they really are cube roots of that original complex number.

## length...

You might be able to use a call to `length`, instead of `nops` and convert/base and make it a little terser. That is , NSD:=x->length(op(1,x)) .

But this, and (Markiyan's) earlier NSD above, mishandles trailing zeroes in the case that there is no decimal point. For example

```NSD(400); # not ok

3

NSD(400.); # ok

3
```

## length...

You might be able to use a call to `length`, instead of `nops` and convert/base and make it a little terser. That is , NSD:=x->length(op(1,x)) .

But this, and (Markiyan's) earlier NSD above, mishandles trailing zeroes in the case that there is no decimal point. For example

```NSD(400); # not ok

3

NSD(400.); # ok

3
```

## 2D Math?...

Are you using 2D Math entry mode, in a Document? If so, then what happens if you separate the statements into different paragraphs or execution blocks? Which of the three gives the error?

## agreed...

I concur with Preben, uploading an example which reproduces the problem would help.

I created a module which exported `.` a procedure that admitted a `seq` argument of a particular types. I was able to loop over the multiple items in that sequence argument, in order, when I call a.b.c.d etc.

So perhaps there is some other critical detail that matters, with your methodology.

btw, it sounds from your description that your module exports its own `.`. It's true that this fits the English term "overloads", but there is another (related, but differnent) overloading mechanism in Maple (option overload) which seems to not be your situation. It might be better to not use that term here, if that mechanism is not used by you, for the sake of clarity. Conversely, if that is in fact what you are doing, as opposed to a mere export, then it would help to know so. Meant in a friendly way.