Orthogonal signals in frequency and time domains
Preamble: a scalar product is a positive semi-definite bilinear form, and we will suppose here we want the standard definitions.

Using their Fourier domain is (one of) the simplest way to construct orthogonal signals. It suffices to choose signals with disjoint frequency supports. Note that is not a necessary condition: some signals can be orthogonal with the same frequency supports, like $\cos$ and $\sin$, and more generally Hilbert transform pairs.

This is due to the Parseval-Plancherel theorem (inner product and norm preservation under Fourier transform): with disjoint frequency support, the scalar product is zero, and hence the vectors are orthogonal.

So in the following results, we take a random spectrum for a real signal. We then segment it into three subsets of points, mutually exclusive, and whose union give the full frequency axis. And then do an inverse FFT to obtain three subsignals whose inner products are:

S1.S2 = -4.7705e-18
S2.S3 = 1.7564e-17
S3.S1 = -1.2645e-17


The corresponding signals and spectra are displayed below, and the code follows (in Matlab):



function seDsp51117(nSample)

if nargin &lt; 1
    nSample = 512;
end
nSampleHalfSpectrum = nSample/2+1;
halfSpectrum = randn(nSampleHalfSpectrum,1)+1i*randn(nSampleHalfSpectrum,1);
halfSpectrum(1) = real(halfSpectrum(1));
halfSpectrum(end) = real(halfSpectrum(end));
nSampleSpectrum1 = ceil(nSampleHalfSpectrum*rand(1));
nSampleSpectrum2 = ceil((nSampleHalfSpectrum-nSampleSpectrum1)*rand(1));
nSampleSpectrum3 = nSampleHalfSpectrum - nSampleSpectrum1 - nSampleSpectrum2;

idxSpectrumRand   = randperm(nSampleHalfSpectrum);
bndSpectrumRand = round(linspace(1,nSampleHalfSpectrum+1,4));

idxSpectrum1 = idxSpectrumRand(bndSpectrumRand(1):bndSpectrumRand(2)-1);
idxSpectrum2 = idxSpectrumRand(bndSpectrumRand(2):bndSpectrumRand(3)-1);
idxSpectrum3 = idxSpectrumRand(bndSpectrumRand(3):bndSpectrumRand(4)-1);

[signal,halfSpectrumSelect] = IFFTReal(halfSpectrum);
[signal1,halfSpectrumSelect1] = IFFTReal(halfSpectrum,idxSpectrum1);
[signal2,halfSpectrumSelect2] = IFFTReal(halfSpectrum,idxSpectrum2);
[signal3,halfSpectrumSelect3] = IFFTReal(halfSpectrum,idxSpectrum3);
figure(1);clf
subplot(4,2,1)
plot((signal));axis tight;grid on
xlabel('Original signal')
subplot(4,2,3)
plot((signal1));axis tight;grid on
xlabel('Subsignal S1')
subplot(4,2,5)
plot((signal2));axis tight;grid on
xlabel('Subsignal S2')
subplot(4,2,7)
plot((signal3));axis tight;grid on
xlabel('Subsignal S3')

subplot(4,2,2);hold on
plot(abs([halfSpectrumSelect]),'o');
plot(abs([halfSpectrumSelect]),'x');
xlabel('Original spectrum')
axis tight;grid on
subplot(4,2,4);hold on
plot(abs([halfSpectrumSelect]),'o');
plot(abs([halfSpectrumSelect1]),'x');
axis tight;grid on
xlabel('Subsignal spectrum for S1')

subplot(4,2,6);hold on
plot(abs([halfSpectrumSelect]),'o');
plot(abs([halfSpectrumSelect2]),'x');
axis tight;grid on
xlabel('Subsignal spectrum for S2')
subplot(4,2,8);hold on
plot(abs([halfSpectrumSelect]),'o');
plot(abs([halfSpectrumSelect3]),'x');
axis tight;grid on
xlabel('Subsignal spectrum for S3')

sp12 = dot(signal1,signal2);
sp23 = dot(signal2,signal3);
sp31 = dot(signal3,signal1);

disp(['S1.S2 = ',num2str(sp12)]);
disp(['S2.S3 = ',num2str(sp23)]);
disp(['S3.S1 = ',num2str(sp31)]);

function [signal,halfSpectrumSelect] = IFFTReal(halfSpectrum,idxSpectrum)
if nargin &lt; 2
    idxSpectrum = 1:length(halfSpectrum);
end
halfSpectrumSelect = zeros(size(halfSpectrum));
halfSpectrumSelect(idxSpectrum) = halfSpectrum(idxSpectrum);

%% Hermitian glue
wholeSpectrum = [halfSpectrumSelect;conj(flipud(halfSpectrumSelect(2:end-1)))];
ratioImagReal = 10^(-6);
tmp = ifft(wholeSpectrum);
normRatio =  norm(imag(tmp),1)/norm(real(tmp),1);
    signal = real(tmp);
if normRatio &gt; ratioImagReal
warning('Check the imaginery value');
    end