Discussion:
storing/loading n-ary data via complex numbers...
Add Reply
Chris M. Thomasson
2017-06-18 23:11:30 UTC
Reply
Permalink
Raw Message
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
function described in the following thread:

"n-ary roots from complex numbers..."
https://groups.google.com/d/topic/comp.lang.c++/05XwgswUnDg/discussion

to actually store data. The following code stores my name "CHRIS" from
the following symbol table:

"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

in a single complex number via root map. For storing data, it maps each
symbol index to a root in the complex number z during iteration. For
loading data, it raises z back up through the root chain. Loading needs
the complex number, the origin number (for termination), and the correct
power, and it can recreate the stored data. It locates each root by
doing a little search in the n-ary roots returned by ct_roots. The
experimental function is ct_try_find. Take note of it because it is key
wrt being able to load the stored data... There has to be a more
efficient way of doing the root search. Humm... For termination, it
compares z iterates to the original number used for storing the information.


the function ct_store stores n-ary tokens in a single complex number.
the function ct_load loads n-ary tokens from a complex number.

The termination condition is iffy and really sensitive to floating point
errors. Its better to store data in strict blocks, so a load knows to
iterate a block length, and then quite. Now it has to compare the
iterates of z to the damn origin. Humm... The can be improved upon.

We cannot store too much data here, or one with get a data-incoherent
error, via assertion. I can store the symbols DEADBEEF for sure. ;^)

This is where floating point errors can really break things down.


Btw, I am wondering if you can run it and perhaps post some of the
output? It would be interesting to compare the results I get on to other
systems.


Before I go on, can anybody run this code? Also, I think this deserved
its own thread? Will get back to the group tomorrow.

Thanks everybody.

In C++:
__________________________________________
// 4/12/2017: n-ary complex storage example by Chris M. Thomasson

#include <complex>
#include <iostream>
#include <vector>
#include <limits>
#include <algorithm> // reverse
#include <cstdint> // want to work with 64-bit numbers
#include <cassert> // want to sanity check run time...
#include <cstring> // faster than iostream's?


// Well, I need some consistent typenames... ;^)
typedef std::int64_t ct_int;
typedef std::uint64_t ct_uint;
typedef double ct_float;
typedef std::numeric_limits<ct_float> ct_float_nlim;
typedef std::complex<ct_float> ct_complex;
typedef std::complex<ct_uint> ct_complex_uint;
typedef std::vector<ct_complex> ct_complex_vec;

#define CT_PI 3.14159265358979323846


// Round up and convert the real and imaginary
// parts of z to unsigned integers of type ct_uint
// return a complex number with unsigned integer parts
ct_complex_uint
ct_round_uint(
ct_complex const& z
) {
ct_uint re = (ct_uint)std::floor(std::abs(z.real()) + .5);
ct_uint im = (ct_uint)std::floor(std::abs(z.imag()) + .5);
return ct_complex_uint(re, im);
}


// the integer p shall not be zero
// create abs(p) roots of z wrt z^(1/p);
// store them in out, and return the average error.
ct_float
ct_roots(
ct_complex const& z,
ct_int p,
ct_complex_vec& out
) {
assert(p != 0);

// Gain the basics
ct_float radius = std::pow(std::abs(z), 1.0 / p);
ct_float angle_base = std::arg(z) / p;
ct_float angle_step = (CT_PI * 2.0) / p;

// Setup the iteration
ct_uint n = std::abs(p);
ct_float avg_err = 0.0;

// Calculate the n roots...
for (ct_uint i = 0; i < n; ++i)
{
// our angle
ct_float angle = angle_step * i;

// our point
ct_complex c = {
std::cos(angle_base + angle) * radius,
std::sin(angle_base + angle) * radius
};

// output data
out.push_back(c);

// Raise our root the the power...
ct_complex raised = std::pow(c, p);

// Sum up the Go% damn floating point errors!
avg_err = avg_err + std::abs(raised - z);
}

// gain the average error sum... ;^o
return avg_err / n;
}


// Try's to find the target root z out of roots using
// eps, return the index of the root, or -1 for failure.
int
ct_try_find(
ct_complex const& z,
ct_complex_vec const& roots,
ct_float eps
) {
std::size_t n = roots.size();

for (std::size_t i = 0; i < n; ++i)
{
ct_complex const& root = roots[i];

ct_float adif = std::abs(root - z);

if (adif < eps)
{
return i;
}
}

return -1;
}





// The Token Table
// Will deal with scrambled token vectors in further posts.
// This is global for now, easy to convert to per store/load
// pairs
static std::string const g_tokens_str =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

// Gains the power from the largest token position
// from tokens in g_tokens_str
ct_int
ct_gain_power(
std::string const& tokens
) {
ct_uint n = tokens.length();

std::size_t pmax = 0;

for (ct_uint i = 0; i < n; ++i)
{
std::size_t fridx = g_tokens_str.find_first_of(tokens[i]);
assert(fridx != std::string::npos);
pmax = std::max(pmax, fridx);
}

return (ct_int)(pmax + 1);
}


// Store tokens using a power of p starting in z-origin
// Return the complex number holding said tokens.
ct_complex
ct_store(
ct_complex const& z_origin,
ct_int p,
std::string const& tokens
) {
ct_uint n = tokens.length();

ct_complex z = z_origin;
ct_float store_avg_err = 0.0;

std::cout << "Storing Data..." << "\n";
std::cout << "stored:z_origin:" << z_origin << "\n";

for (ct_uint i = 0; i < n; ++i)
{
// Gain all of the roots, and running store error
ct_complex_vec roots;
ct_float avg_err = ct_roots(z, p, roots);
store_avg_err = store_avg_err + avg_err;

// reference our root
std::size_t fridx = g_tokens_str.find_first_of(tokens[i]);
assert(fridx != std::string::npos);

z = roots[fridx];

std::cout << "stored[" << i << "]:" << z << "\n";
}

store_avg_err = store_avg_err / n;
std::cout << "store_avg_err:" << store_avg_err << "\n";

return z;
}


// Load our tokens from z_store, power of p,
// stopping at z_target using eps, storing tokens
// in out_tokens, and the resulting z in out_z
ct_float
ct_load(
ct_complex const& z_store,
ct_complex const& z_target,
ct_int p,
ct_float eps, // epsilon
std::string& out_tokens,
ct_complex& out_z
) {
ct_complex z = z_store;
ct_uint n = 128; // max iter
ct_float load_err_sum = 0.0;

std::cout << "Loading Data..." << "\n";
for (ct_uint i = 0; i < n; ++i)
{
// raise...
ct_complex z_next = std::pow(z, p);

// Gain all of the roots, and running load error
ct_complex_vec roots;
ct_float avg_err = ct_roots(z_next, p, roots);
load_err_sum += avg_err;

// try to find our root...
int root_idx = ct_try_find(z, roots, eps);
if (root_idx < 0 ||
(ct_uint)root_idx >= g_tokens_str.length()) break;

std::cout << "loaded[" << i << "]:" << z << "\n";

out_tokens += g_tokens_str[root_idx];

// advance
z = z_next;

// check for termination condition...
if (std::abs(z - z_target) < eps)
{
std::cout << "fin detected!:[" << i << "]:" << z << "\n";
break;
}
}

// reverse our tokens
std::reverse(out_tokens.begin(), out_tokens.end());

out_z = z;
return load_err_sum;
}


int main()
{
std::cout.precision(ct_float_nlim::max_digits10);

std::cout << "g_tokens_str:" << g_tokens_str << "\n\n";

{
ct_complex z_origin = { -.75, .06 };

// The original data to be stored
std::string stored = "CHRIS";
ct_int power = ct_gain_power(stored);

std::cout << "stored:" << stored << "\n";
std::cout << "power:" << power << "\n\n";
std::cout << "________________________________________\n";

// STORE
ct_complex z_stored = ct_store(z_origin, power, stored);

std::cout << "________________________________________\n";


std::cout << "\nSTORED POINT:" << z_stored << "\n";


std::cout << "________________________________________\n";

// The data loaded from the stored.
std::string loaded;
ct_complex z_loaded;
ct_float eps = .001; // epsilon

// LOAD
ct_float load_err_sum =
ct_load(z_stored, z_origin, power, eps, loaded, z_loaded);

std::cout << "________________________________________\n";

std::cout << "\nORIGIN POINT:" << z_origin << "\n";
std::cout << "LOADED POINT:" << z_loaded << "\n";

std::cout << "\nloaded:" << loaded << "\n"
"load_err_sum:" << load_err_sum << "\n";

// make sure everything is okay...
if (stored == loaded)
{
std::cout << "\n\nDATA COHERENT! :^D" << "\n";
}

else
{
std::cout << "\n\n***** DATA CORRUPTED!!! Shi%! *****" << "\n";
assert(stored == loaded);
}
}

// Fin...
std::cout << "\n\nFin, hit <ENTER> to exit...\n";
std::fflush(stdout);
std::cin.get();

return 0;
}
__________________________________________


Fwiw, here are the outputs of the ct_store function I am getting from
two different compilers, MSVC and GCC:


MSVC 2015
________________________________________
Storing Data...
stored:z_origin:(-0.75,0.059999999999999998)
stored[0]:(-0.89756758958883731,0.41826246336621364)
stored[1]:(-0.8048304823068565,-0.59293470672819726)
stored[2]:(0.86792869817386908,-0.49666532554878623)
stored[3]:(-0.73820338609537295,-0.67457761324417354)
stored[4]:(0.95549545746010056,-0.29500576779591425)
store_avg_err:6.8460152306934853e-15
________________________________________


GCC version 5.1.0 (tdm64-1)
________________________________________
Storing Data...
stored:z_origin:(-0.75,0.059999999999999998)
stored[0]:(-0.89756758958883731,0.41826246336621364)
stored[1]:(-0.8048304823068565,-0.59293470672819726)
stored[2]:(0.86792869817386908,-0.49666532554878623)
stored[3]:(-0.73820338609537295,-0.67457761324417354)
stored[4]:(0.95549545746010056,-0.29500576779591425)
store_avg_err:6.8460152306934853e-15
________________________________________


If you run this and get different numbers, I would be interested in
looking at them. For instance, when this is executed online at:

http://cpp.sh I get:
________________________________________
Storing Data...
stored:z_origin:(-0.75,0.059999999999999998)
stored[0]:(-0.89756758958883731,0.41826246336621364)
stored[1]:(-0.8048304823068565,-0.59293470672819726)
stored[2]:(0.86792869817386908,-0.49666532554878623)
stored[3]:(-0.73820338609537295,-0.67457761324417354)
stored[4]:(0.95549545746010056,-0.29500576779591425)
store_avg_err:6.1392213260039921e-15
________________________________________

The store_avg_err is different!


Sorry for the crude nature of my technique. I am hoping readers here can
help me create a more concise, mathematical description.

thank you everybody.

Also, I am doing this in my free time. I wish I had more of it!

;^o
Chris M. Thomasson
2017-06-18 23:19:07 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
"n-ary roots from complex numbers..."
https://groups.google.com/d/topic/comp.lang.c++/05XwgswUnDg/discussion
to actually store data. The following code stores my name "CHRIS" from
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
in a single complex number via root map. For storing data, it maps each
symbol index to a root in the complex number z during iteration. For
loading data, it raises z back up through the root chain. Loading needs
the complex number, the origin number (for termination), and the correct
power, and it can recreate the stored data. It locates each root by
doing a little search in the n-ary roots returned by ct_roots. The
experimental function is ct_try_find. Take note of it because it is key
wrt being able to load the stored data... There has to be a more
efficient way of doing the root search. Humm... For termination, it
compares z iterates to the original number used for storing the information.
[...]
Post by Chris M. Thomasson
Before I go on, can anybody run this code? Also, I think this deserved
its own thread? Will get back to the group tomorrow.
Thanks everybody.
__________________________________________
[...]

Yikes! I forgot to mention that the code needs a C++ 11 compiler!

Sorry about that non-sense. ;^o
Chris M. Thomasson
2017-06-18 23:40:21 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
"n-ary roots from complex numbers..."
https://groups.google.com/d/topic/comp.lang.c++/05XwgswUnDg/discussion
to actually store data. The following code stores my name "CHRIS" from
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
[...]
Post by Chris M. Thomasson
int main()
{
std::cout.precision(ct_float_nlim::max_digits10);
std::cout << "g_tokens_str:" << g_tokens_str << "\n\n";
{
ct_complex z_origin = { -.75, .06 };
// The original data to be stored
std::string stored = "CHRIS";
ct_int power = ct_gain_power(stored);
Just wanted to point out that it also works with negative powers. Change
the line above to:

ct_int power = -ct_gain_power(stored);

and gain the following output:
____________________________
g_tokens_str:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

stored:CHRIS
power:-29

________________________________________
Storing Data...
stored:z_origin:(-0.75,0.059999999999999998)
stored[0]:(-0.91535190113321718,-0.42654987262887645)
stored[1]:(-0.90085434620944727,0.4333418034400674)
stored[2]:(0.94261448083215615,0.33391805934019758)
stored[3]:(-0.71787193351114498,0.69617460640980755)
stored[4]:(0.99091689566132868,0.13447577340611339)
store_avg_err:5.8101727921743071e-015
________________________________________

STORED POINT:(0.99091689566132868,0.13447577340611339)
________________________________________
Loading Data...
loaded[0]:(0.99091689566132868,0.13447577340611339)
loaded[1]:(-0.71787193351113965,0.69617460640981532)
loaded[2]:(0.94261448083202337,0.333918059340434)
loaded[3]:(-0.90085434620729132,0.43334180344764223)
loaded[4]:(-0.91535190100158148,-0.42654987281836065)
fin detected!:[4]:(-0.75000000045429771,0.060000004964319696)
________________________________________

ORIGIN POINT:(-0.75,0.059999999999999998)
LOADED POINT:(-0.75000000045429771,0.060000004964319696)

loaded:CHRIS
load_err_sum:2.8591789162085673e-014


DATA COHERENT! :^D
____________________________

Perry nice!
Bill
2017-06-19 04:29:48 UTC
Reply
Permalink
Raw Message
The roots of complex numbers like z^n+c, or even just z^n can store data.
"Coding theory" is an old and broad topic, and is still of current
interest--and not just among mathematicians! ; )
Chris M. Thomasson
2017-06-19 19:39:51 UTC
Reply
Permalink
Raw Message
Post by Bill
The roots of complex numbers like z^n+c, or even just z^n can store data.
"Coding theory" is an old and broad topic, and is still of current
interest--and not just among mathematicians! ; )
This is exactly what I am doing here Bill: Trying to code multiple
symbols into the roots of a complex number. I need some help wrt
describing the technique in a mathematical way instead of using C++, or
any other programming language!

Let's take z^n as an example, where z is a complex number and n is an
integer power. z^n has abs(n) roots in the form of z^(1/n). Each of the
n roots can directly map into a symbol table for storing actual data.
Loading data raises the final resulting root back up through the root
chain to recreate the data. Floating point precision issues aside for a
moment, this actually works.

I am having some trouble thinking about how to properly express my
program in something other than a programming language. I need some help!
Julio Di Egidio
2017-06-19 20:34:13 UTC
Reply
Permalink
Raw Message
On Monday, June 19, 2017 at 9:40:05 PM UTC+2, Chris M. Thomasson wrote:
<snip>
Post by Chris M. Thomasson
Let's take z^n as an example, where z is a complex number and n is an
integer power. z^n has abs(n) roots in the form of z^(1/n). Each of the
n roots can directly map into a symbol table for storing actual data.
A map is a function from something to something. It is unclear (to me at
least) what you are talking about.
Post by Chris M. Thomasson
Loading data raises the final resulting root back up through the root
chain to recreate the data. Floating point precision issues aside for a
moment, this actually works.
I am having some trouble thinking about how to properly express my
program in something other than a programming language. I need some help!
Can you provide an informal description? Maybe just a function declaration,
with explanation of input arguments and of the expected results.

Julio
Chris M. Thomasson
2017-06-20 19:10:24 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Let's take z^n as an example, where z is a complex number and n is an
integer power. z^n has abs(n) roots in the form of z^(1/n). Each of the
n roots can directly map into a symbol table for storing actual data.
A map is a function from something to something. It is unclear (to me at
least) what you are talking about.
Post by Chris M. Thomasson
Loading data raises the final resulting root back up through the root
chain to recreate the data. Floating point precision issues aside for a
moment, this actually works.
I am having some trouble thinking about how to properly express my
program in something other than a programming language. I need some help!
Can you provide an informal description? Maybe just a function declaration,
with explanation of input arguments and of the expected results.
I am mapping symbols to roots. Let me attempt to give a very crude high
level, simple description of storing data a go here. Okay, pick any
complex number Z[0], except for (0, 0). Now, think of some symbols to
store, say 012. That's three symbols, so we are storing 3-ary data. Lets
say that S[0...2] maps to each one where S[0] = 0, S[1] = 1 and S[2] =
2. Fine.

Lets take the 3 roots of Z[0], as R_0[0...2] such that raising any R_0
to the power of 3 gains Z[0]. Now, we map S[0] to R_0[0]. Lets set Z[1]
equal to R_0[0]. We just stored the first symbol in S via Z[1]. Nice.

Now, we take the 3 roots of Z[1] as R_1[0...2] such that raising any R_1
to the power of 3 gains Z[1]. We map S[1] to R_1[1] as Z[2]. We just
stored the second symbol in S as Z[2], fine.

Finally, we take the 3 roots of Z[2] as R_2[0...2] such that raising any
R_2 to the power of 3 gains Z[2]. We map S[2] to R_2[2] as Z[3]. We just
stored the third and final symbol in S as Z[3], fine.

The final stored point is Z[3] for it contains the 3 symbols in S.

That is how I am storing data in complex numbers. I will write the
procedure for loading the symbols from Z[3] sometime today.

Does this make any sense to anybody? Is my high level description total
garbage? I know the procedure works, I need some help on how to properly
describe it mathematically. This is why I posted it to this group in the
first place.
Julio Di Egidio
2017-06-21 09:43:06 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Finally, we take the 3 roots of Z[2] as R_2[0...2] such that raising any
R_2 to the power of 3 gains Z[2]. We map S[2] to R_2[2] as Z[3]. We just
stored the third and final symbol in S as Z[3], fine.
The final stored point is Z[3] for it contains the 3 symbols in S.
That is how I am storing data in complex numbers. I will write the
procedure for loading the symbols from Z[3] sometime today.
-----------------
Let A be an (ordered) alphabet of size N.
Let Z be a non-zero complex number.
Let T := Z;
For every symbol C := S[I] in S: // i.e. for I = 1 to length(S)
Let T := Roots^N(T)[I] // i.e. the I-th N-th-root of T
In the detail, there are a couple of errors there, but never mind.
Post by Julio Di Egidio
Return T.
We need to know ... ???
-----------------
There I have stopped, not only with the problem of finding a clever way for
the second function, but also with the problem indeed of how to handle the
unavoidable rounding errors: using "complex rationals" won't cut it, as
taking roots is irrational per se, but maybe suitable Z could do the trick,
at least in case there is an absolute maximum length for the strings... etc.
I should think more about it...
It's clever, it's also great to play with complex numbers, but I think
eventually that scheme is not efficient. It is really akin to mapping
any given string to a node of a tree whose branching is equal to the
size of the alphabet and whose depth at that node is equal to the
length of the string. If you think it that way, it becomes apparent
that using complex numbers (or real) will just make things more difficult:
it is easier, an just as efficient I think, to code a node as a sequence of
indexes in the alphabet for each character; and then it may be apparent that
we can do as well with the simplest coding scheme: just take the binary
representation of the string... If I may am not missing anything.

Julio
Julio Di Egidio
2017-06-21 11:32:21 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Finally, we take the 3 roots of Z[2] as R_2[0...2] such that raising any
R_2 to the power of 3 gains Z[2]. We map S[2] to R_2[2] as Z[3]. We just
stored the third and final symbol in S as Z[3], fine.
The final stored point is Z[3] for it contains the 3 symbols in S.
That is how I am storing data in complex numbers. I will write the
procedure for loading the symbols from Z[3] sometime today.
-----------------
Let A be an (ordered) alphabet of size N.
Let Z be a non-zero complex number.
Let T := Z;
For every symbol C := S[I] in S: // i.e. for I = 1 to length(S)
Let T := Roots^N(T)[I] // i.e. the I-th N-th-root of T
In the detail, there are a couple of errors there, but never mind.
Post by Julio Di Egidio
Return T.
We need to know ... ???
-----------------
There I have stopped, not only with the problem of finding a clever way for
the second function, but also with the problem indeed of how to handle the
unavoidable rounding errors: using "complex rationals" won't cut it, as
taking roots is irrational per se, but maybe suitable Z could do the trick,
at least in case there is an absolute maximum length for the strings... etc.
I should think more about it...
It's clever, it's also great to play with complex numbers, but I think
eventually that scheme is not efficient [...]: just take the binary
representation of the string... If I may am not missing anything.
On the other hand, there may be a lossy scheme lurking there...
Have you tried, with the crudest implementation based on the built-in
floating point, what happens when coding-decoding strings of various
lengths? How much "error" do you seem to get? That might be interesting
to investigate.

