text:
CS50 (Computer Science 50) is an on-campus and online introductory course on computer science taught at Harvard University and, as of 2015, Yale University as well. In 2016, CS50 became available to high school students as an AP course. The course material is available online for free on EdX with a range of certificates available for a fee. The on-campus version is Harvard’s largest class with 800 students, 102 staff and up to 2,200 participants in their regular hackathons.

CS50, Wikipedia

* 此课程笔记根据 Harvard CS50 Spring 2020 完成。

• In week 0, we learned binary, a counting system with 0s and 1s.
• In week 2, we talked about memory and how each byte has an address, or identifier, so we can refer to where our variables are actually stored.
• It turns out that, by convention, the addresses for memory use the counting system hexadecimal, where there are 16 digits, 0-9 and A-F.
• Recall that, in binary, each digit stood for a power of 2:
128 64 32 16 8 4 2 1
 1 1 1 1 1 1 1 1
• With 8 bits, we can count up to 255.
• It turns out that, in hexadecimal, we can perfectly count up to 8 binary bits with just 2 digits:
16^1 16^0
F F
• Here, the F is a value of 15 in decimal, and each place is a power of 16, so the first F is 16^1 * 15 = 240, plus the second F with the value of 16^0 * 15 = 15, for a total of 255.
• And 0A is the same as 10 in decimal, and 0F the same as 15. 10 in hexadecimal would be 16, and we would say it as “one zero in hexadecimal” instead of “ten”, if we wanted to avoid confusion.
• The RGB color system also conventionally uses hexadecimal to describe the amount of each color. For example, 000000 in hexadecimal means 0 of each red, green, and blue, for a color of black. And FF0000 would be 255, or the highest possible, amount of red. With different values for each color, we can represent millions of different colors.
• In writing, we can also indicate a value is in hexadecimal by prefixing it with 0x, as in 0x10, where the value is equal to 16 in decimal, as opposed to 10.

Pointers

• We might create a value n, and print it out:
#include <stdio.h>

int main(void)
{
int n = 50;
printf("%i\n", n);
}

• In our computer’s memory, there are now 4 bytes somewhere that have the binary value of 50, labeled n:
• It turns out that, with the billions of bytes in memory, those bytes for the variable n starts at some unique address that might look like 0x12345678.
• In C, we can actually see the address with the & operator, which means “get the address of this variable”:
#include <stdio.h>

int main(void)
{
int n = 50;
printf("%p\n", &n);
}

• And in the CS50 IDE, we might see an address like 0x7ffe00b3adbc, where this is a specific location in the server’s memory.
• The address of a variable is called a pointer, which we can think of as a value that “points” to a location in memory. The * operator lets us “go to” the location that a pointer is pointing to.
• For example, we can print *&n, where we “go to” the address of n, and that will print out the value of n, 50, since that’s the value at the address of n:
#include <stdio.h>

int main(void)
{
int n = 50;
printf("%i\n", *&n);
}

• We also have to use the * operator (in an unfortunately confusing way) to declare a variable that we want to be a pointer:
#include <stdio.h>

int main(void)
{
int n = 50;
int *p = &n;
printf("%p\n", p);
}

• Here, we use int *p to declare a variable, p, that has the type of *, a pointer, to a value of type int, an integer. Then, we can print its value (something like 0x12345678), or print the value at its location with printf("%i\n", *p);.
• In our computer’s memory, the variables might look like this:
• We have a pointer, p, with the address of some variable.
• We can abstract away the actual value of the addresses now, since they’ll be different as we declare variables in our programs, and simply think of p as “pointing at” some value:
• Let’s say we have a mailbox labeled “123”, with the number “50” inside it. The mailbox would be int n, since it stores an integer. We might have another mailbox with the address “456”, inside of which is the value “123”, which is the address of our other mailbox. This would be int *p, since it’s a pointer to an integer.
• With the ability to use pointers, we can create different data structures, or different ways to organize data in memory that we’ll see next week.
• Many modern computer systems are “64-bit”, meaning that they use 64 bits to address memory, so a pointer will be 8 bytes, twice as big as an integer of 4 bytes.

string

• We might have a variable string s for a name like EMMA, and be able to access each character with s[0] and so on:
• But it turns out that each character is in stored in memory at a byte with some address, and s is actually just a pointer with the address of the first character:
• And since s is just a pointer to the beginning, only the \0 indicates the end of the string.
• In fact, the CS50 Library defines a string with typedef char *string, which just says that we want to name a new type, string, as a char *, or a pointer to a character.
• Let’s print out a string:
#include <cs50.h>
#include <stdio.h>

int main(void)
{
string s = "EMMA";
printf("%s\n", s);
}

• This is familiar, but we can just say:
#include <stdio.h>

int main(void)
{
char *s = "EMMA";
printf("%s\n", s);
}

• This will also print EMMA.
• With printf("%p\n", s);, we can print s as its value as a pointer, like 0x42ab52. (printf knows to go to the address and print the entire string when we use %s and pass in s, even though s only points to the first character.)
• We can also try printf("%p\n", &s[0]);, which is the address of the first character of s, and it’s exactly the same as printing s. And printing &s[1], &s[2], and &s[3] gets us the addresses that are the next characters in memory after &s[0], like 0x42ab53, 0x42ab54, and 0x42ab55, exactly one byte after another.
• And finally, if we try to printf("%c\n", *s);, we get a single character E, since we’re going to the address contained in s, which has the first character in the string.
• In fact, s[0], s[1], and s[2] actually map directly to *s, *(s+1), and *(s+2), since each of the next characters are just at the address of the next byte.

Compare and Copy

• Let’s look at compare0:
#include <cs50.h>
#include <stdio.h>

int main(void)
{
// Get two integers
int i = get_int("i: ");
int j = get_int("j: ");

// Compare integers
if (i == j)
{
printf("Same\n");
}
else
{
printf("Different\n");
}
}

• We can compile and run this, and our program works as we’d expect, with the same values of the two integers giving us “Same” and different values “Different”.
• In compare1, we see that the same string values are causing our program to print “Different”:
#include <cs50.h>
#include <stdio.h>

int main(void)
{
// Get two strings
string s = get_string("s: ");
string t = get_string("t: ");

if (s == t)
{
printf("Same\n");
}
else
{
printf("Different\n");
}
}

• Given what we now know about strings, this makes sense because each “string” variable is pointing to a different location in memory, where the first character of each string is stored. So even if the values of the strings are the same, this will always print “Different”.
• For example, our first string might be at address 0x123, our second might be at 0x456, and s will be 0x123 and t will be 0x456, so those values will be different.
• And get_string, this whole time, has been returning just a char *, or a pointer to the first character of a string from the user.
• Now let’s try to copy a string:
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>

int main(void)
{
string s = get_string("s: ");

string t = s;

t[0] = toupper(t[0]);

// Print string twice
printf("s: %s\n", s);
printf("t: %s\n", t);
}

• We get a string s, and copy the value of s into t. Then, we capitalize the first letter in t.
• But when we run our program, we see that both s and t are now capitalized.
• Since we set s and t to the same values, they’re actually pointers to the same character, and so we capitalized the same character!
• To actually make a copy of a string, we have to do a little more work:
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
char *s = get_string("s: ");

char *t = malloc(strlen(s) + 1);

for (int i = 0, n = strlen(s); i < n + 1; i++)
{
t[i] = s[i];
}

t[0] = toupper(t[0]);

printf("s: %s\n", s);
printf("t: %s\n", t);
}

• We create a new variable, t, of the type char *, with char *t. Now, we want to point it to a new chunk of memory that’s large enough to store the copy of the string. With malloc, we can allocate some number of bytes in memory (that aren’t already used to store other values), and we pass in the number of bytes we’d like. We already know the length of s, so we add 1 to that for the terminating null character. So, our final line of code is char *t = malloc(strlen(s) + 1);.
• Then, we copy each character, one at a time, and now we can capitalize just the first letter of t. And we use i < n + 1, since we actually want to go up to n, to ensure we copy the terminating character in the string.
• We can actually also use the strcpy library function with strcpy(t, s) instead of our loop, to copy the string s into t. To be clear, the concept of a “string” is from the C language and well-supported; the only training wheels from CS50 are the type string instead of char *, and the get_string function.
• If we didn’t copy the null terminating character, \0, and tried to print out our string t, printf will continue and print out the unknown, or garbage, values that we have in memory, until it happens to reach a \0, or crashes entirely, since our program might end up trying to read memory that doesn’t belong to it!

valgrind

• It turns out that, after we’re done with memory that we’ve allocated with malloc, we should call free (as in free(t)), which tells our computer that those bytes are no longer useful to our program, so those bytes in memory can be reused again.
• If we kept running our program and allocating memory with malloc, but never freed the memory after we were done using it, we would have a memory leak, which will slow down our computer and use up more and more memory until our computer runs out.
• valgrind is a command-line tool that we can use to run our program and see if it has any memory leaks. We can run valgrind on our program above with help50 valgrind ./copy and see, from the error message, that line 10, we allocated memory that we never freed (or “lost”).
• So at the end, we can add a line free(t), which won’t change how our program runs, but no errors from valgrind.
• Let’s take a look at memory.c:
// http://valgrind.org/docs/manual/quick-start.html#quick-start.prepare

#include <stdlib.h>

void f(void)
{
int *x = malloc(10 * sizeof(int));
x[10] = 0;
}

int main(void)
{
f();
return 0;
}

• This is an example from valgrind’s documentation (valgrind is a real tool, while help50 was written specifically to help us in this course).
• The function f allocates enough memory for 10 integers, and stores the address in a pointer called x. Then we try to set the 11th value of x with x[10] to 0, which goes past the array of memory we’ve allocated for our program. This is called buffer overflow, where we go past the boundaries of our buffer, or array, and into unknown memory.
• valgrind will also tell us there’s an “Invalid write of size 4” for line 8, where we are indeed trying to change the value of an integer (of size 4 bytes).
• And this whole time, the CS50 Library has been freeing memory it’s allocated in get_string, when our program finishes!

Swap

• We have two colored drinks, purple and green, each of which is in a cup. We want to swap the drinks between the two cups, but we can’t do that without a third cup to pour one of the drink into first.
• Now, let’s say we wanted to swap the values of two integers.
void swap(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}

• With a third variable to use as temporary storage space, we can do this pretty easily, by putting a into tmp, and then b to a, and finally the original value of a, now in tmp, into b.
• But, if we tried to use that function in a program, we don’t see any changes:
#include <stdio.h>

void swap(int a, int b);

int main(void)
{
int x = 1;
int y = 2;

printf("x is %i, y is %i\n", x, y);
swap(x, y);
printf("x is %i, y is %i\n", x, y);
}

void swap(int a, int b)
{
int tmp = a;
a = b;
b = tmp;
}

