I think I fixed the precision loss in this fractal, at least for some of the locations which were broken. Was pretty hard. Not sure if there's a generally applicable solution.

It needed a couple of case analyses similar to the diffabs() function (which evaluates |X+x|-|X| without catastrophic precision loss when x is small compared to X) but specific to this fractal.

Separated Perpendicular fractal formula is not working for deep zooms with perturbation techniques as intended.

around the outside, inside looks more reasonable. In other locations (more often) the opposite happens. Other locations are perfectly fine to 1e50 zoom level and beyond. Some kind of precision loss somewhere...

Formula:

a, b = coordinates of pixel
xn = (abs(x) - 7/2) * abs(x) - y * y + a;
yn = 2 * (7/4 - abs(x)) * y + b;
x = xn;
y = yn;


Perturbation techniques applied to give iterations of low-precision deltas vs high-precision reference. This goes wrong somewhere and too much information is lost from the low-precision numbers, causing pixelation

// mathr - 2021-10-12 -

I could not quite fit the code into the toot, pushed here:
code.mathr.co.uk/clive/blob/68

Started work on a new project, still very much at proof of concept stage:

mathr.co.uk/paintin/demo.txt


// mathr - 2021-10-11 -

typedef double sample;
SR 48000
"dsp.h"
R sample

typedef struct
{
double t;
R note[2][3];
PHASOR osc[2][3][2];
} S;

int go(S *s, int inchannels, const float *in, int outchannels, float *out)
{
{
panic(s);
}
R bpm = 138 * 4./6;
R hz = 35;
R cps = bpm / 60 / 4;
R t = (s->t += cps / SR);
( envL(slow(4, t))
* envLR(rotL(4, slow(4, t))
), 2);
pair chords[3][4] =
{ { { 4, 4 }, { 2, 4 }, { 2, 5 }, { 4, 3 } }
, { { 2, 5 }, { 4, 6 }, { 3, 6 }, { 3, 4 } }
, { { 4, 6 }, { 2, 8 }, { 4, 8 }, { 2, 5 } }
};
R chord[2] = { 0, 0 };
for (int c = 0; c < 2; ++c)
{
for (int i = 0; i < 3; ++i)
{
R stereo = rotL(sine2(slow(4, t + (c - 0.5))) / 64, t);
R note = timeCat(chords[i], stereo);
R trig = (s->note[c][i] != note) * 500 * fade;
s->note[c][i] = note;
R q = mix(flatq, 5, envL(slow(8, t)));
R env = sine2(biquad(highpass(&s->env[c][i], cps * note, q), trig));
R osc = sine2(phasor(&s->osc[c][i][0], hz * (1 + (c - 0.5)/16) + (i - 1) / 30.0 + 1000 * env * sine2(phasor(&s->osc[c][i][1], hz * note))));
chord[c] += osc;
}
}
for (int c = 0; c < outchannels; ++c) {
out[c] = c < 2 ? 0.2 * chord[c] * fade : 0;
}
return 0;
}


claude boosted

I spoke to artist Joana Moll about her new piece for the Media Wall at The Photographers' Gallery last week.

We discussed microprocessors, their impact on the environment and the role of artists and the art world in the transition to a less polluting society.

You can read our conversation at Unthinking photography:

unthinking.photography/article


// mathr - 2021-10-06 -
typedef double R;
SR 48000
"dsp.h"
R sample
typedef struct
{
double t;
R note[2][3];
PHASOR osc[2][3],bosc[2][3];
}S;
int go(S *s,int nin,const float *in,int nout,float *out)
{
{
panic(s);
}
R bpm=138*4./3;
R hz=35;
R cps=bpm/60/4;
R t=(s->t+=cps/SR);
pair chords[3][4]=
{{{4,4},{2,4},{2,5},{4,3}}
,{{2,5},{4,6},{3,6},{3,4}}
,{{4,6},{2,8},{4,8},{2,5}}};
R chord[2]={0,0};
R bass=0;
for(int c=0;c<2;++c){
for(int i=0;i<3;++i){
R stereo=rotL(sine2(slow(4,t+(c-0.5)))/64,t);
R note=timeCat(chords[i],stereo);
s->note[c][i]=note;
R q=mix(flatq,5,envL(slow(8,t)));
R osc=square2(phasor(&s->osc[c][i],hz*note*3));
R pulse=exp2(square(fast(3,t)))/4;
R bosc=trisaw2(saw(slow(2,t)),phasor(&s->bosc[c][i],hz*note*3*pulse));
bass+=bosc;
chord[c]+=env*osc;
}
}
for (int c=0;c<nout;++c) {
out[c]=c<2?0.2*mix(chord[c],bass,0.5):0;
}
return 0;
}


Triangle Inequality Average colouring for escape time fractals:

$$t = \sum \frac{ |z| - |(|z-c|-|c|)| }{ |(|z-c|+|c|)| - |(|z-c|-|c|)| }$$
where $c$ is constant (determined by pixel) and $z$ varies (by iteration of the fractal formula)