Julio
Chris M. Thomasson
2017-06-21 20:01:54 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
Post by Julio Di Egidio
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Finally, we take the 3 roots of Z[2] as R_2[0...2] such that raising any
R_2 to the power of 3 gains Z[2]. We map S[2] to R_2[2] as Z[3]. We just
stored the third and final symbol in S as Z[3], fine.
The final stored point is Z[3] for it contains the 3 symbols in S.
That is how I am storing data in complex numbers. I will write the
procedure for loading the symbols from Z[3] sometime today.
-----------------
Let A be an (ordered) alphabet of size N.
Let Z be a non-zero complex number.
Let T := Z;
For every symbol C := S[I] in S: // i.e. for I = 1 to length(S)
Let T := Roots^N(T)[I] // i.e. the I-th N-th-root of T
In the detail, there are a couple of errors there, but never mind.
Post by Julio Di Egidio
Return T.
We need to know ... ???
-----------------
There I have stopped, not only with the problem of finding a clever way for
the second function, but also with the problem indeed of how to handle the
unavoidable rounding errors: using "complex rationals" won't cut it, as
taking roots is irrational per se, but maybe suitable Z could do the trick,
at least in case there is an absolute maximum length for the strings... etc.
I should think more about it...
It's clever, it's also great to play with complex numbers, but I think
eventually that scheme is not efficient [...]: just take the binary
representation of the string... If I may am not missing anything.
On the other hand, there may be a lossy scheme lurking there...
Oh yes. I think so. Storing too much data will start to give errors on
the last bits when loading it back. Also, wrt loading data, I am
comparing the previous roots to the subsequent roots to allow for
termination of the iteration process. Now, we can use a block method
where we store a fixed block of data and eliminate the comparison of the
raised roots to the original Z[0], so to speak.
Post by Julio Di Egidio
Have you tried, with the crudest implementation based on the built-in
floating point, what happens when coding-decoding strings of various
lengths? How much "error" do you seem to get? That might be interesting
to investigate.
Never really measured the error ratios, damn it! I really need to do
that Julio. Wrt storing too much data, the first part of the symbols are
correct, then things start to softly "break down". I can store around
60-ish bits of data in a complex number with two 64-bit parts. However,
it really depends on the nature of the data. I remember that in binary,
if there are a lot of 0's or 1's in a row, well, then it can actually
start to compress data. Not by much, but it can. I will work on an
example when I get some more time. Perhaps today or sometime tomorrow.

Anyway, thank you for taking the time to take a look at this crazy
stuff! Well, perhaps not so crazy since I have a crude working program
of my highly experimental technique...

;^)
Chris M. Thomasson
2017-06-21 19:50:46 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Finally, we take the 3 roots of Z[2] as R_2[0...2] such that raising any
R_2 to the power of 3 gains Z[2]. We map S[2] to R_2[2] as Z[3]. We just
stored the third and final symbol in S as Z[3], fine.
The final stored point is Z[3] for it contains the 3 symbols in S.
That is how I am storing data in complex numbers. I will write the
procedure for loading the symbols from Z[3] sometime today.
-----------------
Let A be an (ordered) alphabet of size N.
Let Z be a non-zero complex number.
Let T := Z;
For every symbol C := S[I] in S: // i.e. for I = 1 to length(S)
Let T := Roots^N(T)[I] // i.e. the I-th N-th-root of T
In the detail, there are a couple of errors there, but never mind.
Post by Julio Di Egidio
Return T.
We need to know ... ???
-----------------
There I have stopped, not only with the problem of finding a clever way for
the second function, but also with the problem indeed of how to handle the
unavoidable rounding errors: using "complex rationals" won't cut it, as
taking roots is irrational per se, but maybe suitable Z could do the trick,
at least in case there is an absolute maximum length for the strings... etc.
I should think more about it...
It's clever, it's also great to play with complex numbers, but I think
eventually that scheme is not efficient.
Its not efficient. However, I do agree with you that its a pretty neat
way to think of complex numbers.
Post by Julio Di Egidio
It is really akin to mapping
any given string to a node of a tree whose branching is equal to the
size of the alphabet and whose depth at that node is equal to the
length of the string.
Thinking of the roots of complex numbers as a tree is a perfect way of
explaining the overall technique. Thank you.
Post by Julio Di Egidio
If you think it that way, it becomes apparent
it is easier, an just as efficient I think, to code a node as a sequence of
indexes in the alphabet for each character; and then it may be apparent that
we can do as well with the simplest coding scheme: just take the binary
representation of the string... If I may am not missing anything.
I started with binary, and moved onto n-ary simply because I thought its
fairly interesting. We map n-ary data to the roots of a tree for storing
data, then we compare the previous values to the node values of the
level, or subsequent nodes, to load data in reverse order. Actually,
when we use binary, we can use the sign of the real part to gain the
on/off nature of binary wrt loading data.
Julio Di Egidio
2017-06-20 21:50:33 UTC
Reply
Permalink
Raw Message
On Tuesday, June 20, 2017 at 9:10:31 PM UTC+2, Chris M. Thomasson wrote:
<snip>
Post by Chris M. Thomasson
Finally, we take the 3 roots of Z[2] as R_2[0...2] such that raising any
R_2 to the power of 3 gains Z[2]. We map S[2] to R_2[2] as Z[3]. We just
stored the third and final symbol in S as Z[3], fine.
The final stored point is Z[3] for it contains the 3 symbols in S.
That is how I am storing data in complex numbers. I will write the
procedure for loading the symbols from Z[3] sometime today.
OK, maybe I get it, here is a first attempt:

-----------------
Let A be an (ordered) alphabet of size N.
Let Z be a non-zero complex number.

Given any string S over A, ***to map S to complex T***:
Let T := Z;
For every symbol C := S[I] in S: // i.e. for I = 1 to length(S)
Let T := Roots^N(T)[I] // i.e. the I-th N-th-root of T
Return T.

Given any complex T obtained as above, ***to map T to string S***:
We need to know ... ???
-----------------

There I have stopped, not only with the problem of finding a clever way for
the second function, but also with the problem indeed of how to handle the
unavoidable rounding errors: using "complex rationals" won't cut it, as
taking roots is irrational per se, but maybe suitable Z could do the trick,
at least in case there is an absolute maximum length for the strings... etc.
I should think more about it...

Julio
Chris M. Thomasson
2017-06-21 19:38:55 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Finally, we take the 3 roots of Z[2] as R_2[0...2] such that raising any
R_2 to the power of 3 gains Z[2]. We map S[2] to R_2[2] as Z[3]. We just
stored the third and final symbol in S as Z[3], fine.
The final stored point is Z[3] for it contains the 3 symbols in S.
That is how I am storing data in complex numbers. I will write the
procedure for loading the symbols from Z[3] sometime today.
-----------------
Let A be an (ordered) alphabet of size N.
Let Z be a non-zero complex number.
Let T := Z;
For every symbol C := S[I] in S: // i.e. for I = 1 to length(S)
Let T := Roots^N(T)[I] // i.e. the I-th N-th-root of T
Return T.
We need to know ... ???
-----------------
Thank you for that Julio. I see what you are getting at in that compact
description.
Post by Julio Di Egidio
There I have stopped, not only with the problem of finding a clever way for
the second function,
Here is how I am loading the symbols back from Z[3], or T in your example.

We raise Z[3] to the power of 3 to get Z[2]. Now we take the 3 roots of
Z[2] as R_2[0...2]. We search for Z[3] in R_2[0...2] and find that Z[3]
is equal to R_2[2], the index is 2. So, we know that S[2] is the last
symbol. Lets map that to a new string L[0...2] where L[0] = S[2]. We
compare Z[2] to Z[0], notice that its not equal and continue. Fine.

Now, we raise Z[2] to the power of 3 to get Z[1]. We take the three
roots of Z[1] as R_1[0...2], perform a search in R_1 for Z[2]. We find
that that Z[2] is equal to R_1[1], the index is 1. Therefore, we map
L[1] to S[1]. We compare Z[1] to Z[0], find that is not equal and continue.

Okay. We raise Z[1] to the power of 3 to get Z[0], the "original" Z so
to speak. Take the 3 roots of Z[0] as R_0[0...2] and search it for Z[1].
We find that R_0[0] is equal to Z[1], index 0, and map L[2] to S[0].
Then we compare Z[0] to Z[0], fine that it is indeed equal, and quit.

Now, we have L[0...2] as "210". We reverse L to gain "012", and we have
the original stored data.

This is a very crude explanation, and the code can be much better, but
this is how I am doing it for now. I have some ideas on how to make it
much more efficient!

The storing and loading of symbols are the ct_store and ct_load
functions in my crude C++ code. The function that searches for roots in
the loading part is my ct_try_find function.
Post by Julio Di Egidio
but also with the problem indeed of how to handle the
unavoidable rounding errors: using "complex rationals" won't cut it, as
taking roots is irrational per se, but maybe suitable Z could do the trick,
at least in case there is an absolute maximum length for the strings... etc.
I should think more about it...
Yes: There is a definite limit wrt the amount of symbols we can store! I
am not really worried about that right now because this is, imvvho, a
fairly interesting and highly experimental way to store data. Its not
meant to be compression in any way shape or form, and its not meant to
be efficient. Actually, I am playing around with it as a toy form of
encryption.

I just wanted to get smarter eyes on my technique. Thank you for taking
a look Julio. I really do appreciate it.