• It turns out that the swap function gets its own variables, a and b when they are passed in, that are copies of x and y, and so changing those values don’t change x and y in the main function.

Memory Layout

• Within our computer’s memory, the different types of data that need to be stored for our program are organized into different sections:
• The machine code section is our compiled program’s binary code. When we run our program, that code is loaded into the “top” of memory.
• Globals are global variables we declare in our program or other shared variables that our entire program can access.
• The heap section is an empty area where malloc can get free memory from, for our program to use.
• The stack section is used by functions in our program as they are called. For example, our main function is at the very bottom of the stack, and has the local variables x and y. The swap function, when it’s called, has its own frame, or slice, of memory that’s on top of main’s, with the local variables a, b, and tmp:
• Once the function swap returns, the memory it was using is freed for the next function call, and we lose anything we did, other than the return values, and our program goes back to the function that called swap.
• So by passing in the addresses of x and y from main to swap, we can actually change the values of x and y:
• By passing in the address of x and y, our swap function can actually work:
#include <stdio.h>

void swap(int *a, int *b);

int main(void)
{
int x = 1;
int y = 2;

printf("x is %i, y is %i\n", x, y);
swap(&x, &y);
printf("x is %i, y is %i\n", x, y);
}

void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

• The addresses of x and y are passed in from main to swap, and we use the int *a syntax to declare that our swap function takes in pointers. We save the value of x to tmp by following the pointer a, and then take the value of y by following the pointer b, and store that to the location a is pointing to (x). Finally, we store the value of tmp to the location pointed to by b (y), and we’re done.
• If we call malloc too many times, we will have a heap overflow, where we end up going past our heap. Or, if we have too many functions being called, we will have a stack overflow, where our stack has too many frames of memory allocated as well. And these two types of overflow are generally known as buffer overflows, after which our program (or entire computer) might crash.

get_int

• We can implement get_int ourselves with a C library function, scanf:
#include <stdio.h>

int main(void)
{
int x;
printf("x: ");
scanf("%i", &x);
printf("x: %i\n", x);
}

• scanf takes a format, %i, so the input is “scanned” for that format, and the address in memory where we want that input to go. But scanf doesn’t have much error checking, so we might not get an integer.
• We can try to get a string the same way:
#include <stdio.h>

int main(void)
{
char *s = NULL;
printf("s: ");
scanf("%s", s);
printf("s: %s\n", s);
}

• But we haven’t actually allocated any memory for s (s is NULL, or not pointing to anything), so we might want to call char s[5] to allocate an array of 5 characters for our string. Then, s will be treated as a pointer in scanf and printf.
• Now, if the user types in a string of length 4 or less, our program will work safely. But if the user types in a longer string, scanf might be trying to write past the end of our array into unknown memory, causing our program to crash.

Files

• With the ability to use pointers, we can also open files:
#include <cs50.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
// Open file
FILE *file = fopen("phonebook.csv", "a");

// Get strings from user
char *name = get_string("Name: ");
char *number = get_string("Number: ");

// Print (write) strings to file
fprintf(file, "%s,%s\n", name, number);

// Close file
fclose(file);
}

• fopen is a new function we can use to open a file. It will return a pointer to a new type, FILE, that we can read from and write to. The first argument is the name of the file, and the second argument is the mode we want to open the file in (r for read, w for write, and a for append, or adding to).
• After we get some strings, we can use fprintf to print to a file.
• Finally, we close the file with fclose.
• Now we can create our own CSV files, files of comma-separated values (like a mini-spreadsheet), programmatically.

JPEG

• We can also write a program that opens a file and tells us if it’s a JPEG (image) file:
#include <stdio.h>

int main(int argc, char *argv[])
{
// Check usage
if (argc != 2)
{
return 1;
}

// Open file
FILE *file = fopen(argv[1], "r");
if (!file)
{
return 1;
}

unsigned char bytes[3];

// Check first three bytes
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff)
{
printf("Maybe\n");
}
else
{
printf("No\n");
}

// Close file
fclose(file);
}

• Now, if we run this program with ./jpeg brian.jpg, our program will try to open the file we specify (checking that we indeed get a non-NULL file back), and read the first three bytes from the file with fread.
• We can compare the first three bytes (in hexadecimal) to the three bytes required to begin a JPEG file. If they’re the same, then our file is likely to be a JPEG file (though, other types of files may still begin with those bytes). But if they’re not the same, we know it’s definitely not a JPEG file.
• We can use these abilities to read and write files, in particular images, and modify them by changing the bytes in them, in this week’s problem set!

习题个人解答

Filter

bmp.h

// BMP-related data types based on Microsoft's own

#include <stdint.h>

/**
* Common Data Types
*
* The data types in this section are essentially aliases for C/C++
* primitive data types.
*
* See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h.
*/
typedef uint8_t  BYTE;
typedef uint32_t DWORD;
typedef int32_t  LONG;
typedef uint16_t WORD;

/**
*
* and layout of a file that contains a DIB [device-independent bitmap].
*
*/
typedef struct
{
WORD   bfType;
DWORD  bfSize;
WORD   bfReserved1;
WORD   bfReserved2;
DWORD  bfOffBits;
} __attribute__((__packed__))

/**
*
* dimensions and color format of a DIB [device-independent bitmap].
*
*/
typedef struct
{
DWORD  biSize;
LONG   biWidth;
LONG   biHeight;
WORD   biPlanes;
WORD   biBitCount;
DWORD  biCompression;
DWORD  biSizeImage;
LONG   biXPelsPerMeter;
LONG   biYPelsPerMeter;
DWORD  biClrUsed;
DWORD  biClrImportant;
} __attribute__((__packed__))

/**
* RGBTRIPLE
*
* This structure describes a color consisting of relative intensities of
* red, green, and blue.
*
*/
typedef struct
{
BYTE  rgbtBlue;
BYTE  rgbtGreen;
BYTE  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

helpers.h

#include "bmp.h"

// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width]);

// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width]);

// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width]);

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width]);

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width]);

filter.c

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>

#include "helpers.h"

int main(int argc, char *argv[])
{

// Define allowable filters
char *filters = "begrs";

// Get filter flag and check validity
char filter = getopt(argc, argv, filters);
if (filter == '?')
{
fprintf(stderr, "Invalid filter.\n");
return 1;
}

// Ensure only one filter
if (getopt(argc, argv, filters) != -1)
{
fprintf(stderr, "Only one filter allowed.\n");
return 2;
}

// Ensure proper usage
if (argc != optind + 2)
{
fprintf(stderr, "Usage: filter [flag] infile outfile\n");
return 3;
}

// Remember filenames
char *infile = argv[optind];
char *outfile = argv[optind + 1];

// Open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", infile);
return 4;
}

// Open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}

// Ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
bi.biBitCount != 24 || bi.biCompression != 0)
{
fclose(outptr);
fclose(inptr);
fprintf(stderr, "Unsupported file format.\n");
return 6;
}

int height = abs(bi.biHeight);
int width = bi.biWidth;

// Allocate memory for image
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
if (image == NULL)
{
fprintf(stderr, "Not enough memory to store image.\n");
fclose(outptr);
fclose(inptr);
return 7;
}

int padding = (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;

// Iterate over infile's scanlines
for (int i = 0; i < height; i++)
{
// Read row into pixel array

}

// Filter image
switch (filter)
{
// Blur
case 'b':
blur(height, width, image);
break;

// Edges
case 'e':
edges(height, width, image);
break;

// Grayscale
case 'g':
grayscale(height, width, image);
break;

// Reflection
case 'r':
reflect(height, width, image);
break;

// Sepia
case 's':
sepia(height, width, image);
break;
}

// Write new pixels to outfile
for (int i = 0; i < height; i++)
{
// Write row to outfile
fwrite(image[i], sizeof(RGBTRIPLE), width, outptr);

// Write padding at end of row
for (int k = 0; k < padding; k++)
{
fputc(0x00, outptr);
}
}

// Free memory for image
free(image);

// Close infile
fclose(inptr);

// Close outfile
fclose(outptr);

return 0;
}

helper.c

#include "helpers.h"
#include <stdlib.h>
#include <math.h>

// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int r = image[i][j].rgbtRed;
int g = image[i][j].rgbtGreen;
int b = image[i][j].rgbtBlue;
int avg = round((r + g + b) / 3.0);
image[i][j].rgbtRed = image[i][j].rgbtGreen = image[i][j].rgbtBlue = (BYTE) avg;
}
}
return;
}

// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int r = image[i][j].rgbtRed;
int g = image[i][j].rgbtGreen;
int b = image[i][j].rgbtBlue;
double sepia_r = round(0.393 * r + 0.769 * g + 0.189 * b);
double sepia_g = round(0.349 * r + 0.686 * g + 0.168 * b);
double sepia_b = round(0.272 * r + 0.534 * g + 0.131 * b);
sepia_r = (sepia_r > 255) ? 255 : sepia_r;
sepia_g = (sepia_g > 255) ? 255 : sepia_g;
sepia_b = (sepia_b > 255) ? 255 : sepia_b;
image[i][j].rgbtRed = (BYTE) sepia_r;
image[i][j].rgbtGreen = (BYTE) sepia_g;
image[i][j].rgbtBlue = (BYTE) sepia_b;
}
}
return;
}

// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width / 2; j++)
{
RGBTRIPLE * temp = malloc(sizeof(RGBTRIPLE));
*temp = image[i][width - 1 - j];
image[i][width - 1 - j] = image[i][j];
image[i][j] = *temp;
free(temp);
}
}
return;
}

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE (*newimage)[width] = calloc(height, width * sizeof(RGBTRIPLE));
int dxy[3] = {-1, 0, 1};
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
double blocks;
int r = 0, g = 0, b = 0;
for (int dx = 0; dx < 3; dx++)
{
int nx = i + dxy[dx];
if (nx < 0 || nx >= height)
continue;
for (int dy = 0; dy < 3; dy++)
{
int ny = j + dxy[dy];
if (ny < 0 || ny >= width)
continue;
r += image[nx][ny].rgbtRed;
g += image[nx][ny].rgbtGreen;
b += image[nx][ny].rgbtBlue;
}
}
if ((i == 0 || i == height - 1) && (j == 0 || j == width - 1))
blocks = 4;
else if (i == 0 || i == height - 1 || j == 0 || j == width - 1)
blocks = 6;
else
blocks = 9;
r = round(r / blocks);
g = round(g / blocks);
b = round(b / blocks);
newimage[i][j].rgbtRed = (BYTE) r;
newimage[i][j].rgbtGreen = (BYTE) g;
newimage[i][j].rgbtBlue = (BYTE) b;
}
}
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
image[i][j] = newimage[i][j];
free(newimage);
return;
}

// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE (*newimage)[width] = calloc(height, width * sizeof(RGBTRIPLE));
int Gx[3][3] = {{-1,0,1},{-2,0,2},{-1,0,1}};
int Gy[3][3] = {{-1,-2,-1},{0,0,0},{1,2,1}};
int dxy[3] = {-1, 0, 1};
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int rx = 0, gx = 0, bx = 0;
int ry = 0, gy = 0, by = 0;
for (int dx = 0; dx < 3; dx++)
{
int nx = i + dxy[dx];
if (nx < 0 || nx >= height)
continue;
for (int dy = 0; dy < 3; dy++)
{
int ny = j + dxy[dy];
if (ny < 0 || ny >= width)
continue;
rx += image[nx][ny].rgbtRed * Gx[dx][dy];
gx += image[nx][ny].rgbtGreen * Gx[dx][dy];
bx += image[nx][ny].rgbtBlue * Gx[dx][dy];
ry += image[nx][ny].rgbtRed * Gy[dx][dy];
gy += image[nx][ny].rgbtGreen * Gy[dx][dy];
by += image[nx][ny].rgbtBlue * Gy[dx][dy];
}
}
int rsqrt = round(sqrt(rx * rx + ry * ry));
int gsqrt = round(sqrt(gx * gx + gy * gy));
int bsqrt = round(sqrt(bx * bx + by * by));
rsqrt = (rsqrt > 255) ? 255 : rsqrt;
gsqrt = (gsqrt > 255) ? 255 : gsqrt;
bsqrt = (bsqrt > 255) ? 255 : bsqrt;
newimage[i][j].rgbtRed = (BYTE) rsqrt;
newimage[i][j].rgbtGreen = (BYTE) gsqrt;
newimage[i][j].rgbtBlue = (BYTE) bsqrt;
}
}
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
image[i][j] = newimage[i][j];
free(newimage);
return;
}

Recover

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#define MAXSIZE 512

typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
int pic = 0;
FILE * outfile = NULL;
BYTE buf[MAXSIZE];
char filename[20];

if (argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}

FILE * infile = fopen(argv[1], "r");

if (infile == NULL)
{
printf("Usage: ./recover image\n");
return 1;
}

do
{
bool header = (buf[0] == 0xff) && (buf[1] == 0xd8) && (buf[2] == 0xff) && ((buf[3] & 0xf0) == 0xe0);
{
if (outfile != NULL)
fclose(outfile);
sprintf(filename, "%03i.jpg", pic);
outfile = fopen(filename, "w");
pic++;
}
if (outfile != NULL)
{


text:
# mathlibdocumentation

ring_theory.artinian

# Artinian rings and modules #

A module satisfying these equivalent conditions is said to be an Artinian R-module if every decreasing chain of submodules is eventually constant, or equivalently, if the relation < on submodules is well founded.

A ring is an Artinian ring if it is Artinian as a module over itself.

(Note that we do not assume yet that our rings are commutative, so perhaps this should be called "left Artinian". To avoid cumbersome names once we specialize to the commutative case, we don't make this explicit in the declaration names.)

## Main definitions #

Let R be a ring and let M and P be R-modules. Let N be an R-submodule of M.

• is_artinian R M is the proposition that M is a Artinian R-module. It is a class, implemented as the predicate that the < relation on submodules is well founded.

## References #

• [M. F. Atiyah and I. G. Macdonald, Introduction to commutative algebra][atiyah-macdonald]
• [samuel]

## Tags #

Artinian, artinian, Artinian ring, Artinian module, artinian ring, artinian module

@[class]
structure is_artinian (R : Type u_1) (M : Type u_2) [semiring R] [ M] :
Prop
• well_founded_submodule_lt :

is_artinian R M is the proposition that M is an Artinian R-module, implemented as the well-foundedness of submodule inclusion.

Instances
theorem is_artinian_of_injective {R : Type u_1} {M : Type u_2} {P : Type u_3} [ring R] [ M] [ P] (f : M →ₗ[R] P) (h : function.injective f) [ P] :
M
@[protected, instance]
def is_artinian_submodule' {R : Type u_1} {M : Type u_2} [ring R] [ M] [ M] (N : M) :
N
theorem is_artinian_of_le {R : Type u_1} {M : Type u_2} [ring R] [ M] {s t : M} [ht : t] (h : s t) :
s
theorem is_artinian_of_surjective {R : Type u_1} (M : Type u_2) {P : Type u_3} [ring R] [ M] [ P] (f : M →ₗ[R] P) (hf : function.surjective f) [ M] :
P
theorem is_artinian_of_linear_equiv {R : Type u_1} {M : Type u_2} {P : Type u_3} [ring R] [ M] [ P] (f : M ≃ₗ[R] P) [ M] :
P
theorem is_artinian_of_range_eq_ker {R : Type u_1} {M : Type u_2} {P : Type u_3} {N : Type u_4} [ring R] [ M] [ P] [ N] [ M] [ P] (f : M →ₗ[R] N) (g : N →ₗ[R] P) (hf : function.injective f) (hg : function.surjective g) (h : f.range = g.ker) :
N
@[protected, instance]
def is_artinian_prod {R : Type u_1} {M : Type u_2} {P : Type u_3} [ring R] [ M] [ P] [ M] [ P] :
(M × P)
@[instance]
theorem is_artinian_of_fintype {R : Type u_1} {M : Type u_2} [ring R] [ M] [fintype M] :
M
@[protected, instance]
def is_artinian_pi {R : Type u_1} {ι : Type u_2} [fintype ι] {M : ι → Type u_3} [ring R] [Π (i : ι), add_comm_group (M i)] [Π (i : ι), (M i)] [∀ (i : ι), (M i)] :
(Π (i : ι), M i)
@[protected, instance]
def is_artinian_pi' {R : Type u_1} {ι : Type u_2} {M : Type u_3} [ring R] [ M] [fintype ι] [ M] :
(ι → M)

A version of is_artinian_pi for non-dependent functions. We need this instance because sometimes Lean fails to apply the dependent version in non-dependent settings (e.g., it fails to prove that ι → ℝ is finite dimensional over ℝ).

theorem is_artinian_iff_well_founded {R : Type u_1} {M : Type u_2} [ring R] [ M] :
theorem is_artinian.finite_of_linear_independent {R : Type u_1} {M : Type u_2} [ring R] [ M] [nontrivial R] [ M] {s : set M} (hs : coe) :
theorem set_has_minimal_iff_artinian {R : Type u_1} {M : Type u_2} [ring R] [ M] :
(∀ (a : set M)), a.nonempty(∃ (M' : M) (H : M' a), ∀ (I : M), I aI M'I = M')) M

A module is Artinian iff every nonempty set of submodules has a minimal submodule among them.

theorem is_artinian.set_has_minimal {R : Type u_1} {M : Type u_2} [ring R] [ M] [ M] (a : set M)) (ha : a.nonempty) :
∃ (M' : M) (H : M' a), ∀ (I : M), I aI M'I = M'
theorem monotone_stabilizes_iff_artinian {R : Type u_1} {M : Type u_2} [ring R] [ M] :
(∀ (f : →o order_dual M)), ∃ (n : ), ∀ (m : ), n mf n = f m) M

A module is Artinian iff every decreasing chain of submodules stabilizes.

theorem is_artinian.monotone_stabilizes {R : Type u_1} {M : Type u_2} [ring R] [ M] [ M] (f : →o order_dual M)) :
∃ (n : ), ∀ (m : ), n mf n = f m
theorem is_artinian.induction {R : Type u_1} {M : Type u_2} [ring R] [ M] [ M] {P : M → Prop} (hgt : ∀ (I : M), (∀ (J : M), J < IP J)P I) (I : M) :
P I

If ∀ I > J, P I implies P J, then P holds for all submodules.

theorem is_artinian.exists_endomorphism_iterate_ker_sup_range_eq_top {R : Type u_1} {M : Type u_2} [ring R] [ M] [I : M] (f : M →ₗ[R] M) :
∃ (n : ), n 0 (f ^ n).ker (f ^ n).range =

For any endomorphism of a Artinian module, there is some nontrivial iterate with disjoint kernel and range.

theorem is_artinian.surjective_of_injective_endomorphism {R : Type u_1} {M : Type u_2} [ring R] [ M] [ M] (f : M →ₗ[R] M) (s : function.injective f) :

Any injective endomorphism of an Artinian module is surjective.

theorem is_artinian.bijective_of_injective_endomorphism {R : Type u_1} {M : Type u_2} [ring R] [ M] [ M] (f : M →ₗ[R] M) (s : function.injective f) :

Any injective endomorphism of an Artinian module is bijective.

theorem is_artinian.disjoint_partial_infs_eventually_top {R : Type u_1} {M : Type u_2} [ring R] [ M] [I : M] (f : M) (h : ∀ (n : ), disjoint ( n) (order_dual.to_dual (f (n + 1)))) :
∃ (n : ), ∀ (m : ), n mf m =

A sequence f of submodules of a artinian module, with the supremum f (n+1) and the infinum of f 0, ..., f n being ⊤, is eventually ⊤.

@[class]
structure is_artinian_ring (R : Type u_1) [ring R] :
Prop
• to_is_artinian : R

A ring is Artinian if it is Artinian as a module over itself.

Instances
theorem is_artinian_ring_iff {R : Type u_1} [ring R] :
theorem ring.is_artinian_of_zero_eq_one {R : Type u_1} [ring R] (h01 : 0 = 1) :
theorem is_artinian_of_submodule_of_artinian (R : Type u_1) (M : Type u_2) [ring R] [ M] (N : M) (h : M) :
N
theorem is_artinian_of_quotient_of_artinian (R : Type u_1) [ring R] (M : Type u_2) [ M] (N : M) (h : M) :
(M N)
theorem is_artinian_of_tower (R : Type u_1) {S : Type u_2} {M : Type u_3} [comm_ring R] [ring S] [ S] [ M] [ M] [ M] (h : M) :
M

If M / S / R is a scalar tower, and M / R is Artinian, then M / S is also Artinian.

theorem is_artinian_of_fg_of_artinian {R : Type u_1} {M : Type u_2} [ring R] [ M] (N : M) (hN : N.fg) :
N
theorem is_artinian_of_fg_of_artinian' {R : Type u_1} {M : Type u_2} [ring R] [ M] (h : .fg) :
M
theorem is_artinian_span_of_finite (R : Type u_1) {M : Type u_2} [ring R] [ M] {A : set M} (hA : A.finite) :
A)

In a module over a artinian ring, the submodule generated by finitely many vectors is artinian.