This suffers from catastrophic cancellation when $|z| << |c|$, but it's possible to rearrange the calculation. Let $z=x+iy$ and $c=a+ib$, then

$$|z-c|-|c| = \frac{ x^2 + y^2 - 2ax - 2by }{ \sqrt{ |z-c|^2 + |c|^2 } + |c| }$$

Now my deep zooms with TIA colouring no longer have glitches around mini-sets due to loss of precision.

Still need to add some tweaks (like only considering the last few iterations before escape) to make it look good, with deep zooms the contrast just washes right out with standard TIA.

Somewhat more interesting than deep zooming is using it for interior regions with a relatively low iteration count.

claude boosted

workshop teaching opportunity

I'm recruiting again for guest online workshop leaders for some (paid) workshops for Babycastles, the art collective/videogame crew/DIY space I work with in NY.

Playlist of past online workshops here:

Topics I'm interested in hosting:

Intro to PD/Pure Data, Intro or Intermediate Twine (or Inform), Intro to Klik n Play, Intro / Intermediate Puzzlescript, Beginner, Intermediate and advanced workshops in Unity or Godot, Hotglue, Love2d,


// mathr - 2021-10-01 -
typedef double sample;
SR 48000
"dsp.h"
R sample

typedef struct
{
double t;
R note[2][3];
PHASOR osc[2][3], bosc[2][3];
} S;

int go(S *s, int nin, const float *in, int nout, float *out)
{
{
panic(s);
}
R bpm = 138;
R hz = 35;
R cps = bpm / 60 / 4;
R t = (s->t += cps / SR);
( envL(slow(4, t))
* envLR(rotL(4, slow(4, t))
), 2);
pair chords[3][4] =
{ { { 2, 4 }, { 1, 4 }, { 1, 5 }, { 4, 3 } }
, { { 1, 5 }, { 2, 6 }, { 2, 6 }, { 3, 4 } }
, { { 2, 6 }, { 1, 8 }, { 3, 8 }, { 2, 5 } }
};
R chord[2] = { 0, 0 };
R bass = 0;
for (int c = 0; c < 2; ++c)
{
for (int i = 0; i < 3; ++i)
{
R stereo = rotL(sine2(slow(4, t + (c - 0.5))) / 64, t);
R note = timeCat(chords[i], stereo);
R trig = (s->note[c][i] != note) * 500 * fade;
s->note[c][i] = note;
R q = mix(flatq, 5, envL(slow(8, t)));
R env = sine2(biquad(highpass(&s->env[c][i], cps * note, q), trig));
R osc = sine2(phasor(&s->osc[c][i], hz * note * 3));
R pulse = exp2(square(fast(4, t))) / 4;
R bosc = sine2(phasor(&s->bosc[c][i], hz * note * 3 * pulse));
bass += bosc;
chord[c] += env * osc;
}
}
for (int c = 0; c < nout; ++c) {
out[c] = c < 2 ? 0.2 * mix(chord[c], bass, 0.5) : 0;
}
return 0;
}


This week I have mostly been working on 's , making it so that it can control uniform variables declared in the colouring .

In the example attached, the interior colour jumps from black to red when passing near to a particular minibrot.

Some bugs to fix:
- zoom speed display is inaccurate (scaled incorrectly by duration)
- the timeline table should not expand so much horizontally to fill the window
- the timeline table should have scrollbars when the window is smaller than the table
- when the windows are hidden (with Ctrl-F10) the timeline sequencing is disabled
- the initial values should be populated from the KFP palette if one is used
- it crashes when the number of columns is too big for Dear ImGui (upstream ImGui has a limit of 64, I applied a patch from the issue tracker to raise it to 1000 which is hopefully enough, unfortunately it seems harder to patch ImGUI to have no fixed limit at all...)

claude boosted

fun reminder that #looptober starts tomorrow!

An idea I had while falling asleep last night:

mathr.co.uk/blog/2018-03-12_pe plus the basic idea behind dual numbers for automatic differentiation -> automatic perturbation?

i.e. have template<typename T> struct perturbed<T> = { T P, B, W; }; with usual numeric operators and functions that propagate the things.

new blog post about the Nova fractal
mathr.co.uk/blog/2021-09-27_pe
the trick is to move the critical point to 0, otherwise there is precision loss (visible glitches that look like mangled slices) when zooming to deep minibrots

claude boosted

A (probably not new) idea I had while watching live-coding performances: use edit distance to see if there's a unique nearest defined word that could be used in place of a typo'd word.

For example: in your Tidal Cycles code you type somtimes and it magically knows you meant sometimes, or in SuperCollider you type .ramge and it gets auto-corrected to .range.