:^D
Julio Di Egidio
2017-06-21 21:01:00 UTC
Reply
Permalink
Raw Message
<snip>
Post by Chris M. Thomasson
Post by Julio Di Egidio
There I have stopped, not only with the problem of finding a clever way for
the second function,
Here is how I am loading the symbols back from Z[3], or T in your example.
[...]
OK, that was clear and simple.
Post by Chris M. Thomasson
Yes: There is a definite limit wrt the amount of symbols we can store! I
am not really worried about that right now because this is, imvvho, a
fairly interesting and highly experimental way to store data. Its not
meant to be compression in any way shape or form, and its not meant to
be efficient. Actually, I am playing around with it as a toy form of
encryption.
But if it's not efficient (lossless or not), it is not really of interest:
IOW, for coding schemes, it is all about efficiency! (And I am not talking
about fine optimisation: the approach should at least be promising.)

In fact, there are really two separate levels of analysis:

- the "pure" approach with the mathematical complex numbers: there you have
a nice scheme that maps any (finite) string to one and only one complex
number: but the reason why it works, lossless and on strings of any length,
is because real numbers are infinite objects to begin with;

- the "feasible" approach with some effective numbers: here, to reiterate,
I do not think your approach can beat any of the known coding schemes, it's
in fact quite inefficient, while I still think a lossy version might be
worth investigating... -- You know, there may be clever ways to recover
exactness (*), still it won't be more efficient than the simplest binary
encoding of a string.

(*) Suitable Z might do some magic: for example, "on the complex plane
the nth roots of unity are at the vertices of a regular n-sided polygon
inscribed in the unit circle", which, if I am not mistaken, means we can
in fact use the rationals (pairs of integers) and, at least in the context
of arbitrary precision, we recover exact results. As said, it won't be
efficient though: the numbers involved will grow big with the strings.
<https://en.wikipedia.org/wiki/Root_of_unity#Group_of_nth_roots_of_unity>
Post by Chris M. Thomasson
I just wanted to get smarter eyes on my technique. Thank you for taking
a look Julio. I really do appreciate it.
You are very welcome, Chris, and thank you for sharing this interesting
problem.

Julio
Chris M. Thomasson
2017-06-22 18:28:45 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Post by Julio Di Egidio
There I have stopped, not only with the problem of finding a clever way for
the second function,
Here is how I am loading the symbols back from Z[3], or T in your example.
[...]
OK, that was clear and simple.
Post by Chris M. Thomasson
Yes: There is a definite limit wrt the amount of symbols we can store! I
am not really worried about that right now because this is, imvvho, a
fairly interesting and highly experimental way to store data. Its not
meant to be compression in any way shape or form, and its not meant to
be efficient. Actually, I am playing around with it as a toy form of
encryption.
IOW, for coding schemes, it is all about efficiency! (And I am not talking
about fine optimisation: the approach should at least be promising.)
The crappy efficiency isn't really a problem for me right now. I am
having fun experimenting with the technique. When I get some more time
sometime today or tomorrow, I will show you how it relates to Julia set
fractals in the form of z^n+c. When we store data in the roots of the
form of (z-c)^(1/n) and plot the complex numbers, the result is a nice
Julia set related to c: I personally find this aspect to be really
fascinating! Take a look at:

https://en.wikipedia.org/wiki/Julia_set#Using_backwards_.28inverse.29_iteration_.28IIM.29

We can use fractals to store information. All I did was figure out how
to store n-ary data in the tree of roots, and load them back up again.
If n is 2 we gain the power of 2 Julias wrt c, if we use n=5 we get
power of 5 Julias in the plot. Imvvho, that's pretty neat. I will show a
C99 program that stores data and outputs a PPM image to visually show
the plot.
Post by Julio Di Egidio
- the "pure" approach with the mathematical complex numbers: there you have
a nice scheme that maps any (finite) string to one and only one complex
number: but the reason why it works, lossless and on strings of any length,
is because real numbers are infinite objects to begin with;
Agreed. Well, if precision loss did not exist, we can store infinite
data in a single complex number. However, we do lose precision in the
real world of computing. So, what I just wrote is deep in the realm of
fantasy land. Arbitrary precision aside for a moment.
Post by Julio Di Egidio
- the "feasible" approach with some effective numbers: here, to reiterate,
I do not think your approach can beat any of the known coding schemes, it's
in fact quite inefficient, while I still think a lossy version might be
worth investigating... -- You know, there may be clever ways to recover
exactness (*), still it won't be more efficient than the simplest binary
encoding of a string.
Right. Afaict, its probably never going to be more efficient than say,
arithmetic coding. My method was never designed to compete with it. I
had fractals on my mind. Fwiw, I am sort of a fractal nerd, so to speak.

;^)
Post by Julio Di Egidio
(*) Suitable Z might do some magic: for example, "on the complex plane
the nth roots of unity are at the vertices of a regular n-sided polygon
inscribed in the unit circle", which, if I am not mistaken, means we can
in fact use the rationals (pairs of integers) and, at least in the context
of arbitrary precision, we recover exact results. As said, it won't be
efficient though: the numbers involved will grow big with the strings.
<https://en.wikipedia.org/wiki/Root_of_unity#Group_of_nth_roots_of_unity>
I think this will work for the first iteration with a magic Z. However,
the integers should break down into the decimal realm after more
iterations. Ahhh, you mentioned arbitrary precision. Well, then we can
store as much data in a single complex number as the memory on the
system we are using to compute the iteration allows.

I have experimented with arbitrary precision, and the complex numbers
get really, really huge depending on the length of the stored symbols.
However, they do gain exact precision when loading the stored data back.
Post by Julio Di Egidio
Post by Chris M. Thomasson
I just wanted to get smarter eyes on my technique. Thank you for taking
a look Julio. I really do appreciate it.
You are very welcome, Chris, and thank you for sharing this interesting
problem.
No problem. :^)

Thanks again.
Chris M. Thomasson
2017-06-22 19:10:45 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
<snip>
Post by Chris M. Thomasson
Post by Julio Di Egidio
There I have stopped, not only with the problem of finding a clever way for
the second function,
Here is how I am loading the symbols back from Z[3], or T in your example.
[...]
OK, that was clear and simple.
Post by Chris M. Thomasson
Yes: There is a definite limit wrt the amount of symbols we can store! I
am not really worried about that right now because this is, imvvho, a
fairly interesting and highly experimental way to store data. Its not
meant to be compression in any way shape or form, and its not meant to
be efficient. Actually, I am playing around with it as a toy form of
encryption.
IOW, for coding schemes, it is all about efficiency! (And I am not talking
about fine optimisation: the approach should at least be promising.)
[...]

Just one more point... Notice how I am comparing the Z[n] to the
original Z[0] during loading for sole purpose of termination of the
iterative process? Well, this can be turned into a block where we store
n-ary data as a fixed block, as in fixed number of iterations for
loading and storing. The error that arises wrt storing too much data can
be fixed wrt loading them back up. The error rate can be fixed. So,
instead of my load procedure loading up many errors because it cannot
find the end due to precision errors can be cut off at the fixed block
length. Its a limiting feature that turns it into a block cipher.

I am experimenting with this.
Julio Di Egidio
2017-06-23 13:07:24 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Right. Afaict, its probably never going to be more efficient than say,
arithmetic coding. My method was never designed to compete with it. I
had fractals on my mind. Fwiw, I am sort of a fractal nerd, so to speak.
I know that, I am a subscriber of yours on G+. :) I'll be looking
forward to those Julia sets, and I start seeing how you could use this
for cryptography. Indeed, I'll try your code and play with some code
myself, but next week, I'm totally busy till Monday...

Julio
Chris M. Thomasson
2017-06-23 17:37:36 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
Post by Chris M. Thomasson
Right. Afaict, its probably never going to be more efficient than say,
arithmetic coding. My method was never designed to compete with it. I
had fractals on my mind. Fwiw, I am sort of a fractal nerd, so to speak.
I know that, I am a subscriber of yours on G+. :) I'll be looking
forward to those Julia sets, and I start seeing how you could use this
for cryptography. Indeed, I'll try your code and play with some code
myself, but next week, I'm totally busy till Monday...
Fwiw, here is the start of the storm, wrt Richards comment, well, not
quite for I am still using complex numbers with real numbers as parts.
Gaining the base of a number in reverse order is just the beginning. As
you know, my complex loading procedure reverses the symbols anyway. So,
if I store n-ary data in reverse form, the load will reverse that
directly into correct form! Cool. Here is some initial code in my base
conversion C program, just part of my complex number fractal cipher PPM
plotter:
______________________________
#include <stdio.h>
#include <stdlib.h>

typedef signed long ct_int;
typedef unsigned long ct_uint;

#define CT_SYMBOLS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

/* converts v to base b using symbol table s in a block n.
the order is reversed, however the load will fix that...
__________________________________________________*/
void
ct_base_block(
ct_uint v,
ct_uint b,
char const* s,
ct_uint n
) {
ct_uint t = v;
size_t l = strlen(s);

for (ct_uint i = 0; i < n; ++i)
{
ct_uint d = t / b;
ct_uint r = t - d * b;
if (r > l)
{
printf("\nsymbol table size error!");
break;
}
printf("%c", s[r]);
//printf("%lu", r);
t = d;
}

printf("\n");
}


int main(int argc, char *argv[])
{
ct_base_block(999, 17, CT_SYMBOLS, 16);

return 0;
}
______________________________

The output is:
______________________________
D730000000000000
______________________________

And when we reverse this base 17 to:

000000000000037D

Well, its equal to 999 in base 10!

All of the zeros can add to the beauty of the fractal. Sometimes, they
will gain spirals, and other wonderful Julia set artifacts.

I am going to use ct_base_block to store a block of data in the fractal.
Each complex number will store one of these blocks. Now, this is in
reverse order. Fine for the loading of the block will reverse it for me
back into normal working order!

The symbol table is there just so we can see the damn things. This will
be directly embedded into the store procedure. Will have the plotter wrt
store/load in complex roots working today or tomorrow.

Yes, I know that this is a Friday, but this is so much fun!