theorem is_artinian_ring_of_surjective (R : Type u_1) [comm_ring R] (S : Type u_2) [comm_ring S] (f : R →+* S) (hf : function.surjective f) [H : is_artinian_ring R] :
@[protected, instance]
def is_artinian_ring_range {R : Type u_1} [comm_ring R] {S : Type u_2} [comm_ring S] (f : R →+* S)  :
theorem is_artinian_ring_of_ring_equiv (R : Type u_1) [comm_ring R] {S : Type u_2} [comm_ring S] (f : R ≃+* S)  :

format: plain


text:
View Single Post
 Thank you But if I want to calculate the entropy of surrounding? Then I have to use specific heat capacity of ice and latent heat fusion of ice.it will same as the entropy forward, then the change of entropy will be zero. But I think that is irreversible process..... Am I wrong?


text:
# Space Gravity issues, need help

This topic is 3590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I am attempting to make a 3d space game with spaceships and all that. I have it set up to load models but now I am trying to make the space ship have the "space" feel. I want it to when user presses a key, it goes forward pretty fast then slowly slows down like a ship would do. I don't want instant stops This is what I have so far. void Keyboard(unsigned char key, int x, int y) { #pragma unused (x, y) bool flag = false; rads=roty*(PI/180.0f); //convert degrees to radians cosa=cos(rads); sina=sin(rads); switch(key) { case 'w'://Move forward velx += cosa *10; velz += sina*10; } thePlayer.x += velx; thePlayer.z += velz; glutPostRedisplay(); } one of my problems I think is that, this function gets called only when a user presses the key. maybe? velx and vely are the velociy of the player, an thePlayer is the actual player movement. Everytime I press "W" it goes forward but instantly stops. Let me know what I am doing wrong and if you need any more info let me know. Thanks, Nahid569

##### Share on other sites
You should try some simple Euler integration instead, or similar.

Perhaps a bit technical, but: http://en.wikipedia.org/wiki/Euler_integration

The gist of it is this: instead of specifying the acceleration directly, you specify the force of the rockets/thrusters. This is exactly what would happen to a normal spaceship, as the rockets apply a force to the ship. This force "turns" into acceleration, and the acceleration makes the velocity change.

So, as long as the player depresses the "forward" key, have FengineX set to cos(rads)*EnginePower, similar for FengineY. If the key is not pressed, set them to zero.

Then, when updating the physics, first accumulate all forces. Since you want it to slowly halt, you'll want to introduce drag (albeit a bit unrealistic in outer space). A simple way to approximate this is to introduce a force which is proportional to the velocity, but "works" in the opposite direction. So

void AccumulateForces() {
ForceX = ForceY = 0;

ForceX += FengineX;
// compute drag
float dragX = -velX * dragCoefficient;
ForceX += dragX;

.. similar for Y

}

dragCoefficient specifies how "aerodynamical" the ship is. Try with zero first to see that it moves correctly, then try low values (ie 0.01) and adjust.

Next you want to perform the integration. For this you need to select a suitable "timestep" which is basically how large steps you take, and is typically around 30-60fps. Setting this as constant will make it depend on framerate, you can learn about how to fix that later.

float dt = 1.f / 30.f;

void TimeStep(float dt) {

AccumulateForces();

float aX = ForceX * inv_mass;
float aY = ForceY * inv_mass;

velX += dt * aX;
velY += dt * aY;

posX += dt * velX;
posY += dt * velY;
}

where inv_mass = 1 / mass of the ship.

Now, simply call TimeStep(dt) inside your game loop, and use posX and posY for the space ship position.

Think that should be it, though I haven't tested it :)

##### Share on other sites
If I understand you correctly, then what you have is this:
- while 'W' key is held down, ship moves forward
- as soon as 'W' key is released, ship stops immediately.

You are exactly correct that your main problem is that the code gets called only when the user presses a key.

What you instead need is to finagle some sort of main update loop that is always running, where on each iteration of the loop, you update the ship's position and redraw the frame. Once you have this sort of pattern in place, your life will be much easier. Now, I forget exactly how to do that in GLUT (I use SDL instead, which I recommend as a superior library to handle windowing and input, while still allowing you to use OpenGL), but read your documentation and I'm sure you can find a way.

Once that is in place, you can start taking Lord Crc's advice. Basically, you want a level of indirection -- instead of a key being down directly controlling the velocity (which in turn directly affects the ship's position), you want the key being down to control acceleration, which will affect the velocity much in the same way that velocity, in turn, affects position. In this manner, the key being held down will indirectly affect position. There'll then be room for you to apply some filters in between, the main one being applying a dampening effect of some sort to slow the ship's velocity down when the key isn't being held. (You probably also want to cap the speed at some maximum velocity also.)

I hope that helps -- good luck!

##### Share on other sites
The property you're describing is related to inertia and the conservation of momentum. Newton's first law sums all of this up well.

Viscosity is the property of a material to disperse the momentum of objects in contact with it. The higher the viscosity, the higher the rate of slow down. The ship should not slow down at all in space, since the vacuum of space is (practically) non-viscous. Since the momentum is not transferred from the ship to the vacuum, the ship must maintain the same velocity in order to ensure the conservation of momentum.

##### Share on other sites
Hey guys THANKS alot!

Those are gread ideas lord and I will use that but first I need to get a way to make a function that runs always. I do not have an idea how to do that. I was thinking of putting the entire movement thing in MAIN function because that is always running but I do not know how to do the keyboard thing outside of Keyboard function.

Is there a better way? Let me know

##### Share on other sites
The heart and soul of any 3D game is a Message loop. This is just an infinite loop that breaks only if the WM_QUIT message is posted to the window. You should handle your main logic updates in that loop and then your rendering functions.

##### Share on other sites
Quote:
 Original post by nahid569Hey guys THANKS alot!Those are gread ideas lord and I will use that but first I need to get a way to make a function that runs always. I do not have an idea how to do that. I was thinking of putting the entire movement thing in MAIN function because that is always running but I do not know how to do the keyboard thing outside of Keyboard function.Is there a better way? Let me know

There is. Do a google search for "glut main loop" and you'll find a few pages describing things to try. You just need to register some sort of idle function or main loop, and that should be enough. You can still have a distinct Keyboard function that works the way it does -- and you can just communicate messages from Keyboard to your main loop function by way of...heck, even a global variable just to get things working (but at some point that should become some sort of formalized message loop). Really, I'm sure GLUT has some framework for this in place already...it's just a matter of searching through documentation to find exactly what it is, and then get that working.

##### Share on other sites
Quote:
 Original post by nahid569I want it to when user presses a key, it goes forward pretty fast then slowly slows down like a ship would do

Er, a space ship wouldn't do that. What would make it slow down?
(That is assuming you meant spaceship in the above. If 'ship' refers to an actual sailing ship, it would slow down, yes)

##### Share on other sites
just put something like this
if(currentkeyboardstate.IsKeyDown(Keys.W)){ship.x.velocity = ship.x.velocity + shipscceleration;}if (paused = false){ship.x.velocity = ship.x.velocity - slowdown;}

something like that. Oh, and stuff doesn't slow down in space( only in sci-fi films)

##### Share on other sites
Quote:
Original post by Spoonbender
Quote:
 Original post by nahid569I want it to when user presses a key, it goes forward pretty fast then slowly slows down like a ship would do

Er, a space ship wouldn't do that. What would make it slow down?
(That is assuming you meant spaceship in the above. If 'ship' refers to an actual sailing ship, it would slow down, yes)

Was about to post the same. On earth what makes things slow down is various forms of friction: air resistance, ground friction, friction of moving parts.

In space there is a pretty good vacuum meaning there are none of these frictional forces. In space, a ship that's moving will effectively keep moving forever until it slows itself down with it's engines by producing a trust in the opposite direction. (I say "effectively" because space is not a perfect vacuum so over galactic distances there would perhaps be enough 'air resistance' to eventually slow you down)

-me

##### Share on other sites
Quote:
 There'll then be room for you to apply some filters in between, the main one being applying a dampening effect of some sort to slow the ship's velocity down when the key isn't being held. (You probably also want to cap the speed at some maximum velocity also.)

That's the beauty of having a drag force, you get the slowdown when there's no force applied, and the maximum velocity is determined by the drag coefficient and the maximum force (thrust).

##### Share on other sites
wow thanks alot you guys are helpful.
I think i get what you guys are saying so i set up a glutIDleFunc and tried it like that but that still causes problems, so im going to try glutMainLoop later today.

About my spaceship, I knaow it should keep going but if that happened then it owuld be cool but then there would be NO way for the user to stop his ship. Maybe I can do that but wouldnt that be a weird game where the user never stops.

##### Share on other sites
Quote:
Original post by Palidine
Quote:
Original post by Spoonbender
Quote:
 Original post by nahid569I want it to when user presses a key, it goes forward pretty fast then slowly slows down like a ship would do

Er, a space ship wouldn't do that. What would make it slow down?
(That is assuming you meant spaceship in the above. If 'ship' refers to an actual sailing ship, it would slow down, yes)

Was about to post the same. On earth what makes things slow down is various forms of friction: air resistance, ground friction, friction of moving parts.

In space there is a pretty good vacuum meaning there are none of these frictional forces. In space, a ship that's moving will effectively keep moving forever until it slows itself down with it's engines by producing a trust in the opposite direction. (I say "effectively" because space is not a perfect vacuum so over galactic distances there would perhaps be enough 'air resistance' to eventually slow you down)

-me

If you take the average density of the universe to be 10^-27 kg/m^3, that's roughly one proton per cubic metre.

If you were to travel from one edge of the galaxy to the other (roughly 10^21 metres), and assumed that you would collide with one proton for every metre travelled, it would have the total effect of colliding with a single 1 milligram object. Pitting that against a spaceship of 10^4 or so kg would produce a negligible amount of slow down.

##### Share on other sites
Quote:
 Original post by nahid569About my spaceship, I knaow it should keep going but if that happened then it owuld be cool but then there would be NO way for the user to stop his ship. Maybe I can do that but wouldnt that be a weird game where the user never stops.

You slow down by rotating the ship to face backwards and firing the main engine.

Similarly, to make turns, you point the nose of the ship towards the desired center of the turn, then fire the engine and throttle it to provide a centripetal force.

Play Asteroids? or Escape Velocity? they tend to be pretty good examples of this working out pretty well.

##### Share on other sites

This topic is 3590 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628682
• Total Posts
2984190

• 13
• 12
• 9
• 10
• 10


text:
## Caractérisation des groupes de cohomologie d’un groupe topologique en termes de suites exactes.(English)Zbl 0537.22002