I have a vague idea how to implement this for Pure-data object names (use the loader API and inspect objectmaker's method list, implement in C and might need non-public include files).

Can SuperCollider run user code on mis-spelled class and/or method names?

Or could a preprocessor do this more generally, handling parameter names etc? Maybe editor integration so it highlights the error visually and allows you to click to correct it in the text?

claude boosted

I am 100% serious that I'll pay somebody to design A4 sized posters that will go up at my uni and which hopefully mastonauts will also want to post where they study or work

I think I'll disable encryption as suspend/hibernate leaves persistence drive unlocked with a console also unlocked with live user auto-logged-in with capability to sudo to root without password, too much suggestion of security without actually providing any at all in that scenario...

here is a table of kernel boot parameters for (un)encrypted persistence vs partition encryption:

kernel 🔐 partition 🔐 -> prompts for unlock password, if password ok uses encrypted persistence partition no issues, otherwise it boots without persistence (RAM overlay only)
kernel 🔐 partition 🔓 -> ignores unencrypted partition completely, boots without persistence (RAM overlay only)
kernel 🔓 partition 🔐 -> ignores encrypted partition completely, boots without persistence (RAM overlay only)
kernel 🔓 partition 🔓 -> automatically uses persistence partition, no issues

changing kernel boot parameters requires either manual keyboarding on each boot, or recreating the hybrid ISO and reflashing the USB key. neither area fun.

Automated workaround:


$cat ~/.config/systemd/user/xfce4-resume-fix.service [Unit] Description=Fixes blank screen on resume from suspend After=suspend.target [Service] Type=oneshot ExecStart=xrandr --auto [Install] WantedBy=suspend.target$ systemctl --user enable xfce4-resume-fix


Probably resets monitor configurations so not great but better than a blank screen...

get for on old hardware?

My running my software makes the same sounds in the same order when powered on, when I really want it to be different each time. I seed based on time() but either libc from VBCC does not support it or the machine has no battery-backed real time clock or both.

Maybe I could use a cartridge and hope its noise floor isn't too good? Allocate memory without clearing and hash it before using it (would that survive a cold boot?).

Show older

Welcome to post.lurk.org, an instance for discussions around cultural freedom, experimental, new media art, net and computational culture, and things like that.

<svg xmlns="http://www.w3.org/2000/svg" id="hometownlogo" x="0px" y="0px" viewBox="25 40 50 20" width="100%" height="100%"><g><path d="M55.9,53.9H35.3c-0.7,0-1.3,0.6-1.3,1.3s0.6,1.3,1.3,1.3h20.6c0.7,0,1.3-0.6,1.3-1.3S56.6,53.9,55.9,53.9z"/><path d="M55.9,58.2H35.3c-0.7,0-1.3,0.6-1.3,1.3s0.6,1.3,1.3,1.3h20.6c0.7,0,1.3-0.6,1.3-1.3S56.6,58.2,55.9,58.2z"/><path d="M55.9,62.6H35.3c-0.7,0-1.3,0.6-1.3,1.3s0.6,1.3,1.3,1.3h20.6c0.7,0,1.3-0.6,1.3-1.3S56.6,62.6,55.9,62.6z"/><path d="M64.8,53.9c-0.7,0-1.3,0.6-1.3,1.3v8.8c0,0.7,0.6,1.3,1.3,1.3s1.3-0.6,1.3-1.3v-8.8C66,54.4,65.4,53.9,64.8,53.9z"/><path d="M60.4,53.9c-0.7,0-1.3,0.6-1.3,1.3v8.8c0,0.7,0.6,1.3,1.3,1.3s1.3-0.6,1.3-1.3v-8.8C61.6,54.4,61.1,53.9,60.4,53.9z"/><path d="M63.7,48.3c1.3-0.7,2-2.5,2-5.6c0-3.6-0.9-7.8-3.3-7.8s-3.3,4.2-3.3,7.8c0,3.1,0.7,4.9,2,5.6v2.4c0,0.7,0.6,1.3,1.3,1.3 s1.3-0.6,1.3-1.3V48.3z M62.4,37.8c0.4,0.8,0.8,2.5,0.8,4.9c0,2.5-0.5,3.4-0.8,3.4s-0.8-0.9-0.8-3.4C61.7,40.3,62.1,38.6,62.4,37.8 z"/><path d="M57,42.7c0-0.1-0.1-0.1-0.1-0.2l-3.2-4.1c-0.2-0.3-0.6-0.5-1-0.5h-1.6v-1.9c0-0.7-0.6-1.3-1.3-1.3s-1.3,0.6-1.3,1.3V38 h-3.9h-1.1h-5.2c-0.4,0-0.7,0.2-1,0.5l-3.2,4.1c0,0.1-0.1,0.1-0.1,0.2c0,0-0.1,0.1-0.1,0.1C34,43,34,43.2,34,43.3v7.4 c0,0.7,0.6,1.3,1.3,1.3h5.2h7.4h8c0.7,0,1.3-0.6,1.3-1.3v-7.4c0-0.2,0-0.3-0.1-0.4C57,42.8,57,42.8,57,42.7z M41.7,49.5h-5.2v-4.9 h10.2v4.9H41.7z M48.5,42.1l-1.2-1.6h4.8l1.2,1.6H48.5z M44.1,40.5l1.2,1.6h-7.5l1.2-1.6H44.1z M49.2,44.6h5.5v4.9h-5.5V44.6z"/></g></svg>