;^)
Chris M. Thomasson
2017-06-23 17:49:51 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by Julio Di Egidio
Post by Chris M. Thomasson
Right. Afaict, its probably never going to be more efficient than say,
arithmetic coding. My method was never designed to compete with it. I
had fractals on my mind. Fwiw, I am sort of a fractal nerd, so to speak.
I know that, I am a subscriber of yours on G+. :) I'll be looking
forward to those Julia sets, and I start seeing how you could use this
for cryptography. Indeed, I'll try your code and play with some code
myself, but next week, I'm totally busy till Monday...
Fwiw, here is the start of the storm, wrt Richards comment, well, not
quite for I am still using complex numbers with real numbers as parts.
Gaining the base of a number in reverse order is just the beginning. As
you know, my complex loading procedure reverses the symbols anyway. So,
if I store n-ary data in reverse form, the load will reverse that
directly into correct form! Cool. Here is some initial code in my base
conversion C program, just part of my complex number fractal cipher PPM
______________________________
#include <stdio.h>
#include <stdlib.h>
typedef signed long ct_int;
typedef unsigned long ct_uint;
#define CT_SYMBOLS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
/* converts v to base b using symbol table s in a block n.
the order is reversed, however the load will fix that...
__________________________________________________*/
void
ct_base_block(
ct_uint v,
ct_uint b,
char const* s,
ct_uint n
) {
ct_uint t = v;
size_t l = strlen(s);
for (ct_uint i = 0; i < n; ++i)
{
ct_uint d = t / b;
ct_uint r = t - d * b;
if (r > l)
^^^^^^^^^^^^^^^^^^^^
[...]

Yikes! For some moronic reason, I forgot about the NULL in C strings.
The if condition in the code above should be:

if (r >= l)

ARGH! So sorry for the bugger!

Corrected function:
___________________________
ct_base_block(
ct_uint v,
ct_uint b,
char const* s,
ct_uint n
) {
ct_uint t = v;
size_t l = strlen(s);

for (ct_uint i = 0; i < n; ++i)
{
ct_uint d = t / b;
ct_uint r = t - d * b;
if (r >= l)
{
printf("\nsymbol table size error!");
break;
}
printf("%c", s[r]);
//printf("%lu", r);
t = d;
}

printf("\n");
}
___________________________

DAMN IT TO HECK! ;^o
Chris M. Thomasson
2017-06-23 18:07:39 UTC
Reply
Permalink
Raw Message
[...]

Fwiw, I am going to use my following PPM plotter for the graphics:

https://groups.google.com/d/topic/comp.lang.c/YnEcpH-vRxw/discussion

Output PPM is: ct_cipher_rifc.ppm

Here is the graphic rendered as a jpg:

Loading Image...

Imvvho, a decent visualization of a location in the Seahorse Valley
power of 2 Julia set. The spirals are there due to the drastic weight
differential wrt plotting random roots of (z-c)^(1/n).

C99 code:
_____________________________________
/* Chris M. Thomasson RIFC Renderer ver:0.0.0.0 (pre-alpha)
5/13/2017 - Raw Hyper Experimental
_________________________________________________*/

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <complex.h>
#include <tgmath.h>
#include <stdbool.h>


#define CT_RAND() (rand() / (RAND_MAX - 0.0))


struct ct_axes
{
double xmin;
double xmax;
double ymin;
double ymax;
};


struct ct_canvas
{
unsigned long width;
unsigned long height;
unsigned char* buf;
};

bool
ct_canvas_create(
struct ct_canvas* const self,
unsigned long width,
unsigned long height
){
size_t size = width * height;

self->buf = calloc(1, size);

if (self->buf)
{
self->width = width;
self->height = height;

return true;
}

return false;
}

void
ct_canvas_destroy(
struct ct_canvas const* const self
){
free(self->buf);
}

bool
ct_canvas_save_ppm(
struct ct_canvas const* const self,
char const* fname
){
FILE* fout = fopen(fname, "w");

if (fout)
{
char const ppm_head[] =
"P3\n"
"# Chris M. Thomasson RIFC Cipher Renderer ver:0.0.0.0
(pre-alpha)";

fprintf(fout, "%s\n%lu %lu\n%u\n",
ppm_head,
self->width, self->height,
255U);

size_t size = self->width * self->height;

for (size_t i = 0; i < size; ++i)
{
unsigned int c = self->buf[i];
fprintf(fout, "%u %u %u ", c, 0U, 0U);
}

if (! fclose(fout))
{
return true;
}
}

return false;
}


struct ct_plane
{
struct ct_axes axes;
struct ct_canvas* canvas;
};

size_t
ct_plane_project(
struct ct_plane const* const self,
double complex c
){
double awidth = self->axes.xmax - self->axes.xmin;
double aheight = self->axes.ymax - self->axes.ymin;

double xstep = awidth / (self->canvas->width - 1.0);
double ystep = aheight / (self->canvas->height - 1.0);

size_t x = (creal(c) - self->axes.xmin) / xstep;
size_t y = (self->axes.ymax - cimag(c)) / ystep;

size_t i = x + y * self->canvas->height;

return i;
}

bool
ct_plane_plot(
struct ct_plane* const self,
double complex c,
unsigned char color
){
size_t cp = ct_plane_project(self, c);

if (cp < self->canvas->height * self->canvas->width)
{
self->canvas->buf[cp] = color;
return true;
}

return false;
}


void
ct_ifs(
struct ct_plane* const self,
double complex z,
double complex c,
double ratio,
unsigned long n
){
printf("ct_ifs: %lf%+lfi, ratio:%lf\n", creal(c), cimag(c), ratio);

for (unsigned long i = 0; i < n; ++i)
{
double complex d = z - c;
double complex root = csqrt(d);

z = root;

if (CT_RAND() > ratio)
{
z = -root;
}

ct_plane_plot(self, z, 255);
ct_plane_plot(self, root, 255);

if (! (i % 256))
{
printf("rendering: %lu of %lu\r", i + 1, n);
}
}

printf("rendering: %lu of %lu\n", n, n);
}


#define CT_WIDTH 1024
#define CT_HEIGHT 1024
#define CT_N 10000000

int main(void)
{
struct ct_canvas canvas;

bool status = ct_canvas_create(&canvas, CT_WIDTH, CT_HEIGHT);
assert(status);

struct ct_axes axes = { -2.0, 2.0, -2.0, 2.0 };
struct ct_plane plane = { axes, &canvas };

double complex z = 0+0*I;
//double complex c = -.75+.06*I;
double complex c = -.75+.06*I;
double ratio = .04;

ct_ifs(&plane, z, c, ratio, CT_N);

status = ct_canvas_save_ppm(&canvas, "ct_cipher_rifc.ppm");
assert(status);
printf("\ncreated: ct_cipher_rifc.ppm\n");

ct_canvas_destroy(&canvas);

return 0;
}
_____________________________________
FromTheRafters
2017-06-24 13:01:58 UTC
Reply
Permalink
Raw Message
Post by Julio Di Egidio
Post by Chris M. Thomasson
Right. Afaict, its probably never going to be more efficient than say,
arithmetic coding. My method was never designed to compete with it. I
had fractals on my mind. Fwiw, I am sort of a fractal nerd, so to speak.
I know that, I am a subscriber of yours on G+. :) I'll be looking
forward to those Julia sets, and I start seeing how you could use this
for cryptography. Indeed, I'll try your code and play with some code
myself, but next week, I'm totally busy till Monday...
Fwiw, here is the start of the storm, wrt Richards comment, well, not quite
for I am still using complex numbers with real numbers as parts. Gaining the
base of a number in reverse order is just the beginning. As you know, my
complex loading procedure reverses the symbols anyway. So, if I store n-ary
data in reverse form, the load will reverse that directly into correct form!
Cool. Here is some initial code in my base conversion C program, just part of
______________________________
#include <stdio.h>
#include <stdlib.h>
typedef signed long ct_int;
typedef unsigned long ct_uint;
#define CT_SYMBOLS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
/* converts v to base b using symbol table s in a block n.
the order is reversed, however the load will fix that...
__________________________________________________*/
void
ct_base_block(
ct_uint v,
ct_uint b,
char const* s,
ct_uint n
) {
ct_uint t = v;
size_t l = strlen(s);
for (ct_uint i = 0; i < n; ++i)
{
ct_uint d = t / b;
ct_uint r = t - d * b;
if (r > l)
{
printf("\nsymbol table size error!");
break;
}
printf("%c", s[r]);
//printf("%lu", r);
t = d;
}
printf("\n");
}
int main(int argc, char *argv[])
{
ct_base_block(999, 17, CT_SYMBOLS, 16);
return 0;
}
______________________________
______________________________
D730000000000000
______________________________
000000000000037D
Well, its equal to 999 in base 10!
All of the zeros can add to the beauty of the fractal. Sometimes, they will
gain spirals, and other wonderful Julia set artifacts.
It could be that that very beauty is bad for the crypto aspect.
I am going to use ct_base_block to store a block of data in the fractal. Each
complex number will store one of these blocks. Now, this is in reverse order.
Fine for the loading of the block will reverse it for me back into normal
working order!
The symbol table is there just so we can see the damn things. This will be
directly embedded into the store procedure. Will have the plotter wrt
store/load in complex roots working today or tomorrow.
Yes, I know that this is a Friday, but this is so much fun!
;^)
https://en.wikipedia.org/wiki/Heptadecagon
Chris M. Thomasson
2017-06-24 16:41:17 UTC
Reply
Permalink
Raw Message
Post by FromTheRafters
Post by Chris M. Thomasson
Post by Julio Di Egidio
Post by Chris M. Thomasson
Right. Afaict, its probably never going to be more efficient than say,
arithmetic coding. My method was never designed to compete with it. I
had fractals on my mind. Fwiw, I am sort of a fractal nerd, so to speak.
I know that, I am a subscriber of yours on G+. :) I'll be looking
forward to those Julia sets, and I start seeing how you could use this
for cryptography. Indeed, I'll try your code and play with some code
myself, but next week, I'm totally busy till Monday...
Fwiw, here is the start of the storm, wrt Richards comment, well, not
quite for I am still using complex numbers with real numbers as parts.
Gaining the base of a number in reverse order is just the beginning.
As you know, my complex loading procedure reverses the symbols anyway.
So, if I store n-ary data in reverse form, the load will reverse that
directly into correct form! Cool. Here is some initial code in my base
conversion C program, just part of my complex number fractal cipher
______________________________
#include <stdio.h>
#include <stdlib.h>
typedef signed long ct_int;
typedef unsigned long ct_uint;
#define CT_SYMBOLS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
/* converts v to base b using symbol table s in a block n.
the order is reversed, however the load will fix that...
__________________________________________________*/
void
ct_base_block(
ct_uint v,
ct_uint b,
char const* s,
ct_uint n
) {
ct_uint t = v;
size_t l = strlen(s);
for (ct_uint i = 0; i < n; ++i)
{
ct_uint d = t / b;
ct_uint r = t - d * b;
if (r > l)
{
printf("\nsymbol table size error!");
break;
}
printf("%c", s[r]);
//printf("%lu", r);
t = d;
}
printf("\n");
}
int main(int argc, char *argv[])
{
ct_base_block(999, 17, CT_SYMBOLS, 16);
return 0;
}
______________________________
______________________________
D730000000000000
______________________________
000000000000037D
Well, its equal to 999 in base 10!
All of the zeros can add to the beauty of the fractal. Sometimes, they
will gain spirals, and other wonderful Julia set artifacts.
It could be that that very beauty is bad for the crypto aspect.
Yes, that is a problem. Wrt z^n+c, lets say that the initial z, the
power n and c are part of the secret key. Now, Eve can look at the
fractal and guess at n and c. Not good. However, there is a way to hide
the fractal by using a random z, n and c for the last couple of
iterations when storing data. This ends up making strange fractals that
end up hiding the secret key. They look nothing like the secret key.
Post by FromTheRafters
Post by Chris M. Thomasson
I am going to use ct_base_block to store a block of data in the
fractal. Each complex number will store one of these blocks. Now, this
is in reverse order. Fine for the loading of the block will reverse it
for me back into normal working order!
The symbol table is there just so we can see the damn things. This
will be directly embedded into the store procedure. Will have the
plotter wrt store/load in complex roots working today or tomorrow.
Yes, I know that this is a Friday, but this is so much fun!
;^)
https://en.wikipedia.org/wiki/Heptadecagon
Nice. Humm... Wrt to z^n, one of these should pop out if I use a power
of 17. Each root would be on the Heptadecagon.
Chris M. Thomasson
2017-06-25 00:14:29 UTC
Reply
Permalink
Raw Message
[...]
Post by FromTheRafters
https://en.wikipedia.org/wiki/Heptadecagon
Okay. I am learning about the roots of unity wrt magic values of z. Here
is a program that produces roots of unity for any given power. Its
hardcoded to gain a 17-gon such that each number when raised to the
17'th power gains the number 1. Well, 1 in the sense of real part 1,
imag part zero. Floating point issues aside for a moment. Here is the
C99 code:
______________________________
#include <stdio.h>
#include <math.h>
#include <complex.h>