Let G be a topological group and let A be a smooth G-module, i.e., a G- module in which every element has an isotropy group open in G. The author considers the complex whose n-cochains are the mappings $$c:G^ n\to A$$ such that, for $$0\leq i\leq n$$ and for each $$(g_ 1,g_ 2,...,g_ i)\in G^ i,$$ there exists a neighborhood U of $$1_ G$$ in G with $c(g_ n,...,g_{i+2},g_{i+1}u,\quad g_ i,...,g_ 1)=c(g_ n,...,g_{i+2},g_{i+1},g_ i,...,g_ 1)$ for all $$(g_ n,...,g_{i+1})\in G^{n-i}$$ and all $$u\in U$$ [J. Algebra, 49, 422-440 (1977; Zbl 0368.22002)].
The author shows that, for each $$n\geq 2$$, there exists an isomorphism of the n-th cohomology group $$H^ n(G,A)$$ of this complex onto a cohomology group defined in terms of a set of exact sequences which begin by A and end by G.
Reviewer: U.Cattaneo

### MSC:

 22A05 Structure of general topological groups 20J05 Homological methods in group theory 16W20 Automorphisms and endomorphisms

Zbl 0368.22002


text:
Waste less time on Facebook — follow Brilliant.
×
Back to all chapters

Orbits

Believe it or not — the world does not revolve around you. Accept this harsh truth, then calculate the beguiling dance of objects in orbit, from binary stars to the symphony of our Solar System.

Deriving Kepler's Laws

Two satellites each of mass $$m_1 = 3.00 \text{ kg}$$ and mass $$m_2 = 6.00 \text{ kg}$$ revolve around the same planet. The respective radii of their orbits are $$r_1 = 2.00 \times 10^5 \text{ m}$$ and $$r_2 = 1.80 \times 10^6 \text{ m}.$$ If the time period of the satellite of mass $$m_1$$ is $$T_1 = 4.00 \times 10^5 \text{ s},$$ what is that of the satellite of mass $$m_2?$$

Assumptions and Details

• The universal gravitational constant is $$G=6.67 \times 10^{-11} \text{ N}\cdot\text{m}^2\text{/kg}^2.$$

A box of mass $$m = 3 \text{ kg}$$ is placed on the edge of a merry-go-round of radius $$r= 4 \text{ m}.$$ The coefficient of static friction between the box and the merry-go-round is $$\mu = 0.3 .$$ What is the merry-go-round's speed squared at the moment the box slides off?

Assumptions and Details

• The gravitational acceleration is $$g= 10 \text{ m/s}^2.$$

A satellite of mass $$m = 2.00 \times 10^3 \text{ kg}$$ revolves around a planet of mass $$M = 6.00 \times 10^{16} \text{ kg},$$ with constant speed. If the radius of the orbit is $$r = 2.00 \times 10^5 \text{ m},$$ what is the satellite's approximate speed?

Assumptions and Details

• The universal gravitational constant is $$G=6.67 \times 10^{-11} \text{ N}\cdot\text{m}^2\text{/kg}^2.$$

A satellite of mass $$m = 5.00 \times 10^3 \text{ kg}$$ revolves around a planet of mass $$M = 5.00 \times 10^{16} \text{ kg},$$ at constant speed. If the radius of the orbit is $$r = 3.00 \times 10^5 \text{ m} ,$$ what is the approximate period of the revolution?

Assumptions and Details

• The universal gravitational constant is $$G=6.67 \times 10^{-11} \text{ N}\cdot\text{m}^2\text{/kg}^2.$$

Two identical satellites each of mass $$m = 6.00 \times 10 ^3 \text{ kg}$$ revolve around a planet of mass $$M = 5.00 \times 10^{16} \text{ kg}.$$ If the respective radii of their orbits are $$r_1 = 2.00 \times 10^5 \text{ m}$$ and $$r_2 = 1.80 \times 10^6 \text{ m} ,$$ what is the ratio between the speeds of the two satellites?

Assumptions and Details

• The universal gravitational constant is $$G=6.67 \times 10^{-11} \text{ N}\cdot\text{m}^2\text{/kg}^2.$$
×

Problem Loading...

Note Loading...

Set Loading...


text:
Article | Open | Published:

# High Quantum Yield Green-Emitting Carbon Dots for Fe(ІІІ) Detection, Biocompatible Fluorescent Ink and Cellular Imaging

## Abstract

In the present work, we reported the luminescence of a green-emitting carbon dots (CDs) synthesized via solid state reaction method using diammonium hydrogen citrate and urea as a starting materials. The obtained green-emitting CDs shows strong absorption in the 350–450 nm region and gives intense green emission (λmax = 537 nm) with quantum yield as high as 46.4% under 420 nm excitation. The obtained green-emitting CDs also demonstrates high photo-stability, which is evidenced by the fact that its emission intensity almost has no change under irradiation by a 365 nm UV lamp for 2 hours. Moreover, the obtained green-emitting CDs shows high sensitivity and selectivity for the detection of Fe3+, and their emission intensity response towards Fe3+ ions is highly linear (R2 = 0.995) over the concentration range from 25 to 300 µM, which could provide an effective platform for detection of Fe3+. Mostly important, we further demonstrate that such photoluminescent green-emitting CDs exhibits low toxicity and are biocompatible for use with in cellular imaging. Combining with low cytotoxicity, good water solubility and excellent luminescence properties, green-emitting CDs could be used as a biocompatible fluorescent ink in future applications.

## Introduction

As a new comer of fluorescent nanoparticle, carbon dots (CDs) continue to fascinate a mankind because of their outstanding physiochemical properties such as high luminescence, low-toxicity, surface modification flexibility, super resistance to photobleaching, good biocompatibility and excellent water solubility1,2,3,4. CDs is intensely recognized for their potential applications in bio-imaging, optoelectronics, photocatalysis, light-emitting diodes, sensing and energy conversion/storage devices5,6,7,8,9,10,11. These excellent physiochemical properties and their numerous applications make CDs a promising alternative to organic dyes, polymer dots and semiconductors quantum dots that have been extensively studied over the past decades12,13. However, the toxicity, poor water solubility and photobleaching, complex synthesis procedure and low quantum yield (QY) of the latter materials (organic dyes, polymer dots and semiconductors quantum dots) have limited their practical applications14,15,16,17.

After a careful reviewing of the existing literatures, it is found that many different types of materials and approaches have been used to synthesize CDs. The reported raw materials vary from laboratory-produced chemicals to natural products, and approaches include laser ablation, pyrolysis, electrochemical oxidation, hydro/solvo-thermal reactions, and microwave treatment et al.15,18,19,20,21,22. However, most of the resultant carbon dots emit blue and blue-green, and few are found to emit in longer wavelengths10,23,24,25,26. In addition, the methods mentioned above are not able to produce large quantity of product. Moreover, carbon dots suffer from the difficulty in producing high quantum yield (QY) and long wavelength (>500 nm) emissive products, which are considered as a major disadvantage of CDs. Therefore, it is urgent to develop a new way to synthesize carbon dots that can emit a longer emission beyond blue region, so as to enrich the luminescence properties and diversify its applications.

Herein, we report for the first time highly fluorescent green-emitting carbon dots through a facile solid state reaction method with quantum yield as high as 46.4% under 420 nm excitation. The resulting green-emitting CDs can emit bright and stable green luminescence at high salt concentration and show good photostability under continuous 365 nm UV lamp irradiation for 2 hours. The obtained green-emitting CDs possess excitation-dependent emission and short monoexponential fluorescent lifetime. Besides, the green-emitting CDs is shown to be able to detect Fe3+ ions with good sensitivity and selectivity over the concentration range from 25 to 300 µM. Because of their outstanding photoluminescence properties and low-cytotoxicity, green-emitting CDs is particularly suitable for biocompatible fluorescent ink and also fluorescent probe for cellular imaging. For their easy preparation and unique optical properties make these CDs promising for numerous applications in modern science and technology.

## Results and Discussion

### Photoluminescent properties of the green-emitting CDs

Different combinations of materials with diammonium hydrogen citrate were used to synthesize carbon dots, however, only the carbon dots synthesized by using diammonium hydrogen citrate with urea were found give green emission, and all the rest give blue emission (see supporting information Figure S1). As a result, urea with diammonium hydrogen citrate are ultimately selected due to their products yielded green emission with high quantum yield, indicating that green emissive products with highly quantum yield are dominate to synthesize carbon dots.

The obtained carbon dots are yellow under day light irradiation but green under a 365 nm UV lamp irradiation, which can be seen in Fig. 1a. The absorption and photoluminescence (PL) properties of the aqueous green-emitting CDs is characterized (Fig. 1b) by the ultraviolet-visible (UV-Vis) and PL spectrometer. In the UV-Vis spectrum, it can be seen clearly that there are two absorption peaks appeared at 274 and 410 nm. The absorption peak at 274 nm is attributed to carbonic core center and the peak catered at 410 nm is ascribed to surface or molecule center27. Under 420 nm excitation, the carbon dots yield green emission at 537 nm (see Fig. 1b). The excitation spectrum obtained by monitoring the green emission at 537 nm is consistent with the result presented in the absorption spectrum. This behavior also indicates that there are at least two types of excitation energy trapping on the surface of CDs19. In additon, it is found that the green-emitting CDs exhibit excitation-dependent emission as shown in Fig. 1c. When the excitation wavelenght is increased from 360 to 500 nm with the increment of 20 nm, the emission peak is red shifted from 525 to 570 nm. The excitation-dependent emission behavior of greem-emitting CDs is related to be the non-uniform particle size and distribution of different surface states7,28,29. TEM image confirms that the size of the particle is not very uniform (see Fig. 2). The QYs of the green-emitting CDs is determined to be respectable in either organic solvent (e.g. ethanol, 46.4%, Figure S2) or DI water (15.5%, Figure S3) under 420 nm excitation by using a rhodamine 6 G (95%) solution as a reference. To best of our knowledge, this is the highest QY value for the green-emitting CDs reported so far. Figure 1d presents the decay curve of the obtained green-emitting CDs with excitation and emission wavelengths in 420 and 537 nm respectively. The decay curve can be fitted by a single exponential function:

$${\rm{N}}({\rm{t}})={{\rm{A}}}_{0}\,exp(-{\rm{t}}/{\rm{\tau }})$$
(1)

The decay lifetime was determined to be 7.2 ns, and such a short lifetime indicates that the luminescence mechanism of our obtained green-emitting CDs is the radiative recombination nature19.

High stability is one of the important factors in nano-size flourescent materials, which plays a significant role to demonstrate their application in various fields. The photo-stability and salt (KCl) effect on the green-emitting CDs have been investigated. It is confirmed that green-emitting CDs is highly stable under continuous irradiation of a 365 nm UV lamp for two hours (supporting information Fig. S4a). Furthermore, the prepared green-emitting CDs has favorable ionic strength at high salt (KCl) concentration of about 2 M (supporting information Fig. S4b). Moreover, the green-emitting CDs is confirmed to be relatively stable over the pH range from 2 to 9.5 as shown in the (supporting information Fig. S5).

