Calculate CRC16 CCITT FALSE in Google Apps Script [duplicate] - google-apps-script
This question already has an answer here:
Calculate CRC-16/CCITT-FALSE in Google Apps Script
(1 answer)
Closed 1 year ago.
I have VBA code that calculate the CRC16 CCITT value of string but now i have plan to use it on Google Sheet, but didn't have any idea how it will be on google script
Function crc_ccitt_ffff(strParam As String) As String
Const CRC_POLY_CCITT As Long = &H1021&
Const CRC_START_CCITT_FFFF As Long = &HFFFF&
Dim crc_tabccitt(0 To 255) As Long, crc As Long, b() As Byte, c As Long, i As Long, j As Long
For i = 0 To 255
crc = 0
c = i * 256
For j = 0 To 7
If (crc Xor c) And 32768 Then
crc = (crc * 2) Xor CRC_POLY_CCITT
Else
crc = crc * 2
End If
c = c * 2
Next j
crc_tabccitt(i) = crc
Next i
b = strParam
crc = CRC_START_CCITT_FFFF
For i = 0 To UBound(b) Step 2
crc = (crc * 256) Xor crc_tabccitt(((crc \ 256) Xor b(i)) And 255)
crc = ((crc \ 65536) * 65536) Xor crc
Next i
crc_ccitt_ffff = Hex(crc)
End Function
String on Column A : 00020101021129370016A000000677010111021312345678901215802TH5406500.5553037646304
Expected Results on Column B(or any other column) : 3D85
Can anyone help me with this?
Okay. Just for fun I've managed to translate your VB code (not sure if the code is working) to JS. Here you go:
function crc_ccitt_ffff(str) {
const POLY = 0x1021;
const START = 0xFFFF;
function get_crc_for_num(i) {
var crc = 0;
var c = i * 256;
[...Array(8).keys()].forEach(_ => {
crc = ((crc ^ c) & 0x8000) ? (crc * 2) ^ POLY : crc * 2;
c = c * 2 });
return crc;
}
var table = [...Array(256).keys()].map((_,n) => get_crc_for_num(n));
var crc = START;
str.split('').forEach(c => {
crc = (crc * 0x100) ^ table[ ( ((crc / 0x100) >> 0) ^ c.charCodeAt() ) & 0xFF ];
crc = (((crc / 0x10000) >> 0) * 0x10000) ^ crc;
}
)
return crc.toString(16);
}
var str = '00020101021129370016A000000677010111021312345678901215802TH5406500.5553037646304';
console.log( crc_ccitt_ffff(str) ); // output 3d85
It gives the same result with your data and it gives the same results as here https://crccalc.com/
But, beware, I'm not a real coder and I know next to nothing about VB and CRC-16. So it makes sense to test my code thoroughly before rush it into production.
Here is the code for Google Spreadsheet:
function main() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getRange("A1:B");
const data = range.getValues().map(x => [x[0], crc_ccitt_ffff(x[0])]);
range.setValues(data);
}
function crc_ccitt_ffff(str) {
if (str == '') return;
const get_crc_for_num = (n) => {
let crc = 0;
let c = n * 256;
[...Array(8).keys()].forEach(_ => {
crc = ((crc ^ c) & 0x8000) ? (crc * 2) ^ 0x1021 : crc * 2;
c = c * 2;
});
return crc;
}
const table = [...Array(256).keys()].map((_,n) => get_crc_for_num(n));
var crc = 0xFFFF;
str.split('').forEach(c => {
crc = (crc * 0x100) ^ table[(((crc / 0x100) >> 0) ^ c.charCodeAt()) & 0xFF];
crc = (((crc / 0x10000) >> 0) * 0x10000) ^ crc;
});
return crc.toString(16);
}
It takes all strings from column 'A' and put their CRC-16 to column 'B'.
Not sure if my solution is correct. Here is the JS implementation of CRC-16/CCITT: Generate CRC16 CCITT False with Javascript?
It gives 7D133D85 which looks suspiciously like your expected result. I have no idea where the first four digits go in the VB code.
So I took that JS code and updated it a little bit this way:
var crcTable = [
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0,
];
function crc16(str) {
var crc = 0xFFFF;
str.split('').forEach(c =>
crc = (crc << 8) ^ crcTable[(c.charCodeAt(0) ^ (crc >> 8)) & 0xFF]);
return crc.toString(16).toUpperCase();
}
var str = "00020101021129370016A000000677010111021312345678901215802TH5406500.5553037646304"
console.log(crc16(str)); // it gives 7d133d85
console.log(crc16(str).substring(4)); // it gives 3d85
As you can see, I use the substring(4) to get rid of the first four digits. Probably it's a stupid idea. Frankly, I'm not sure if this trick is applicable at all. You have to try it on your data.
Or to wait for someone who can translate accurately your VB code to JS. It doesn't look like an unsolvable task.
Related
Tradingview custom function with security()
I'm looking at the Pine version 3 migration guide and there's an example showing a custom function and using security() to call that function. https://www.tradingview.com/wiki/Pine_Version_3_Migration_Guide Now I tried to change my custom function in order to return two values instead of one, but for some reason it doesn't work anymore. The error is on line 10 ("[t,i] = ...") and says: variableType.itemType is not a function. My code below, can anyone advise what the issue is please? //#version=3 study("My Script") calcS() => s = 0.0 j = 0.0 s := close + 1 j := close + 2 [s, j] [t, i] = security(tickerid, '120', calcS()) plot(t, color=red, transp=0) plot(i, color=blue, transp=0)
It's a known problem. You can't return tuple from security. It's in our plans to fix this bug. Now you may use the following workaround: //#version=3 study("My Script") calcS() => s = 0.0 j = 0.0 s := close + 1 j := close + 2 [s, j] calcSs() => [s, j] = calcS() s calcSj() => [s, j] = calcS() j t = security(tickerid, '120', calcSs()) i = security(tickerid, '120', calcSj()) plot(t, color=red, transp=0) plot(i, color=blue, transp=0)
UPDATE Starting with Pine v4 you can use functions returning tuples with security(): //#version=4 study("", "", true) f() => [open, high] [o, h] = security(syminfo.tickerid, "D", f()) plot(o) plot(h)
Octave index out of bounds
The program is an optimized gradient descent. Here is the code : clear all close all [x,y] = meshgrid(-2:0.1:2); z = x.^2 + 100*y.^2; n = 1; k(n)=0.01; arret = 0.0001; mesh(x,y,z); [x1(n),y1(n)] = ginput(1); diff_x(n) = 2*x1(n); diff_y(n) = 200*y1(n); while sqrt(diff_x(n)^2 + diff_y(n)^2) > arret && n < 30 k(n) = sqrt(diff_x(n)^2 + diff_y(n)^2)/(8*x1(n).^2+2*10.^6*y1(n).^2); x1(n+1) = x1(n) - k(n)*diff_x(n); y1(n+1) = y1(n) - k(n)*diff_y(n); n = n+1; diff_x(n) = 2*x1(n); diff_y(n) = 200*y1(n); z1(n) = x1(n).^2 + 100*y1(n).^2; plot3(x1(n),y1(n),z1(n)); end x1(n) y1(n) n So I got this and I don't understand why. error: GradientPasOptFinal2: A(I): index out of bounds; value 2 out of bound 1 error: called from: error: error: C:\Octave\octave-3.8.2\GradientPasOptFinal2.m at line 13, column 8 SOLVED : the k(n) between y1(n) and n was the reason, i don't know why, but now the program works, thank you !
You have only defined k(1). k(2) is undefined. Move this line: k(n) = sqrt(diff_x(n)^2 + diff_y(n)^2)/(8*x1(n).^2+2*10.^6*y1(n).^2); Ahead of these lines: x1(n+1) = x1(n) - k(n)*diff_x(n); y1(n+1) = y1(n) - k(n)*diff_y(n); And it should work.
Mkfifo in GNU Octave
I have yet to find a complete example for using the mkfifo() function online. I am able to make the fifo like this: mkfifo("file",777) But when I fopen() this file, Octave just hangs. What is the proper way to create, queue, and dequeue bytes from a mkfifo object? I would like to create an in-memory fifo in Octave (on-disk is fine too) and read and write it from the same Octave script. My project is running in real time, and so I need a buffer so that I can fill and drain from the same Octave script. I've searched for a fifo library with zero results. Even just creating a vector and pushing and popping will suit my needs. I tried this myself, but I'm running into object oriented programming design problems because Octave does not allow pass by reference or pointers.
There are two issues. First: mkfifo expects mode as integer with base 10, if you write "777" you think in octal, base 8. Second: mkfifo uses umask to modify the permissions to (mode & ~umask) (See man 3) As example: fn=tempname [ERR, MSG] = mkfifo (fn, base2dec("744", 8)) stat(fn) fn = /tmp/oct-83UCBR ERR = 0 MSG = ans = scalar structure containing the fields: dev = 2053 ino = 3408172 mode = 4580 modestr = prwxr--r-- nlink = 1 uid = 1000 gid = 1000 rdev = 0 size = 0 atime = 1.4311e+09 mtime = 1.4311e+09 ctime = 1.4311e+09 blksize = 4096 blocks = 0 As you can see the modestr is now prwxr--r-- as you would expect from octal 744 Now you can open one end of the FIFO: fid = fopen (fn, "r") Of course this blocks until the other end of the fifo gets connected.
The fifo class works, but only up to a certain size. The max size in bytes of a fifo can be found by running: cat /proc/sys/fs/pipe-max-size 1048576 Below is the code that I wrote for an in-memory fifo. It's fairly crude but it works well: 1; % Prevent Octave from thinking that this is a function file global fifoCount fifoSamples fifoFiles fifoFids fifoDataType fifoSamples = zeros(0); fifoCount = 0; fifoFiles = cell(1); fifoFids = zeros(0); fifoDataType = 'single'; fifoDataTypeSize = 4; fifoMaxBytes = 1048576; % this is operating system enforced, changing here will not help function [] = o_fifo_write(index, data) global fifoCount fifoSamples fifoFiles fifoFids fifoDataType wrcount = fwrite(fifoFids(index), data, fifoDataType); [sz,~] = size(data); fifoSamples(index) = fifoSamples(index) + sz; if( sz ~= wrcount ) disp(sprintf('o_fifo_write was given %d samples but wrote %d', sz, wrcount)); end if( ~iscolumn(data) ) disp('data must be columnar in o_fifo_write'); end end function [data] = o_fifo_read(index, count) global fifoCount fifoSamples fifoFiles fifoFids fifoDataType [data, rdcount] = fread(fifoFids(index), count, fifoDataType); [sz,~] = size(data); fifoSamples(index) = fifoSamples(index) - sz; if( sz ~= rdcount || sz ~= count ) disp(sprintf('in o_fifo_read %d %d %d should all be the same', sz, rdcount, count)); end end function [avail] = o_fifo_avail(index) global fifoCount fifoSamples fifoFiles fifoFids fifoDataType avail = fifoSamples(index); end function index = o_fifo_new() global fifoCount fifoSamples fifoFiles fifoFids fifoDataType fifoCount = fifoCount + 1; index = fifoCount; fifoSamples(index) = 0; fifoFiles{index} = tempname; [ERR, MSG] = mkfifo(fifoFiles{index}, base2dec('744',8)); fifoFids(index) = fopen(fifoFiles{index}, 'a+'); % fcntl(fifoFids(index), F_SETFL, O_NONBLOCK); % uncomment to avoid hangs when trying to overfill fifo end % ---- usage ----- txfifo = o_fifo_new(); disp(o_fifo_avail(txfifo)); o_fifo_write(txfifo, [1.243 pi 2*pi 4/3*pi]'); disp(o_fifo_avail(txfifo)); disp(o_fifo_read(txfifo, 4)); disp(o_fifo_avail(txfifo));
How can I get the color halfway between two colors?
I have two colors: #15293E #012549 How can I find the color that is half way in between them? Is there some way to do this calculation?
As Mr Lister just said, it is easy to automate the calculation with any programming language : Separate your two colors into their 3 color numbers for Red, Green, Blue : (r1,g1,b1) and (r2,g2,b2). For example #15293E, #012549 become ("15", "29", "3E"), ("01", "25", "49") Convert each color string into an integer, specifying explicitly that you are parsing a hexadecimal-based representation of a number. For example ("15", "29", "3E") becomes (21, 41, 62) Calculate the average (r',g',b') = ( (r1+r2)/2, (g1+g2)/2, (b1+b2)/2 ). For example ( (21+1)/2, (41+37)/2, (62+73)/2) = (11, 39, 67) Convert them again to strings , specifying explicitly that you are generating two-digit hexadecimal representations (pad with a zero when necessary). For example (11, 39, 67) -> ("0B", "27", "43") Concatenate a hash character followed by the 3 strings For example ("0B", "27", "43") -> "#0B2743" Edit : Implementation is not "very easy" as I initially stated. I took the time to write the code in several languages on Programming-Idioms .
I use this website to do this task for me: ColorBlender. The mid-color will be #0B2744.
With LESS If you use the latest LESS CSS preprocessor then you'll notice there is a function (mix()) that does this: mix(#15293E, #012549, 50%) Outputs: #0b2744.
If you need to do this generically, and expect the middle colour to be visually accurate in more cases (i.e. the visual colour and tone of the mid point should "look right" to a human viewer), then as suggested above you may want to convert from RGB to HSV or HSL before calculating the mid point, and then convert back afterwards. This may differ significantly from averaging RGB values directly. Here is some JavaScript code for the conversion to/from HSL that I found on a brief search, and that on a brief check appears to do the right thing: github.com/mjackson/mjijackson.github.com/blob/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.txt https://web.archive.org/web/20170919064926/https://github.com/mjackson/mjijackson.github.com/blob/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.txt Just apply the rgbToHsl function to your two r,g,b colour vectors, average the two resulting vectors, and apply hslToRgb to that . . .
Handy-Dandy Function function padToTwo(numberString) { if (numberString.length < 2) { numberString = '0' + numberString; } return numberString; } function hexAverage() { var args = Array.prototype.slice.call(arguments); return args.reduce(function (previousValue, currentValue) { return currentValue .replace(/^#/, '') .match(/.{2}/g) .map(function (value, index) { return previousValue[index] + parseInt(value, 16); }); }, [0, 0, 0]) .reduce(function (previousValue, currentValue) { return previousValue + padToTwo(Math.floor(currentValue / args.length).toString(16)); }, '#'); } console.log(hexAverage('#111111', '#333333')); // => #222222 console.log(hexAverage('#111111', '#222222')); // => #191919 console.log(hexAverage('#111111', '#222222', '#333333')); // => #222222 console.log(hexAverage('#000483', '#004B39')); // => #00275e
Like this: function colourGradientor(p, rgb_beginning, rgb_end){ var w = p * 2 - 1; var w1 = (w + 1) / 2.0; var w2 = 1 - w1; var rgb = [parseInt(rgb_beginning[0] * w1 + rgb_end[0] * w2), parseInt(rgb_beginning[1] * w1 + rgb_end[1] * w2), parseInt(rgb_beginning[2] * w1 + rgb_end[2] * w2)]; return rgb; }; where p is a value between 0 and 1 specifying how far through the gradient the colour should be and rgb_beginning is the from colour and rgb_end is the to colour. Both are [r,g,b] arrays so you'll have to convert from hex first. This is a simplified version of LESS's mix function which I think is from SASS. For the poster p would be 0.5
i just wrote a function that calculates colors between two colors so here it is in case somebody needs it, i think it's quite short and readable, it accepts two colors in hex strings, and the number of colors to calculate in between, returns the colors in an array of hex strings i took the rgbToHex and hexToRgb functions from here Hope this helps! function rgbToHex(r, g, b) { return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); } function hexToRgb(hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } // returns an array of startColor, colors between according to steps, and endColor function getRamp(startColor, endColor, steps) { var ramp = []; ramp.push(startColor); var startColorRgb = hexToRgb(startColor); var endColorRgb = hexToRgb(endColor); var rInc = Math.round((endColorRgb.r - startColorRgb.r) / (steps+1)); var gInc = Math.round((endColorRgb.g - startColorRgb.g) / (steps+1)); var bInc = Math.round((endColorRgb.b - startColorRgb.b) / (steps+1)); for (var i = 0; i < steps; i++) { startColorRgb.r += rInc; startColorRgb.g += gInc; startColorRgb.b += bInc; ramp.push(rgbToHex(startColorRgb.r, startColorRgb.g, startColorRgb.b)); } ramp.push(endColor); return ramp; }
I found an npm module that does this: https://www.npmjs.com/package/color-between Here's some example usage: const colorBetween = require('color-between'); // rgb format colorBetween('rgb(255, 255, 255)', 'rgb(0, 0, 0)', 0.5, 'rgb'); // output: 'rgb(128, 128, 128)' // rgba format colorBetween('rgba(255, 255, 255, .2)', 'rgba(0, 0, 0, .8)', 0.5, 'rgb'); // output: 'rgba(128, 128, 128, 0.5) // hex format colorBetween('#fff', '#000', 0.5, 'hex'); // output: '#808080' // mixed format colorBetween('#fff', 'rgb(0, 0, 0)', 0.5, 'hsl'); output: 'hsl(0, 0%, 50%)'
If you so wished you could do it yourself with windows calculator. Open Windows Calculator > View > Programmer Choose the Hex option Enter the Hex value Switch to Dec and write down the value given Repeat for steps 2-4 for the second hex value Calculate the average by adding the two Dec numbers and dividing by 2 Enter this value into calculator with the Dec option selected then switch to the hex option and voila Example: 15293E (HEX) = 1386814 (DEC) 012549 (HEX) = 75081 (DEC) Mid Point = (1386814+75081)/2 Mid Point = 730947 (DEC) 730947 (DEC) = 0B2743 (HEX) #0B2743 or use ColorBlender as mentioned above ;)
Here I leave the code that I use in my typescript app function mixHexColors(color1: string, color2: string) { const valuesColor1 = color1.replace('#', '').match(/.{2}/g).map((value) => parseInt(value, 16) ) const valuesColor2 = color2.replace('#', '').match(/.{2}/g).map((value) => parseInt(value, 16) ) const mixedValues = valuesColor1.map((value, index) => ((value + valuesColor2[index]) / 2).toString(16).padStart(2, '') ) return `#${mixedValues.join('')}` }
Here's a Python version. # -*- coding: utf-8 -*- """jcolor_split.py splits 2 hex color values, HEX_COLOR_1 and HEX_COLOR_2, printing the color halfway between the two colors Usage: jcolor_split.py HEX_COLOR_1 HEX_COLOR_2 Example: ./jcolor_split.py 3E599C 2E4892 """ import sys def jcolor_split(hex_color_1, hex_color_2): print() print (hex_color_1) r1s = hex_color_1[0:2] g1s = hex_color_1[2:4] b1s = hex_color_1[4:6] print(r1s,g1s,b1s) print() print (hex_color_2) r2s = hex_color_2[0:2] g2s = hex_color_2[2:4] b2s = hex_color_2[4:6] print(r2s,g2s,b2s) # convert rgb's to ints r1 = int(r1s, 16); g1 = int(g1s, 16); b1 = int(b1s, 16); r2 = int(r2s, 16); g2 = int(g2s, 16); b2 = int(b2s, 16); print() print(r1,g1,b1) print(r2,g2,b2) # get the average ra = int(round(float(r1+r2)/2)) ga = int(round(float(g1+g2)/2)) ba = int(round(float(b1+b2)/2)) print() print(format(ra, 'x')+ format(ga, 'x')+ format(ba, 'x') ) NUM_ARGS = 2 def main(): args = sys.argv[1:] if len(args) != NUM_ARGS or "-h" in args or "--help" in args: print (__doc__) sys.exit(2) jcolor_split(args[0], args[1]) if __name__ == '__main__': main() sample_run = ''' PS C:\1d\JoeCodeswellHomePage> ./jcolor_split.py 3E599C 2E4892 3E599C 3E 59 9C 2E4892 2E 48 92 62 89 156 46 72 146 365097 PS C:\1d\JoeCodeswellHomePage> '''
I know this thread is about 10 years old, but this answer might be interesting for someone who is searching for a CSS-only alternative. Therefore you can just create a CSS gradient between two colors where you set an huge size, e.g. 10000vw and set the position to center: background: linear-gradient(90deg, rgb(255,255,0) 0%, rgb(0,0,255) 100%); background-size: 10000vw; background-position: center; Based on the percentage of the gradient positions you can also set a ratio to one direction of color.
Plotting a function in matlab involving an integral
I'm trying to plot a function that contains a definite integral. My code uses all anonymous functions. When I run the file, it gives me an error. My code is below: %%% List of Parameters %%% gamma_sp = 1; cap_gamma = 15; gamma_ph = 0; omega_0 = -750; d_omega_0 = 400; omega_inh = 100; d_omega_inh = 1000; %%% Formulae %%% gamma_t = gamma_sp/2 + cap_gamma/2 + gamma_ph; G = #(x) exp(-(x-omega_inh).^2./(2*d_omega_inh.^2))./(sqrt(2*pi)*d_omega_inh); F = #(x) exp(-(x-omega_0).^2./(2*d_omega_0.^2))./(sqrt(2*pi)*d_omega_0); A_integral = #(x,y) G(x)./(y - x + 1i*gamma_t); Q_integral = #(x,y) F(x)./(y - x + 1i*gamma_t); A = #(y) integral(#(x)A_integral(x,y),-1000,1000); Q = #(y) integral(#(x)Q_integral(x,y),-3000,0); P1 = #(y) -1./(1i.*(gamma_sp + cap_gamma)).*(1./(y + 2.*1i.*gamma_t)*(A(y)-conj(A(0)))-1./y.*(A(y)-A(0))+cap_gamma./gamma_sp.*Q(y).*(A(0)-conj(A(0)))); P2 = #(y) conj(P1(y)); P = #(y) P1(y) - P2(y); sig = #(y) abs(P(y)).^2; rng = -2000:0.05:1000; plot(rng,sig(rng)) It seems to me that when the program runs the plot command, it should put each value of rng into sig(y), and that value will be used as the y value in A_integral and Q_integral. However, matlab throws an error when I try to run the program. Error using - Matrix dimensions must agree. Error in #(x,y)G(x)./(y-x+1i*gamma_t) Error in #(x)A_integral(x,y) Error in integralCalc/iterateScalarValued (line 314) fx = FUN(t); Error in integralCalc/vadapt (line 133) [q,errbnd] = iterateScalarValued(u,tinterval,pathlen); Error in integralCalc (line 76) [q,errbnd] = vadapt(#AtoBInvTransform,interval); Error in integral (line 89) Q = integralCalc(fun,a,b,opstruct); Error in #(y)integral(#(x)A_integral(x,y),-1000,1000) Error in #(y)-1./(1i.*(gamma_sp+cap_gamma)).*(1./(y+2.*1i.*gamma_t)*(A(y)-conj(A(0)))-1. /y.*(A(y)-A(0))+cap_gamma./gamma_sp.*Q(y).*(A(0)-conj(A(0)))) Error in #(y)P1(y)-P2(y) Error in #(y)abs(P(y)).^2 Error in fwm_spec_diff_paper_eqn (line 26) plot(rng,sig(rng)) Any ideas about what I'm doing wrong?
You have >> rng = -2000:0.05:1000; >> numel(rng) ans = 60001 all 60001 elements get passed down to A = #(y) integral(#(x)A_integral(x,y),-1000,1000); which calls A_integral = #(x,y) G(x)./(y - x + 1i*gamma_t); (similar for Q). The thing is, integral is an adaptive quadrature method, meaning (roughly) that the amount of x's it will insert into A_integral varies with how A_integral behaves at certain x. Therefore, the amount of elements in y will generally be different from the elements in x in the call to A_integral. This is why y-x +1i*gamma_t fails. Considering the complexity of what you're trying to do, I think it is best to re-define all anonymous functions as proper functions, and integrate a few of them into single functions. Look into the documentation of bsxfun to see if that can help (e.g., bsxfun(#minus, y.', x) instead of y-x could perhaps fix a few of these issues), otherwise, vectorize only in x and loop over y.
Thanks Rody, that made sense to me. I keep trying to use matlab like mathematica and I forget how matlab does things. I modified the code a bit, and it produces the right result. The integrals are evaluated very roughly, but it should be easy to fix that. I've posted my modified code below. %%% List of Parameters %%% gamma_sp = 1; cap_gamma = 15; gamma_ph = 0; omega_0 = -750; d_omega_0 = 400; omega_inh = 100; d_omega_inh = 1000; %%% Formulae %%% gamma_t = gamma_sp/2 + cap_gamma/2 + gamma_ph; G = #(x) exp(-(x-omega_inh).^2./(2*d_omega_inh.^2))./(sqrt(2*pi)*d_omega_inh); F = #(x) exp(-(x-omega_0).^2./(2*d_omega_0.^2))./(sqrt(2*pi)*d_omega_0); A_integral = #(x,y) G(x)./(y - x + 1i*gamma_t); Q_integral = #(x,y) F(x)./(y - x + 1i*gamma_t); w = -2000:0.05:1000; sigplot = zeros(size(w)); P1plot = zeros(size(w)); P2plot = zeros(size(w)); Pplot = zeros(size(w)); aInt_range = -1000:0.1:1200; qInt_range = -2000:0.1:100; A_0 = sum(A_integral(aInt_range,0).*0.1); for k=1:size(w,2) P1plot(k) = -1./(1i*(gamma_sp + cap_gamma)).*(1./(w(k)+2.*1i.*gamma_t).*(sum(A_integral(aInt_range,w(k)).*0.1)-conj(A_0))-1./w(k).*(sum(A_integral(aInt_range,w(k)).*0.1)-A_0)+cap_gamma./gamma_sp.*sum(Q_integral(qInt_range,w(k)).*0.1).*(A_0-conj(A_0))); P2plot(k) = conj(P1plot(k)); Pplot(k) = P1plot(k) - P2plot(k); sigplot(k) = abs(Pplot(k)).^2; end plot(w,sigplot)