#define CT_PI 3.1415926535897932384626433832795
#define CT_PI2 6.283185307179586476925286766559

typedef double ct_real;
typedef double complex ct_complex;

ct_complex
ct_root(
ct_complex const z,
int p,
unsigned int r
){
ct_real radius = cpow(cabs(z), 1.0 / p);

ct_real angle_base = carg(z) / p;
ct_real angle_step = CT_PI2 / p;
ct_real angle = angle_base + angle_step * r;

ct_complex root = cos(angle) * radius + sin(angle) * radius * I;

return root;
}

int main(void)
{
// unity root, real part 1, imaginary part zero.
ct_complex z = 1+0*I;
printf("s:(%lf%+lfi)\n", creal(z), cimag(z));

unsigned int p = 17; // the number of roots

printf("\nRoots of Unity Power: %u\n", p);
printf("__________________________________\n");
for (unsigned int i = 0; i < p; ++i)
{
ct_complex r = ct_root(z, p, i);
ct_complex raised = cpow(r, p);

printf("r[%u]:(%lf%+lfi) raised = (%lf+%lfi)\n",
i,
creal(r), cimag(r),
creal(raised), cimag(raised)
);
}
printf("__________________________________\n");

return 0;
}
______________________________


It outputs the following text:
***************************************
s:(1.000000+0.000000i)

Roots of Unity Power: 17
__________________________________
r[0]:(1.000000+0.000000i) raised = (1.000000+0.000000i)
r[1]:(0.932472+0.361242i) raised = (1.000000+-0.000000i)
r[2]:(0.739009+0.673696i) raised = (1.000000+-0.000000i)
r[3]:(0.445738+0.895163i) raised = (1.000000+-0.000000i)
r[4]:(0.092268+0.995734i) raised = (1.000000+-0.000000i)
r[5]:(-0.273663+0.961826i) raised = (1.000000+-0.000000i)
r[6]:(-0.602635+0.798017i) raised = (1.000000+-0.000000i)
r[7]:(-0.850217+0.526432i) raised = (1.000000+0.000000i)
r[8]:(-0.982973+0.183750i) raised = (1.000000+-0.000000i)
r[9]:(-0.982973-0.183750i) raised = (1.000000+-0.000000i)
r[10]:(-0.850217-0.526432i) raised = (1.000000+-0.000000i)
r[11]:(-0.602635-0.798017i) raised = (1.000000+-0.000000i)
r[12]:(-0.273663-0.961826i) raised = (1.000000+-0.000000i)
r[13]:(0.092268-0.995734i) raised = (1.000000+-0.000000i)
r[14]:(0.445738-0.895163i) raised = (1.000000+0.000000i)
r[15]:(0.739009-0.673696i) raised = (1.000000+0.000000i)
r[16]:(0.932472-0.361242i) raised = (1.000000+-0.000000i)
__________________________________
***************************************


Each root r[0...16] wrt power of 17 gains (1, 0) when raised up to the
power of 17.


Can you run it? Its C99... Wow! Love to learn.
Chris M. Thomasson
2017-06-25 01:08:30 UTC
Reply
Permalink
Raw Message
[...]
Post by FromTheRafters
https://en.wikipedia.org/wiki/Heptadecagon
[...]

YIKES! I have an extra % in the printf on line 43 in the original code.

Fwiw, one can set the power by altering line 34. The hardcoded line 34 is:

unsigned int p = 103; // the number of roots

Fwiw, here is fixed code wrt the extra % that shows a 103-gon:
______________
#include <stdio.h>
#include <math.h>
#include <complex.h>

#define CT_PI 3.1415926535897932384626433832795
#define CT_PI2 6.283185307179586476925286766559

typedef double ct_real;
typedef double complex ct_complex;

ct_complex
ct_root(
ct_complex const z,
int p,
unsigned int r
){
ct_real radius = cpow(cabs(z), 1.0 / p);

ct_real angle_base = carg(z) / p;
ct_real angle_step = CT_PI2 / p;
ct_real angle = angle_base + angle_step * r;

ct_complex root = cos(angle) * radius + sin(angle) * radius * I;

return root;
}

int main(void)
{
// unity root, real part 1, imaginary part zero.
ct_complex z = 1+0*I;
printf("s:(%lf, %lf)\n", creal(z), cimag(z));

unsigned int p = 103; // the number of roots

printf("\nRoots of Unity Power: %u\n", p);
printf("__________________________________\n");
for (unsigned int i = 0; i < p; ++i)
{
ct_complex r = ct_root(z, p, i);
ct_complex raised = cpow(r, p);

printf("r[%u]:(%lf, %lf) raised = (%lf, %lf)\n",
i,
creal(r), cimag(r),
creal(raised), cimag(raised)
);
}
printf("__________________________________\n");

return 0;
}
______________

Sorry about that!
Chris M. Thomasson
2017-06-25 06:21:18 UTC
Reply
Permalink
Raw Message
[...]
Post by Chris M. Thomasson
The symbol table is there just so we can see the damn things. This will
be directly embedded into the store procedure. Will have the plotter wrt
store/load in complex roots working today or tomorrow.
This is going to take a little more time than I thought. Please try to
cut me some slack. ;^o

richard miller
2017-06-21 21:05:26 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?

It is much better (easier, faster computation etc.) using integer unity (or primitive) roots, i.e. integers that satisfy

x^n == 1 (mod p)

Very briefly, for instance, for prime base p, p = 2.n.l + 1, for some integer l, odd n, you will get n such roots with a lovely integer value. Even exponents are also possible, see Legendre's theorem.

E.g. n=3, p=7, x={1,2,4}

1^3 == 1 (mod 7)
2^3 == 1 (mod 7)
4^3 == 1 (mod 7)

The roots form a cyclic group, prime p, single generator, here '2', i.e.
the three roots are 2^0=1, 2^1=2, 2^2=4.

These are isomorphic to the cubic roots of unity, i.e. 1~e^i.0, 2~e^i.2.pi/3, 4~e^i.4.pi/3.

You can do everything you want in integers, plus p can also be arbitrary, composite, so long as it has prime factors of the requisite form (you will then get more roots than n).

There is some free stuff on unity roots at http://www.urmt.org, otherwise just search the web 'primitive roots', 'Legendre's theorem'

This reply is very terse, and I could give more info. Request it by email to the address given at the below web-site if required.

In short, if you can do it in complex numbers of r.[cos(theta) + i.sin(theta)] form, you can do it in integers

Richard Miller
http://www.urmt.org
Chris M. Thomasson
2017-06-22 18:41:40 UTC
Reply
Permalink
Raw Message
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
Well, I need to use them in order to plot Julia sets that have the
stored data contained within them. Think of:

https://en.wikipedia.org/wiki/Julia_set#Using_backwards_.28inverse.29_iteration_.28IIM.29
Post by richard miller
It is much better (easier, faster computation etc.) using integer unity (or primitive) roots, i.e. integers that satisfy
x^n == 1 (mod p)
Very briefly, for instance, for prime base p, p = 2.n.l + 1, for some integer l, odd n, you will get n such roots with a lovely integer value. Even exponents are also possible, see Legendre's theorem.
E.g. n=3, p=7, x={1,2,4}
1^3 == 1 (mod 7)
2^3 == 1 (mod 7)
4^3 == 1 (mod 7)
The roots form a cyclic group, prime p, single generator, here '2', i.e.
the three roots are 2^0=1, 2^1=2, 2^2=4.
Please try to forgive my ignorance here Richard, but I am having trouble
seeing how this can work in my iterative scheme. I am thinking I would
have to choose a prime base that is large enough to store the data. In
the sense that the loading iteration can recover it wrt giving me a big
enough cyclic group that would allow for both the storing and loading
process. My loading process in a small group might give me false
positives? Hummm.... Need to think!
Post by richard miller
These are isomorphic to the cubic roots of unity, i.e. 1~e^i.0, 2~e^i.2.pi/3, 4~e^i.4.pi/3.
You can do everything you want in integers, plus p can also be arbitrary, composite, so long as it has prime factors of the requisite form (you will then get more roots than n).
There is some free stuff on unity roots at http://www.urmt.org, otherwise just search the web 'primitive roots', 'Legendre's theorem'
This reply is very terse, and I could give more info. Request it by email to the address given at the below web-site if required.
In short, if you can do it in complex numbers of r.[cos(theta) + i.sin(theta)] form, you can do it in integers
Wrt Diffie-Hellman, check this out:

https://groups.google.com/d/msg/sci.crypt/CIUkq58Xe_4/seELFfkSAgAJ

When using non-compatible inputs, the keyspace for Diffie-Hellman
drastically decreases. I am thinking that after a couple of iterations,
this problem will show it face.

Thank you for the excellent comment Richard.
richard miller
2017-06-22 19:29:22 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
Well, I need to use them in order to plot Julia sets that have the
OK, see my next point
Post by Chris M. Thomasson
Post by richard miller
In short, if you can do it in complex numbers of r.[cos(theta) + i.sin(theta)] form, you can do it in integers
Slightly flippant of me, I meant if you can do it with the complex roots of unity, you can do it with integer, primitive roots...

Unity roots pervade maths and mathematical physics. Whilst you are working on cryptography, I'm also currently working on some other industrial application at the mo involving replacing complex unity roots with integers - it is working very nicely (and very fast), which is why I posted a reply to you in the thought that you may also benefit. I will try and read a bit more of your stuff and links.

The primitive roots are basically isomorphic, group-wise, to the complex roots of unity. As regards a large prime-base, I will have to think on this and properly read your stuff. but large number arithmetic is de-rigeur in computational number theory, no base too big - thousand digits to one million plus...
Post by Chris M. Thomasson
https://groups.google.com/d/msg/sci.crypt/CIUkq58Xe_4/seELFfkSAgAJ
I haven't checked this out yet, but I will.

Good luck for now, will try and expend some effort over the next few days...

Richard M.
http://www.urmt.org
Chris M. Thomasson
2017-06-23 01:46:13 UTC
Reply
Permalink
Raw Message
Post by richard miller
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
Well, I need to use them in order to plot Julia sets that have the
OK, see my next point
Post by Chris M. Thomasson
Post by richard miller
In short, if you can do it in complex numbers of r.[cos(theta) + i.sin(theta)] form, you can do it in integers
Slightly flippant of me, I meant if you can do it with the complex roots of unity, you can do it with integer, primitive roots...
I need to calm down and think. If I gain the roots of a number, and use
that number for the next set of roots, how can this next root under
iteration be used with the same cyclic group that gained the first
iteration? The group would start to get smaller and smaller. Sorry for
my brainstorming here.
Post by richard miller
Unity roots pervade maths and mathematical physics. Whilst you are working on cryptography, I'm also currently working on some other industrial application at the mo involving replacing complex unity roots with integers - it is working very nicely (and very fast), which is why I posted a reply to you in the thought that you may also benefit. I will try and read a bit more of your stuff and links.
The primitive roots are basically isomorphic, group-wise, to the complex roots of unity. As regards a large prime-base, I will have to think on this and properly read your stuff. but large number arithmetic is de-rigeur in computational number theory, no base too big - thousand digits to one million plus...
Post by Chris M. Thomasson
https://groups.google.com/d/msg/sci.crypt/CIUkq58Xe_4/seELFfkSAgAJ
I haven't checked this out yet, but I will.
Good luck for now, will try and expend some effort over the next few days...
Richard M.
http://www.urmt.org
richard miller
2017-06-23 16:41:30 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
Well, I need to use them in order to plot Julia sets that have the
OK, see my next point
Post by Chris M. Thomasson
Post by richard miller
In short, if you can do it in complex numbers of r.[cos(theta) + i.sin(theta)] form, you can do it in integers
Slightly flippant of me, I meant if you can do it with the complex roots of unity, you can do it with integer, primitive roots...
I need to calm down and think. If I gain the roots of a number, and use
that number for the next set of roots, how can this next root under
iteration be used with the same cyclic group that gained the first
iteration? The group would start to get smaller and smaller. Sorry for
my brainstorming here.
That is likely so, but, right now, it works for me for my application and permits recursive calls.

Hopefully this is your 'calm before the storm' (a storm of your new ideas that is)

For now, some thought required.
Post by Chris M. Thomasson
Post by richard miller
Richard M.
http://www.urmt.org
Chris M. Thomasson
2017-06-23 17:43:58 UTC
Reply
Permalink
Raw Message
Post by richard miller
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
Well, I need to use them in order to plot Julia sets that have the
OK, see my next point
Post by Chris M. Thomasson
Post by richard miller
In short, if you can do it in complex numbers of r.[cos(theta) + i.sin(theta)] form, you can do it in integers
Slightly flippant of me, I meant if you can do it with the complex roots of unity, you can do it with integer, primitive roots...
I need to calm down and think. If I gain the roots of a number, and use
that number for the next set of roots, how can this next root under
iteration be used with the same cyclic group that gained the first
iteration? The group would start to get smaller and smaller. Sorry for
my brainstorming here.
That is likely so, but, right now, it works for me for my application and permits recursive calls.
WOW! Okay... Need to calm down again... Can you possibly get my
technique to perform any sort of compression? The integer realm seems
most promising Richard. Fwiw, I can do it in the real number realm if
and _only_ if the stored symbols follow certain patterns. Wrt binary
encoding, a lot of zeros and ones in a row can be exploited, and
compressed: The compression ratio is not that good at all, but it can
work...
Post by richard miller
Hopefully this is your 'calm before the storm' (a storm of your new ideas that is)
For now, some thought required.
Thank you so much for your time and energy: This is perfect for its the
reason why I posted it here in the first place Richard! Need smarter
people looking at the damn thing!

:^D
richard miller
2017-06-23 18:12:32 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
Well, I need to use them in order to plot Julia sets that have the
... an espilon of snippagio
Post by Chris M. Thomasson
Post by richard miller
Hopefully this is your 'calm before the storm' (a storm of your new ideas that is)
For now, some thought required.
Thank you so much for your time and energy: This is perfect for its the
reason why I posted it here in the first place Richard! Need smarter
people looking at the damn thing!
:^D
I aint that smart, but... thanks, and you have a good concept and I will take a look over the next few days.

To a wider audience, I hope this gives you some faith in sci.math as a completely uncensored environment. There are a lot of cranks here, but at least they make us think . One has to be able to reason.

Back to thought on your matter...

Richard M.
Chris M. Thomasson
2017-06-23 18:54:38 UTC
Reply
Permalink
Raw Message
Post by richard miller
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
Well, I need to use them in order to plot Julia sets that have the
... an espilon of snippagio
Post by Chris M. Thomasson
Post by richard miller
Hopefully this is your 'calm before the storm' (a storm of your new ideas that is)
For now, some thought required.
Thank you so much for your time and energy: This is perfect for its the
reason why I posted it here in the first place Richard! Need smarter
people looking at the damn thing!
:^D
I aint that smart, but... thanks, and you have a good concept and I will take > a look over the next few days.
Thank you so much for the very kind comment.
Post by richard miller
To a wider audience, I hope this gives you some faith in sci.math as a completely
uncensored environment. There are a lot of cranks here, but at least they make us
think . One has to be able to reason.
I have to admit that some of the cranky trolls make me think as well. :^)
Post by richard miller
Back to thought on your matter...
Perfect for that is the main goal!

:^D
Chris M. Thomasson
2017-06-25 00:20:32 UTC
Reply
Permalink
Raw Message
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
[...]

Please excuse my ignorance, again... But getting better at gaining roots
of unity. Take a look at the following c99 program I created:

https://groups.google.com/d/msg/sci.math/fZBCdVwvHGQ/DOjmsGB7AQAJ

It gives output as:

s:(1.000000+0.000000i)

Roots of Unity Power: 17
__________________________________
r[0]:(1.000000+0.000000i) raised = (1.000000+0.000000i)
r[1]:(0.932472+0.361242i) raised = (1.000000+-0.000000i)
r[2]:(0.739009+0.673696i) raised = (1.000000+-0.000000i)
r[3]:(0.445738+0.895163i) raised = (1.000000+-0.000000i)
r[4]:(0.092268+0.995734i) raised = (1.000000+-0.000000i)
r[5]:(-0.273663+0.961826i) raised = (1.000000+-0.000000i)
r[6]:(-0.602635+0.798017i) raised = (1.000000+-0.000000i)
r[7]:(-0.850217+0.526432i) raised = (1.000000+0.000000i)
r[8]:(-0.982973+0.183750i) raised = (1.000000+-0.000000i)
r[9]:(-0.982973-0.183750i) raised = (1.000000+-0.000000i)
r[10]:(-0.850217-0.526432i) raised = (1.000000+-0.000000i)
r[11]:(-0.602635-0.798017i) raised = (1.000000+-0.000000i)
r[12]:(-0.273663-0.961826i) raised = (1.000000+-0.000000i)
r[13]:(0.092268-0.995734i) raised = (1.000000+-0.000000i)
r[14]:(0.445738-0.895163i) raised = (1.000000+0.000000i)
r[15]:(0.739009-0.673696i) raised = (1.000000+0.000000i)
r[16]:(0.932472-0.361242i) raised = (1.000000+-0.000000i)
__________________________________


Each point raised gives 1.... Nice!

BTW, thank you so much for taking the time to help make me smarter!

Well, before I get too happy, notice the +- in there? Even though its
correct, I need to fix that in the output wrt the program. Well, shit.
Its my call to printf damn it!

Please, try to have some patience with me Richard!

;^o
Chris M. Thomasson
2017-06-25 00:30:58 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
[...]
Please excuse my ignorance, again... But getting better at gaining roots
https://groups.google.com/d/msg/sci.math/fZBCdVwvHGQ/DOjmsGB7AQAJ
[...]
Post by Chris M. Thomasson
Each point raised gives 1.... Nice!
BTW, thank you so much for taking the time to help make me smarter!
Well, before I get too happy, notice the +- in there? Even though its
correct, I need to fix that in the output wrt the program. Well, shit.
Its my call to printf damn it!
Please, try to have some patience with me Richard!
Fixed my output. Here are the roots of unity for the 103-gon:

s:(1.000000, 0.000000)