The obtained green-emitting CDs in aqueous state exhibits a long-term homogeneous phase without any noticeable precipitation at room temperature. The TEM images and size distribution of the prepared green-emitting CDs are displayed in Fig. 2a, from which it can be seen clearly that the obtained particles are scattered in regular manner and possess closely spherical pattern. The inset HRTEM image demonstrate the crystallinity of the green-emitting CDs with a lattice parameter of 0.21 nm, which agrees with (100) lattice fringes of graphite30. The size of the obtained green-emitting CDs is not very uniform and it is distributed in the ranges from 2 to 7 nm. The average size of the green-emitting CDs is 4.6 nm as displayed in Fig. 2b.

The XRD profile of the green-emitting CDs shows (002) peak centred at 26° as shown in the Fig. 3a. The result is similar to that of the graphite, showing highly disordered carbon atoms31,32. The structure and composition of green-emitting CDs were characterized by FT-IR spectroscopy. As shown in Fig. 3b, the synthesized green-emitting CDs show main absorption bands related to OH/NH stretching vibration at 3435 to 3175 cm−1. These functional groups improve the hydrophilicity and stability of green-emitting CDs in aqueous systems3,33. The weak peak at 2808 cm−1 is related to the C-H band stretching vibration. The peaks at 1708 and 1597 cm−1 are ascribed to the O-C = O and C = C stretching vibrations, respectlively23. Moreover, the CH/CN band is starching at 1366 cm−1 on the surface of the green-emitting CDs. The characteristic stretch band of the amine H-N bond is at 1150 cm−1. The IR bands appear within the range of 1050 to 580 cm−1, which correspond to the stretching vibration of C-O, CH2 and C-N, respectively34. The unsaturated carbon bonds were further examined by the Raman spectrum, which shows the feature of D band at 1375 cm−1 and G band at 1596 cm−1 (supporting information, Fig. S6). The ratio of the relative intensity of D band and G band (I D /I G ) is about 0.96, indicating the disorder nature of the green-emitting CDs with poor crystalline framework32.

X-ray photoelectron spectroscopy (XPS) measurements were performed for the surface elemental analysis of green-emitting CDs. The wide XPS spectrum of the green-CDs as shown in Fig. 4a clearly reveals that carbon (284.6 eV), nitrogen (398.8 eV), and oxygen (531.3 eV) are presented at the surface of green-emitting CDs. In the expanded XPS spectra (Fig. 4b), the C1s band can be deconvoluted into three peaks, which were assigned to sp2 carbons (C = C, 284.5 eV), sp3 (C-O/C-N, 286.1 eV), carboxyl carbons (O-C = O, 288.1 eV). The N1s band can be deconvoluted into three peaks (Fig. 4c), which were corresponded to (C-N-C, 398.8 eV), amino N (N-H, 399.5 eV) and (C3-N, 400.5 eV). The oxygen containing groups are also presented in the surface of the green-emitting CDs (Fig. 4d), the O1s band contains two peaks associated to sp2 (C = O, 531.3 eV) and sp3 (C-O, 532.3 eV)35,36.

## Application of green-emitting CDs

### Detection of Fe3+ in an aqueous solution

The Fe3+ plays an important role in life due to their essential function in oxygen metabolism, oxygen transport, transfer of electrons and catalytic procedures37. Recently, carbon fluorescent dots have been used as a fluorescent probe for heavy metal ions, showing good sensitivity and selectivity towards different metal ions. The photographs in Fig. 5a show the emission of green-emitting CDs before and after adding Fe3+ ions. Many common metal ions have been used for detection (Fig. 5b), but only Fe3+ is able to quench the fluorescence of green-emitting CDs, suggesting the green-emitting CDs have a potential to detect Fe3+ ions via luminescence measurements. The observed fluorescent quenching by Fe3+ ions could be attributed to its strong interaction with surface groups of green-emitting CDs, which facilitate the transformation of photoelectron from CDs to Fe3+ ions7,38. Figure 5c shows the fluorescent spectra of the green-emitting CDs aqueous solution containing different concentration of Fe3+ ions: 25, 50, 75, 100, 125, 150, 175, 200, 225 and 300 µM. The photoluminescence spectra are decreasing by regular manner adding the different concentration of Fe3+ (excitation wavelength 420 nm). The ratios between (f/f0) and Fe3+ concentration have a good linear relationship with correlation coefficient R2 of 0.995 as shown in Fig. 5d. The limit of detection (LOD) is calculated to be 19 µM using the 3 times σ/K ratio. The observed results clearly illustrating that the green-emissive CDs have a good sensitivity and selectivity towards Fe3+ ions, which can be used as a practical application. The analytical performances of recent reported sensors for the detection of Fe3+ are summarized in (Table 1).

### Biocompatible fluorescent ink

The low/non-toxicity at high concentration of green-emitting CDs indicates that it can possibly be used as a new type of biocompatible fluorescent ink. Figure 6a and b, show the green-emitting CDs based fluorescent fingerprint on filter paper under sun light and UV lamp (365 nm) irradiation. Figure 6c shows the fluorescent characters on filter paper irradiated by 365 nm UV beam. The carbon dots based fluorescent ink doesn’t contaminate fingers and can be easily washed off from water4,27.

### Cellular imaging in HeLa cells

Carbon dots have a promising candidate for biological applications because of their non/low toxicity, good stability and highly luminescent materials49,50,51. The cytotoxicity of the green-emitting CDs was evaluated by using a standard MTT assay with HeLa cells8. As shown in the Fig. 7a, the average cell viability is above 90% with concentrations ranging from 100 to 500 µg/mL for 24 hours. The result suggests that the green-emitting CDs has very low cytotoxicity and good biocompatibility with high concentration about 500 µg/mL. Figure 7b shows the bright field image of the HeLa cells. After incubating the green-emitting CDs to HeLa cells for imaging, cells emitted a remarkable green fluorescence (Fig. 7c and d) and showed good morphology under confocal laser scanning microscopy. The fluorescence signals reveal that green-emitting CDs is mainly inside the cell membrane, suggesting that the green-emitting CDs can pass through cell membrane and enter into the cells cytoplasm. These results indicate good cell permeability of the green-emitting CDs towards HeLa cells, which further confirm the merits of the green-emitting CDs.

## Conclusion

In this work, we report the optical properties and possible applications of a green-emitting CDs synthesized by solid state reaction approach. Under 420 nm excitation, the obtained CDs emits bright green emission with quantum yield of 46.4%, which is the highest QY value for the green-emitting CDs reported so far. Besides, the obtained green-emitting CDs is proved to have favorable ionic strength, high stability, excellent water solubility and excitation dependent emission. The synthesized carbon dots have been demonstrated the potential to be used as a sensor of Fe3+ ions, fluorescent based-ink and cell marker. The low cost, biocompatibility, and low-toxicity of the green-emitting CDs and their distinct PL properties indicate that green-emitting CDs could potentially be synthesized on an industrial scale and could be used for numerous possible applications.

## Methods

### Materials

Diammonium hydrogen citrate, urea, L-cystiene, HD-met-oH, glycine, L-glutathione (GSH) and the salts (PbCl2, Cr(NO3)3, CuCl2, HgCl2, NiCl2, FeCl2, FeCl3, CdCl2, CoCl2, SnCl2, HgCl2, MnCl2 and SrCl2) were purchased from Sinopharm Chemical Reagent Co., Ltd, Rhodamine 6 G (99%) was purchased from Adamas Reagent Co., Ltd. All the chemicals were of analytical grade and used without further purification. The deionzed water was used throughout the experiments.

### Synthesis of green-emitting CDs

For a typical synthesis process diammonium hydrogen citrate (0.2 g) and urea (0.2 g) were grinded homogeneously in agate morter, and then the obtained mixture was heated in an oven at 180 °C for 1 hour in air. After the reaction was over, the resulting product was dissolved in water. The obtained solution was purified in a centrifuge at high speed (12000 rpm, 5 min) to remove the large particles. Afterword, the solution was further filtered via 0.22 µm filter membrane to obtain the pure CDs. The obtained solution of CDs was dispersed in deionize water for further characterizations.

### Characterizations

The morphology and size of the samples was observed by (FEI Tecnai F30 transmission electron microscope (TEM) operating at 300 kV). Photoluminescence (PL) and photoluminescence excitation (PLE) spectra were recorded using a Fluorolog-3 Spectrofluorometer equipped with a 450 W Xenon light source. Ultraviolet-visible (UV-Vis) absorption spectra were recorded using a Lambda 950, Perkin-Elmer (USA) UV-Vis-NIR spectrophotometer. The phase purity of fluorescent CDs was analyzed by X-ray diffraction (XRD) using a Bruker D2 PHASER X-ray Diffractometer with graphite monochromator using Cu Kα radiation (λ = 1.54056 Å), operating at 30 kV and 15 mA. Fourier transform infrared spectroscopy (FT-IR) was recorded a Nicolet 670 spectrophotometer at room temperature. X-ray photoelectron spectra (XPS) were acquired using a (XPS, PHI- 5702, Physical Electronics) with a monochromatic Al Kα irradiation source. The PL decay curves were measured by a FLS-920T fluorescence spectrophotometer with an nF900 nanosecond flash lamp as the light source. Raman spectroscopy was measured using a (JY-HR800 micro-Raman spectroscopy) with a 532 nm wavelength of YAG laser.

Publisher's note: Springer Nature remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.

## References

1. 1.

Zheng, Y. et al. A facile approach for the synthesis of highly luminescent carbon dots using vitamin-based small organic molecules with benzene ring structure as precursors. RSC Advances 5, 90245–90254 (2015).

2. 2.

Lan, M. et al. A carbon dot-based fluorescence turn-on sensor for hydrogen peroxide with a photo-induced electron transfer mechanism. Chemical Communications 51, 15574–15577 (2015).

3. 3.

Gao, Z.-h, Lin, Z.-z, Chen, X.-m, Zhong, H.-p & Huang, Z.-y A fluorescent probe based on N-doped carbon dots for highly sensitive detection of Hg2 + in aqueous solutions. Analytical Methods 8, 2297–2304 (2016).

4. 4.

Zhu, S. et al. Highly photoluminescent carbon dots for multicolor patterning, sensors, and bioimaging. Angewandte Chemie 52, 3953–3957 (2013).

5. 5.

Zhang, Y.-Q. et al. One-pot synthesis of N-doped carbon dots with tunable luminescence properties. Journal of Materials Chemistry 22, 16714–16718 (2012).

6. 6.

Algarra, M. et al. Carbon dots obtained using hydrothermal treatment of formaldehyde. Cell imaging in vitro. Nanoscale 6, 9071 (2014).

7. 7.