Roots of Unity Power: 103
__________________________________
r[0]:(1.000000, 0.000000) raised = (1.000000, 0.000000)
r[1]:(0.998140, 0.060964) raised = (1.000000, -0.000000)
r[2]:(0.992567, 0.121701) raised = (1.000000, -0.000000)
r[3]:(0.983301, 0.181986) raised = (1.000000, -0.000000)
r[4]:(0.970378, 0.241593) raised = (1.000000, -0.000000)
r[5]:(0.953844, 0.300302) raised = (1.000000, -0.000000)
r[6]:(0.933762, 0.357893) raised = (1.000000, -0.000000)
r[7]:(0.910207, 0.414153) raised = (1.000000, -0.000000)
r[8]:(0.883266, 0.468873) raised = (1.000000, -0.000000)
r[9]:(0.853038, 0.521848) raised = (1.000000, -0.000000)
r[10]:(0.819638, 0.572882) raised = (1.000000, -0.000000)
r[11]:(0.783188, 0.621785) raised = (1.000000, 0.000000)
r[12]:(0.743825, 0.668375) raised = (1.000000, -0.000000)
r[13]:(0.701694, 0.712478) raised = (1.000000, -0.000000)
r[14]:(0.656954, 0.753931) raised = (1.000000, -0.000000)
r[15]:(0.609769, 0.792579) raised = (1.000000, -0.000000)
r[16]:(0.560316, 0.828279) raised = (1.000000, -0.000000)
r[17]:(0.508779, 0.860897) raised = (1.000000, -0.000000)
r[18]:(0.455349, 0.890313) raised = (1.000000, -0.000000)
r[19]:(0.400225, 0.916417) raised = (1.000000, -0.000000)
r[20]:(0.343612, 0.939112) raised = (1.000000, -0.000000)
r[21]:(0.285721, 0.958313) raised = (1.000000, 0.000000)
r[22]:(0.226767, 0.973949) raised = (1.000000, 0.000000)
r[23]:(0.166969, 0.985962) raised = (1.000000, -0.000000)
r[24]:(0.106550, 0.994307) raised = (1.000000, -0.000000)
r[25]:(0.045735, 0.998954) raised = (1.000000, -0.000000)
r[26]:(-0.015250, 0.999884) raised = (1.000000, -0.000000)
r[27]:(-0.076178, 0.997094) raised = (1.000000, -0.000000)
r[28]:(-0.136824, 0.990595) raised = (1.000000, -0.000000)
r[29]:(-0.196960, 0.980412) raised = (1.000000, -0.000000)
r[30]:(-0.256363, 0.966581) raised = (1.000000, -0.000000)
r[31]:(-0.314813, 0.949154) raised = (1.000000, -0.000000)
r[32]:(-0.372091, 0.928196) raised = (1.000000, -0.000000)
r[33]:(-0.427986, 0.903785) raised = (1.000000, -0.000000)
r[34]:(-0.482288, 0.876013) raised = (1.000000, -0.000000)
r[35]:(-0.534796, 0.844981) raised = (1.000000, -0.000000)
r[36]:(-0.585315, 0.810806) raised = (1.000000, -0.000000)
r[37]:(-0.633656, 0.773615) raised = (1.000000, -0.000000)
r[38]:(-0.679640, 0.733546) raised = (1.000000, -0.000000)
r[39]:(-0.723096, 0.690748) raised = (1.000000, -0.000000)
r[40]:(-0.763862, 0.645380) raised = (1.000000, -0.000000)
r[41]:(-0.801786, 0.597612) raised = (1.000000, -0.000000)
r[42]:(-0.836727, 0.547620) raised = (1.000000, 0.000000)
r[43]:(-0.868556, 0.495591) raised = (1.000000, -0.000000)
r[44]:(-0.897154, 0.441719) raised = (1.000000, 0.000000)
r[45]:(-0.922414, 0.386203) raised = (1.000000, -0.000000)
r[46]:(-0.944243, 0.329251) raised = (1.000000, -0.000000)
r[47]:(-0.962559, 0.271073) raised = (1.000000, 0.000000)
r[48]:(-0.977294, 0.211888) raised = (1.000000, -0.000000)
r[49]:(-0.988394, 0.151914) raised = (1.000000, -0.000000)
r[50]:(-0.995817, 0.091375) raised = (1.000000, -0.000000)
r[51]:(-0.999535, 0.030496) raised = (1.000000, -0.000000)
r[52]:(-0.999535, -0.030496) raised = (1.000000, -0.000000)
r[53]:(-0.995817, -0.091375) raised = (1.000000, -0.000000)
r[54]:(-0.988394, -0.151914) raised = (1.000000, -0.000000)
r[55]:(-0.977294, -0.211888) raised = (1.000000, -0.000000)
r[56]:(-0.962559, -0.271073) raised = (1.000000, -0.000000)
r[57]:(-0.944243, -0.329251) raised = (1.000000, -0.000000)
r[58]:(-0.922414, -0.386203) raised = (1.000000, -0.000000)
r[59]:(-0.897154, -0.441719) raised = (1.000000, -0.000000)
r[60]:(-0.868556, -0.495591) raised = (1.000000, -0.000000)
r[61]:(-0.836727, -0.547620) raised = (1.000000, -0.000000)
r[62]:(-0.801786, -0.597612) raised = (1.000000, -0.000000)
r[63]:(-0.763862, -0.645380) raised = (1.000000, -0.000000)
r[64]:(-0.723096, -0.690748) raised = (1.000000, -0.000000)
r[65]:(-0.679640, -0.733546) raised = (1.000000, -0.000000)
r[66]:(-0.633656, -0.773615) raised = (1.000000, -0.000000)
r[67]:(-0.585315, -0.810806) raised = (1.000000, -0.000000)
r[68]:(-0.534796, -0.844981) raised = (1.000000, -0.000000)
r[69]:(-0.482288, -0.876013) raised = (1.000000, -0.000000)
r[70]:(-0.427986, -0.903785) raised = (1.000000, -0.000000)
r[71]:(-0.372091, -0.928196) raised = (1.000000, -0.000000)
r[72]:(-0.314813, -0.949154) raised = (1.000000, -0.000000)
r[73]:(-0.256363, -0.966581) raised = (1.000000, -0.000000)
r[74]:(-0.196960, -0.980412) raised = (1.000000, -0.000000)
r[75]:(-0.136824, -0.990595) raised = (1.000000, -0.000000)
r[76]:(-0.076178, -0.997094) raised = (1.000000, -0.000000)
r[77]:(-0.015250, -0.999884) raised = (1.000000, -0.000000)
r[78]:(0.045735, -0.998954) raised = (1.000000, -0.000000)
r[79]:(0.106550, -0.994307) raised = (1.000000, 0.000000)
r[80]:(0.166969, -0.985962) raised = (1.000000, -0.000000)
r[81]:(0.226767, -0.973949) raised = (1.000000, -0.000000)
r[82]:(0.285721, -0.958313) raised = (1.000000, -0.000000)
r[83]:(0.343612, -0.939112) raised = (1.000000, 0.000000)
r[84]:(0.400225, -0.916417) raised = (1.000000, -0.000000)
r[85]:(0.455349, -0.890313) raised = (1.000000, -0.000000)
r[86]:(0.508779, -0.860897) raised = (1.000000, -0.000000)
r[87]:(0.560316, -0.828279) raised = (1.000000, -0.000000)
r[88]:(0.609769, -0.792579) raised = (1.000000, -0.000000)
r[89]:(0.656954, -0.753931) raised = (1.000000, -0.000000)
r[90]:(0.701694, -0.712478) raised = (1.000000, -0.000000)
r[91]:(0.743825, -0.668375) raised = (1.000000, -0.000000)
r[92]:(0.783188, -0.621785) raised = (1.000000, -0.000000)
r[93]:(0.819638, -0.572882) raised = (1.000000, -0.000000)
r[94]:(0.853038, -0.521848) raised = (1.000000, -0.000000)
r[95]:(0.883266, -0.468873) raised = (1.000000, -0.000000)
r[96]:(0.910207, -0.414153) raised = (1.000000, -0.000000)
r[97]:(0.933762, -0.357893) raised = (1.000000, -0.000000)
r[98]:(0.953844, -0.300302) raised = (1.000000, -0.000000)
r[99]:(0.970378, -0.241593) raised = (1.000000, -0.000000)
r[100]:(0.983301, -0.181986) raised = (1.000000, -0.000000)
r[101]:(0.992567, -0.121701) raised = (1.000000, -0.000000)
r[102]:(0.998140, -0.060964) raised = (1.000000, -0.000000)
__________________________________


I just made my call to printf output complex numbers as:

(%lf, %lf)

Results look very nice!

The negative zeros are tweaking me out here....
Chris M. Thomasson
2017-06-25 00:43:16 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those of the form exp(i*x)?
[...]
Please excuse my ignorance, again... But getting better at gaining roots
[...]

Can you please help me figure out how to do the same with integers? I am
having some trouble. ;^o

Complex numbers seem fairly easy to me, the mod cyclic group of integers
is messing me up a bit. DAMN!
Chris M. Thomasson
2017-06-25 01:51:42 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those
of the form exp(i*x)?
[...]
Please excuse my ignorance, again... But getting better at gaining
[...]
Can you please help me figure out how to do the same with integers? I am
having some trouble. ;^o
Complex numbers seem fairly easy to me, the mod cyclic group of integers
is messing me up a bit. DAMN!
Getting closer! Let me keep trying.
Chris M. Thomasson
2017-06-25 03:13:47 UTC
Reply
Permalink
Raw Message
Post by Chris M. Thomasson
Post by Chris M. Thomasson
Post by richard miller
Post by Chris M. Thomasson
The roots of complex numbers like z^n+c, or even just z^n can store
data. Fwiw, here is a quick and crude example of using the ct_roots
Do you really need to use 'real' numbered complex roots, i.e. those
of the form exp(i*x)?
[...]
Please excuse my ignorance, again... But getting better at gaining
[...]
Can you please help me figure out how to do the same with integers? I am
having some trouble. ;^o
Complex numbers seem fairly easy to me, the mod cyclic group of integers
is messing me up a bit. DAMN!
I am having trouble with picking an integer i and a power p.

gaining the p integer roots of i as r.

choosing one of roots in r as the new i.

gaining the p roots of i as r.

choosing one of roots in r wrt the symbols that we are storing as the new i.

and on and on until the iteration is complete for storing all of the
symbols.

Then, for loading, raising the final i up to the power of p, gaining the
roots and comparing i to said roots to determine what symbol to load.
setting i to the correct root, raising again, and on and on until all of
the symbols are loaded. This works fine with complex numbers.

So far, I cannot convert my complex number method of storing n-ary data
into a form that uses integers!

Damn it!
Loading...