Ding, H., Wei, J.-S. & Xiong, H.-M. Nitrogen and sulfur co-doped carbon dots with strong blue luminescence. Nanoscale 6, 13817–13823 (2014).

8. 8.

Ding, H., Yu, S.-B., Wei, J.-S. & Xiong, H.-M. Full-Color Light-Emitting Carbon Dots with a Surface-State-Controlled Luminescence Mechanism. ACS Nano 10, 484–491 (2016).

9. 9.

Fernandes, D., Krysmann, M. J. & Kelarakis, A. Carbon dot based nanopowders and their application for fingerprint recovery. Chemical Communications 51, 4902–4905 (2015).

10. 10.

Jiang, K. et al. Red, Green, and Blue Luminescence by Carbon Dots: Full-Color Emission Tuning and Multicolor Cellular Imaging. Angewandte Chemie International Edition 54, 5360–5363 (2015).

11. 11.

Zhang, Y.-Q., Ma, D.-K., Zhang, Y.-G., Chen, W. & Huang, S.-M. N-doped carbon quantum dots for TiO2-based photocatalysts and dye-sensitized solar cells. Nano Energy 2, 545–552 (2013).

12. 12.

Wu, C. & Chiu, D. T. Highly Fluorescent Semiconducting Polymer Dots for Biology and Medicine. Angewandte Chemie International Edition 52, 3086–3109 (2013).

13. 13.

Zhou, D. et al. Conducting the Temperature-Dependent Conformational Change of Macrocyclic Compounds to the Lattice Dilation of Quantum Dots for Achieving an Ultrasensitive Nanothermometer. ACS Nano 7, 2273–2283 (2013).

14. 14.

Dong, Y. et al. Carbon-based dots co-doped with nitrogen and sulfur for high quantum yield and excitation-independent emission. Angewandte Chemie 52, 7800–7804 (2013).

15. 15.

De, B. & Karak, N. A green and facile approach for the synthesis of water soluble fluorescent carbon dots from banana juice. RSC Advances 3, 8286 (2013).

16. 16.

Jaiswal, A., Ghosh, S. S. & Chattopadhyay, A. One step synthesis of C-dots by microwave mediated caramelization of poly(ethylene glycol). Chemical communications 48, 407–409 (2012).

17. 17.

Ding, C., Zhu, A. & Tian, Y. Functional Surface Engineering of C-Dots for Fluorescent Biosensing and in Vivo Bioimaging. Accounts of Chemical Research 47, 20–30 (2014).

18. 18.

Qin, X., Lu, W., Asiri, A. M., Al-Youbi, A. O. & Sun, X. Microwave-assisted rapid green synthesis of photoluminescent carbon nanodots from flour and their applications for sensitive and selective detection of mercury(II) ions. Sensors and Actuators B: Chemical 184, 156–162 (2013).

19. 19.

Yang, Z. et al. Nitrogen-doped, carbon-rich, highly photoluminescent carbon dots from ammonium citrate. Nanoscale 6, 1890–1895 (2014).

20. 20.

Sun, D. et al. Hair fiber as a precursor for synthesizing of sulfur- and nitrogen-co-doped carbon dots with tunable luminescence properties. Carbon 64, 424–434 (2013).

21. 21.

Shi, L. et al. Carbon dots with high fluorescence quantum yield: the fluorescence originates from organic fluorophores. Nanoscale 8, 14374–14378 (2016).

22. 22.

Ramanan, V. et al. Outright Green Synthesis of Fluorescent Carbon Dots from Eutrophic Algal Blooms for In Vitro Imaging. ACS Sustainable Chemistry & Engineering 4, 4724–4731 (2016).

23. 23.

Jiang, K. et al. Bright-Yellow-Emissive N-Doped Carbon Dots: Preparation, Cellular Imaging, and Bifunctional Sensing. ACS Applied Materials & Interfaces 7, 23231–23238 (2015).

24. 24.

Kim, E., Koh, M., Lim, B. J. & Park, S. B. Emission Wavelength Prediction of a Full-Color-Tunable Fluorescent Core Skeleton, 9-Aryl-1,2-dihydropyrrolo[3,4-b]indolizin-3-one. Journal of the American Chemical Society 133, 6642–6649 (2011).

25. 25.

Liu, S., Zhao, N., Cheng, Z. & Liu, H. Amino-functionalized green fluorescent carbon dots as surface energy transfer biosensors for hyaluronidase. Nanoscale 7, 6836–6842 (2015).

26. 26.

Wang, H. et al. Excitation wavelength independent visible color emission of carbon dots. Nanoscale 9, 1909–1915 (2017).

27. 27.

Xu, M. et al. A green heterogeneous synthesis of N-doped carbon dots and their photoluminescence applications in solid and aqueous states. Nanoscale 6, 10307–10315 (2014).

28. 28.

Wang, C. et al. A hydrothermal route to water-stable luminescent carbon dots as nanosensors for pH and temperature. Carbon 82, 87–95 (2015).

29. 29.

Li, W. et al. Simple and Green Synthesis of Nitrogen-Doped Photoluminescent Carbonaceous Nanospheres for Bioimaging. Angewandte Chemie International Edition 52, 8151–8155 (2013).

30. 30.

Chen, B. B. et al. A large-scale synthesis of photoluminescent carbon quantum dots: a self-exothermic reaction driving the formation of the nanocrystalline core at room temperature. Green Chemistry 18, 5127–5132 (2016).

31. 31.

Qu, S., Wang, X., Lu, Q., Liu, X. & Wang, L. A Biocompatible Fluorescent Ink Based on Water-Soluble Luminescent Carbon Nanodots. Angewandte Chemie International Edition 51, 12215–12218 (2012).

32. 32.

Dong, Y. et al. Graphene quantum dots, graphene oxide, carbon quantum dots and graphite nanocrystals in coals. Nanoscale 6, 7410–7415 (2014).

33. 33.

Chen, B. B. et al. A large-scale synthesis of photoluminescent carbon quantum dots: a self-exothermic reaction driving the formation of the nanocrystalline core at room temperature. Green Chem. 18, 5127–5132 (2016).

34. 34.

Wang, D.-Y. et al. Photoluminescence quenching of graphene oxide by metal ions in aqueous media. Carbon 82, 24–30 (2015).

35. 35.

Guo, Y., Wang, Z., Shao, H. & Jiang, X. Hydrothermal synthesis of highly fluorescent carbon nanoparticles from sodium citrate and their use for the detection of mercury ions. Carbon 52, 583–589 (2013).

36. 36.

Zhang, J., Yang, L., Yuan, Y., Jiang, J. & Yu, S.-H. One-Pot Gram-Scale Synthesis of Nitrogen and Sulfur Embedded Organic Dots with Distinctive Fluorescence Behaviors in Free and Aggregated States. Chemistry of Materials 28, 4367–4374 (2016).

37. 37.

Qu, K., Wang, J., Ren, J. & Qu, X. Carbon Dots Prepared by Hydrothermal Treatment of Dopamine as an Effective Fluorescent Sensing Platform for the Label-Free Detection of Iron(III) Ions and Dopamine. Chemistry – A European Journal 19, 7243–7249 (2013).

38. 38.

Wu, Z. L. et al. One-pot hydrothermal synthesis of highly luminescent nitrogen-doped amphoteric carbon dots for bioimaging from Bombyx mori silk - natural proteins. Journal of Materials Chemistry B 1, 2868–2873 (2013).

39. 39.

Liu, Y. et al. One-step synthesis of robust nitrogen-doped carbon dots: acid-evoked fluorescence enhancement and their application in Fe3 + detection. Journal of Materials Chemistry A 3, 17747–17754 (2015).

40. 40.

Yang, G., Wan, X., Su, Y., Zeng, X. & Tang, J. Acidophilic S-doped carbon quantum dots derived from cellulose fibers and their fluorescence sensing performance for metal ions in an extremely strong acid environment. Journal of Materials Chemistry A 4, 12841–12849 (2016).

41. 41.

Yu, J., Xu, C., Tian, Z., Lin, Y. & Shi, Z. Facilely synthesized N-doped carbon quantum dots with high fluorescent yield for sensing Fe3+. New Journal of Chemistry 40, 2083–2088 (2016).

42. 42.

Xu, J., Zhou, Y., Liu, S., Dong, M. & Huang, C. Low-cost synthesis of carbon nanodots from natural products used as a fluorescent probe for the detection of ferrum(iii) ions in lake water. Analytical Methods 6, 2086–2090 (2014).

43. 43.

Li, G., Lv, N., Bi, W., Zhang, J. & Ni, J. Nitrogen-doped carbon dots as a fluorescence probe suitable for sensing Fe3 + under acidic conditions. New Journal of Chemistry 40, 10213–10218 (2016).

44. 44.

Zhang, Y.-L. et al. Graphitic carbon quantum dots as a fluorescent sensing platform for highly efficient detection of Fe3 + ions. RSC Advances 3, 3733–3738 (2013).

45. 45.

Miao, P., Tang, Y., Han, K. & Wang, B. Facile synthesis of carbon nanodots from ethanol and their application in ferric(iii) ion assay. Journal of Materials Chemistry A 3, 15068–15073 (2015).

46. 46.

Liu, M., Xu, Y., Niu, F., Gooding, J. J. & Liu, J. Carbon quantum dots directly generated from electrochemical oxidation of graphite electrodes in alkaline alcohols and the applications for specific ferric ion detection and cell imaging. Analyst 141, 2657–2664 (2016).

47. 47.

Wang, D., Wang, L., Dong, X., Shi, Z. & Jin, J. Chemically tailoring graphene oxides into fluorescent nanosheets for Fe3 + ion detection. Carbon 50, 2147–2154 (2012).

48. 48.

Gong, X. et al. Facile synthesis of nitrogen-doped carbon dots for Fe3 + sensing and cellular imaging. Analytica Chimica Acta 861, 74–84 (2015).

49. 49.

Zheng, M. et al. One-Pot To Synthesize Multifunctional Carbon Dots for Near Infrared Fluorescence Imaging and Photothermal Cancer Therapy. ACS Applied Materials & Interfaces 8, 23533–23541 (2016).

50. 50.

Ge, J. et al. Red-Emissive Carbon Dots for Fluorescent, Photoacoustic, and Thermal Theranostics in Living Mice. Advanced Materials 27, 4169–4177 (2015).

51. 51.

Zeng, Y.-W. et al. N, S co-doped carbon dots with orange luminescence synthesized through polymerization and carbonization reaction of amino acids. Applied Surface Science 342, 136–143 (2015).

## Acknowledgements

This work was supported by the National Natural Science Funds of China (grant no. 51372105, 51602137), and the Fundamental Research Funds for the Central Universities (lzujbky-2016–118). One of the authors (W.U. Khan) would like to thank for the financial support from China Scholarship Council.

## Author information

### Affiliations

1. #### School of Physical Science and Technology, Lanzhou University, Lanzhou, 730000, P. R. China

• Waheed Ullah Khan
• , Deyin Wang
• , Zuobin Tang
• , Xinlong Ma
• , Xin Ding
• , Shanshan Du
•  & Yuhua Wang

• Wei Zhang

### Contributions

W.K. and D.W. conducted the most of investigation for the samples. W.K. wrote the main paper. D.W. and W.Z. designed the concept and the experiment method of the research. D.W. and Y.W. supervised the project, had given valuable advices on the proceeding of this work and revised the manuscript. Z.T. and S.D. supported the characterization of the samples. D.X. and X.M. revised the manuscript. All authors discussed the results and commented on the manuscript at all stages.

### Competing Interests

The authors declare that they have no competing interests.

### Corresponding authors

Correspondence to Deyin Wang or Yuhua Wang.


text:
# Achievable Catalog Size in Peer-to-Peer Video-on-Demand Systems

1 GANG - Networks, Graphs and Algorithms
LIAFA - Laboratoire d'informatique Algorithmique : Fondements et Applications, Inria Paris-Rocquencourt
Abstract : We analyze a system where $n$ set-top boxes with same upload and storage capacities collaborate to serve $r$ videos simultaneously (a typical value is $r=n$). We give upper and lower bounds on the catalog size of the system, i.e. the maximal number of distinct videos that can be stored in such a system so that any demand of at most $r$ videos can be served. Besides $r/n$, the catalog size is constrained by the storage capacity, the upload capacity, and the maximum number of simultaneous connections a box can open. We show that the achievable catalog size drastically increases when the upload capacity of the boxes becomes strictly greater than the playback rate of videos.
Document type :
Conference papers
Domain :

Cited literature [7 references]

https://hal.inria.fr/inria-00471724
Contributor : Laurent Viennot <>
Submitted on : Thursday, April 8, 2010 - 5:53:11 PM
Last modification on : Friday, January 4, 2019 - 5:33:21 PM
Long-term archiving on : Friday, October 19, 2012 - 11:26:40 AM

### File

iptps2008.pdf
Files produced by the author(s)

### Identifiers

• HAL Id : inria-00471724, version 1

### Citation

Yacine Boufkhad, Fabien Mathieu, Fabien de Montgolfier, Diego Perino, Laurent Viennot. Achievable Catalog Size in Peer-to-Peer Video-on-Demand Systems. Proceedings of the 7th Internnational Workshop on Peer-to-Peer Systems (IPTPS), Feb 2008, Tampa Bay, United States. pp.1-6. ⟨inria-00471724⟩

Record views


text:
Title & Authors
Choi, Eun-Mi;

Abstract
If k is a subfield of $\small{\mathbb{Q}(\varepsilon_m)}$ then the cohomology group $\small{H^2(k(\varepsilon_n)/k)}$ is isomorphic to $\small{H^2(k(\varepsilon_{n$ with gcd(m, n') = 1. This enables us to reduce a cyclotomic k-algebra over $\small{k(\varepsilon_n)}$ to the one over $\small{k(\varepsilon_{n$. A radical extension in projective Schur algebra theory is regarded as an analog of cyclotomic extension in Schur algebra theory. We will study a reduction of cohomology group of radical extension and show that a Galois cohomology group of a radical extension is isomorphic to that of a certain subextension of radical extension. We then draw a cohomological characterization of radical group.
Keywords
Language
English
Cited by
References
1.
E. Aljadeff and J. Sonn, Projective Schur algebras have abelian splitting fields, J. Algebra 175 (1995), no. 1, 179-187

2.
E. Aljadeff and J. Sonn, Projective Schur algebras of nilpotent type are Brauer equivalent to radical algebras, J. Algebra 220 (1999), no. 2, 401-414

3.
A. Babakhanian, Cohomological methods in group theory, Marcel Dekker Inc., New York, 1972

4.
E. Choi and H. Lee, Crossed product algebras over cyclotomic extension fields, Math. Japon. 50 (1999), no. 2, 207-210

5.
E. Choi and H. Lee, The crossed product theorem for projective Schur algebras, Glasg. Math. J. 43 (2001), no. 1, 135-143

6.
G. Janusz, The Schur group of cyclotomic fields, J. Number Theory 7 (1975), no. 3, 345-352

7.
G. Karpilovsky, Projective representations of finite groups, Monographs and Textbooks in Pure and Applied Mathematics, 94, Marcel Dekker Inc., New York, 1985

8.
G. Karpilovsky, Field Theory, Monographs and Textbooks in Pure and Applied Mathematics, 120, Marcel Dekker Inc., New York, 1988

9.
F. Lorenz and H. Opolka, Einfache Algebren und projektive Darstellungen Äuber ZahlkÄorpern, Math. Z. 162 (1978), no. 2, 175-182

10.
I. Reiner, Maximal orders, London Math. Soc. Monogr. Ser. 5, London, Academic Press, New York, 1975

11.
J. P. Serre, Local Fields, Grad. Text. Math. 67, Springer-Verlag, NewYork, 1979

12.
E. Weiss, Cohomology of groups , Academic press, New York, 1969

13.
T. Yamada, The Schur subgroup of the Brauer group, Lect. Notes Math. 397, Springer- Verlag, NewYork, 1974


text:
# Thread: Synthetic division in two variables?

1. ## Synthetic division in two variables?

Use synthetic division to find the quotient and remainder: $(x^4-y^4)/(x-y)$

I know how to do synthetic division with just x, but this threw me for a loop. Bagatrix (math software) also could not solve it. Any ideas?

2. My guess (and it's only a guess!) is that you are expected to use the underlying concepts for synthetic division, and apply them here.

When you do synthetic division of a polynomial in x by a factor in x, you are actually just plugging in the corresponding x-value. For instance, if you divide by x - 3, you are actually only plugging the 3 into the division and, if the remainder is zero, then you will have shown that x = 3 is a zero of the original polynomial (or, which is the same thing, that x - 3 is a factor).

In this case, you are dividing by x - y. When you were dividing by x - 3, you set this equal to zero, and solved for the value to plug into the synthetic-division matrix: x - 3 = 0, so x = 3, so plug in "3". The corresponding process here would be: x - y = 0, so x - y, so plug in "y".

You can find "the answer" by long polynomial division. Try the synthetic division with the top row being 1, 0y, 0y^2, 0y^3, 1y^4, and see if you get the right result.

3. Originally Posted by stapel
In this case, you are dividing by x - y. When you were dividing by x - 3, you set this equal to zero, and solved for the value to plug into the synthetic-division matrix: x - 3 = 0, so x = 3, so plug in "3". The corresponding process here would be: x - y = 0, so x - y, so plug in "y".

You can find "the answer" by long polynomial division. Try the synthetic division with the top row being 1, 0y, 0y^2, 0y^3, 1y^4, and see if you get the right result.
Aha! Right you are (with the exception of the sign on the last coefficient). I used $y$ for my synthetic divisor and used $[1][0][0][0][-y^4]$ for my coefficients. Carrying it through I got $x^3+x^2y+xy^2+y^3$ with no remainder. Thanks!


text:
Expected maximum inner product

The question was asked on MSE on Jan 22 with no luck so far.

If you sample $n$ vectors each with $m$ entries, with each entry chosen from the set $\{-1, 1\}$, how can you calculate the expected maximum absolute value of the inner product between all pairs of vectors? That is let us call the vectors $v_i$ and let $X_{n,m} = \max_{i \ne j} |\langle v_i,v_j \rangle|$. I would like $\mathbb{E}(X_{n,m})$.

We can assume both $n$ and $m$ are large. We can also assume that $n^c \leq m \leq n^{d}$ for constant $c,d > 0$.

-

For one pair of (random) vectors, the inner product $X$ is distributed the same way as the sum of $m$ independent $\pm 1$-valued random variables. The simplest Chernoff inequality tells us that $$\mathbb P(|X| > a) < 2e^{-a^2/2m}.$$ So $|X|$ is exponentially unlikely to take values greater than anything just a tiny bit larger than $\sqrt m$. Since $m$ and $n$ are related polynomially, summing over the $n^2$ pairs of vectors doesn't make the failure probabilty substantially greater, so with very high probability $|X_{m,n}|$ will be less than $m^{1/2+o(1)}$.
Thank you. Is there a matching lower bound which tells me that it is exponentially unlikely to take values smaller than anything just a tiny bit smaller than $\sqrt{m}$ too? –  Anush Jan 28 at 11:01
The binomial distribution is fairly flat in a strip of width $\sqrt m$ near its mean, so I certainly expect to see values of size $\sqrt m$. Lower bounds for the probability of large deviations are not as common as upper bounds, and I don't know any nice statements offhand, but something precise is said in the appendix of Alon and Spencer, for example. Often the guiding principle is that the binomial distribution is well approximated by a normal distribution in the centre. –  Ben Barber Jan 28 at 11:17


text:
# The cable of a uniformly loaded suspension bridge hangs in the form of a parabola.

Question:

The cable of a uniformly loaded suspension bridge hangs in the form of a parabola. The roadway which is horizontal and 100 m long is supported by vertical wires attached to the cable, the longest wire being 30 m and the shortest being 6 m. Find the length of a supporting wire attached to the roadway 18 m from the middle.

Solution:

The vertex is at the lowest point of the cable. The origin of the coordinate plane is taken as the vertex of the parabola, while its vertical axis is taken along the positive y-axis. This can be diagrammatically represented as

Here, AB and OC are the longest and the shortest wires, respectively, attached to the cable.

DF is the supporting wire attached to the roadway, 18 m from the middle.

Here, $A B=30 \mathrm{~m}, O C=6 \mathrm{~m}$, and $B C=\frac{100}{2}=50 \mathrm{~m} .$

The equation of the parabola is of the form $x^{2}=4 a y$ (as it is opening upwards).

The coordinates of point A are (50, 30 – 6) = (50, 24).

Since A (50, 24) is a point on the parabola,

$(50)^{2}=4 a(24)$

$\Rightarrow a=\frac{50 \times 50}{4 \times 24}=\frac{625}{24}$

$\therefore$ Equation of the parabola, $x^{2}=4 \times \frac{625}{24} \times y$ or $6 x^{2}=625 y$

The x-coordinate of point D is 18.

Hence, at x = 18,

$6(18)^{2}=625 y$

$\Rightarrow y=\frac{6 \times 18 \times 18}{625}$

$\Rightarrow y=3.11$ (approx)

$\therefore \mathrm{DE}=3.11 \mathrm{~m}$

DF = DE + EF = 3.11 m + 6 m = 9.11 m

Thus, the length of the supporting wire attached to the roadway 18 m from the middle is approximately 9.11 m.